summaryrefslogtreecommitdiff
path: root/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/client
diff options
context:
space:
mode:
Diffstat (limited to 'webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/client')
-rw-r--r--webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/client/Builder.js478
-rw-r--r--webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/client/Command.js288
-rw-r--r--webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/client/History.js137
-rw-r--r--webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/client/NativeWindow.js639
-rw-r--r--webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/client/Timer.js183
5 files changed, 1725 insertions, 0 deletions
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/client/Builder.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/client/Builder.js
new file mode 100644
index 0000000000..03156282f5
--- /dev/null
+++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/client/Builder.js
@@ -0,0 +1,478 @@
+/* ************************************************************************
+
+ qooxdoo - the new era of web development
+
+ http://qooxdoo.org
+
+ Copyright:
+ 2004-2006 by 1&1 Internet AG, Germany, http://www.1and1.org
+
+ License:
+ LGPL 2.1: http://www.gnu.org/licenses/lgpl.html
+
+ Authors:
+ * Sebastian Werner (wpbasti)
+ * Andreas Ecker (ecker)
+
+************************************************************************ */
+
+/* ************************************************************************
+
+
+************************************************************************ */
+
+/*!
+ A class to generate a widget hierarchy from XML
+
+ qx.client.Builder is not thread safe by design
+ - state information is stored at the instance level
+ - only use it from a single thread
+*/
+qx.OO.defineClass("qx.client.Builder", qx.core.Target,
+function(flags)
+{
+ qx.core.Target.call(this);
+
+ // map<className, map<propertyName, function>>
+ this._propertyEditors = {};
+
+ this._registerDefaultPropertyEditors();
+
+ this._flags = flags || {};
+
+ // ensure the default flags are setup
+ if (this._flags.strict == null) {
+ // strick mode throws exceptions when
+ // * widget setters don't exist
+ this._flags.strict = true;
+ }
+
+});
+
+/*
+------------------------------------------------------------------------------------
+ BUILD
+------------------------------------------------------------------------------------
+*/
+
+/*!
+ Asynchronous method - fetches XML data from the URL then delegates to build to process the xml
+ Dispatches a qx.event.type.Event("done") after the hierarchy is built
+*/
+qx.Proto.buildFromUrl = function(parent, url) {
+ var req = new qx.io.remote.Request(url, "GET", "application/xml");
+ var self = this;
+ req.addEventListener("completed", function(e) {
+ self.build(parent, e.getData().getContent());
+ qx.ui.core.Widget.flushGlobalQueues();
+ });
+ req.send();
+}
+
+/*!
+ parse the children of the xml and appending all widgets to the parent widget
+ @param parent can either be the application instance, or a widget to append the xml toplevel widgets to
+ @param node can be either a xml string, or a xml dom document or fragment
+*/
+qx.Proto.build = function(parent, node) {
+ // support embedding of an XML string within a textarea
+ if (typeof node == "object" && node.nodeName == 'TEXTAREA') {
+ node = node.value;
+ }
+
+ // parse strings in to XML DOM
+ if (typeof node == "string") {
+ var parser = new DOMParser();
+ node = parser.parseFromString(node, "text/xml");
+ // TODO handle parse errors
+ }
+ this._buildNodes(parent, node.childNodes);
+}
+
+qx.Proto._buildNodes = function(parent, nodes) {
+ var x = 0;
+ for (var i = 0; i < nodes.length; i++) {
+ var n = nodes[i];
+ // 1 = ELEMENT_NODE
+ if (n.nodeType == 1) {
+ this._buildWidgetFromNode(parent, n);
+ }
+ }
+}
+
+qx.Proto._buildEventListener = function(widget, args, text) {
+ if (qx.util.Validation.isInvalidString(args.type)) {
+ throw this._newError('eventListener requires a string type attribute');
+ }
+
+ var self = this;
+
+ // are we delegating ?
+ if (qx.util.Validation.isValidString(args.delegate)) {
+
+ if (args.delegate.indexOf('.') > -1) {
+ // delegation to a global method
+ var p = args.delegate.split('.');
+ var o = p[0];
+ var m = p[1];
+ widget.addEventListener(args.type, function(e) {
+
+ if (!window[o]) {
+ throw self._newError('delegate not found', {delegate:args.delegate});
+ }
+
+ if (!window[o][m]) {
+ throw self._newError('delegate not found', {delegate:args.delegate});
+ }
+
+ window[o][m].apply(window[o], [e]);
+ });
+ }
+ else {
+
+ // delegation to a global method
+ widget.addEventListener(args.type, function(e) {
+
+ if (!window[args.delegate]) {
+ throw self._newError('delegate not found', {delegate:args.delegate});
+ }
+
+ window[args.delegate].apply(null, [e]);
+ });
+ }
+ }
+ else {
+
+ // build a function object using text as the function body
+ //
+ // the args attribute indicates the name of the event argument
+ // if not provided - use 'event' as the name
+ if (!args.args) {
+ args.args = "event";
+ }
+
+ var f = new Function(args.args, text);
+ widget.addEventListener(args.type, f);
+ }
+}
+
+
+/*
+ a node builder that will be used if no node builder is declared for a nodeName
+*/
+qx.Proto._buildWidgetFromNode = function(parent, node) {
+
+ var className = this._extractClassName(node);
+
+ if (!className) {
+ throw this._newError("unrecognised node", {nodeName:node.nodeName});
+ }
+
+ if (className == "qx.client.builder.Container") {
+ // generic container node to allow xml to contain multiple toplevel nodes
+ this._buildNodes(parent, node.childNodes);
+ return;
+ }
+
+ if (className == "qx.client.builder.Script") {
+ var e = document.createElement("script");
+ var attribs = this._mapXmlAttribToObject(node);
+ if (attribs.type) {
+ e.type = attribs.type;
+ }
+ else {
+ e.type='text/javascript';
+ }
+
+ // e.innerHTML = node.firstChild.nodeValue;
+
+ // fix for Internet Explorer by Cristian Bica
+ if (qx.sys.Client.getInstance().isMshtml())
+ {
+ e.innerHTML = eval(node.firstChild.nodeValue);
+ }
+ else
+ {
+ e.innerHTML = node.firstChild.nodeValue;
+ }
+
+ document.body.appendChild(e);
+ return;
+ }
+
+ if (className == "qx.client.builder.EventListener") {
+ var attribs = this._mapXmlAttribToObject(node);
+ var text;
+ if (node.firstChild) {
+ text = node.firstChild.nodeValue;
+ }
+ this._buildEventListener(parent, attribs, text);
+ return;
+ }
+
+
+ var classConstructor = qx.OO.classes[className];
+ if (!classConstructor) {
+ throw this._newError("constructor not found", {className:className});
+ }
+
+ // construct the widget instance - using the default constructor
+ var widget = new classConstructor();
+ var attribs = this._mapXmlAttribToObject(node, widget);
+ delete attribs['qxtype'];
+
+ var dummyWidget = attribs.id && attribs.id.indexOf("_") == 0;
+
+ if (attribs.id) {
+ // register a global refrence for this widget
+ window[attribs.id] = widget;
+ delete attribs.id;
+ }
+
+ // convert any on?? attribs into event listeners
+ for (var a in attribs) {
+
+ if (a.toLowerCase().indexOf('on') == 0 && a.length > 2) {
+
+ // there may be issues here for XHTML based attributes - due to their case
+ var type = a.substring(2);
+ type = type.charAt(0) + type.substring(1);
+
+ this._buildEventListener(widget, {type:type,args:'event'}, attribs[a]);
+
+ delete attribs[a];
+ }
+ }
+
+ for (var n in attribs) {
+ this._setWidgetProperty(widget, n, attribs[n]);
+ }
+
+ if(!dummyWidget) {
+ parent.add(widget);
+ }
+
+ // recurse to all of the nodes children, using the newly created widget as the parent
+ this._buildNodes(widget, node.childNodes);
+}
+
+/*
+------------------------------------------------------------------------------------
+ WIDGET PROPERTIES
+------------------------------------------------------------------------------------
+*/
+
+
+/*!
+ Set a widget's property using a propertyEditor
+*/
+qx.Proto._setWidgetProperty = function(widget, name, value) {
+ var editor = this._findPropertyEditor(widget.classname, name);
+ if (!editor) {
+ editor = this._coercePropertyEditor;
+ }
+ editor.set(widget, name, value);
+}
+
+qx.Proto._findPropertyEditor = function(className, propertyName) {
+ // get all defined propertyEditors for this widget's prototype
+ var m = this._propertyEditors[className];
+ // lookup the converter for this property name
+ if (m && m[propertyName]) {
+ return m[propertyName];
+ }
+
+ // try the widget's superclass
+ var w = qx.OO.classes[className];
+ if (w && w.superclass && w.superclass.prototype.classname) {
+ return this._findPropertyEditor(w.superclass.prototype.classname, propertyName);
+ }
+
+ return null;
+}
+
+qx.Proto.registerPropertyEditor = function(className, propertyName, editor) {
+ if (!this._propertyEditors[className]) this._propertyEditors[className] = {};
+ this._propertyEditors[className][propertyName] = editor;
+}
+
+qx.Proto._registerDefaultPropertyEditors = function() {
+ var self = this;
+
+ // a property editor that splits the values on a comma and coerces each one into a suitable type
+ var commaDelimitedPropertyEditor = {};
+ commaDelimitedPropertyEditor.set = function(widget, name, value) {
+ if (value == null || value == "") {
+ self._setProperty(widget, name, null);
+ return;
+ }
+
+ var s = value.split(",");
+ var v = [];
+ for (var i = 0; i < s.length; i++) {
+ v[i] = self._coerce(s[i]);
+ }
+
+ self._setProperties(widget, name, v);
+ }
+
+ var evalPropertyEditor = {};
+ evalPropertyEditor.set = function(widget, name, value) {
+ if (value == null || value == "") {
+ self._setProperty(widget, name, null);
+ return;
+ }
+
+ self._setProperty(widget, name, eval(value));
+ }
+
+ var referencePropertyEditor = {};
+ referencePropertyEditor.set = function(widget, name, value) {
+ self._setProperty(widget, name, window[value]);
+ }
+
+ this.registerPropertyEditor('qx.ui.core.Widget', 'location', commaDelimitedPropertyEditor);
+ this.registerPropertyEditor('qx.ui.core.Widget', 'dimension', commaDelimitedPropertyEditor);
+
+ this.registerPropertyEditor('qx.ui.core.Widget', 'space', commaDelimitedPropertyEditor);
+ this.registerPropertyEditor('qx.ui.core.Widget', 'edge', commaDelimitedPropertyEditor);
+
+ this.registerPropertyEditor('qx.ui.core.Widget', 'padding', commaDelimitedPropertyEditor);
+ this.registerPropertyEditor('qx.ui.core.Widget', 'margin', commaDelimitedPropertyEditor);
+
+ this.registerPropertyEditor('qx.ui.core.Widget', 'heights', commaDelimitedPropertyEditor);
+ this.registerPropertyEditor('qx.ui.core.Widget', 'widths', commaDelimitedPropertyEditor);
+
+ this.registerPropertyEditor('qx.ui.core.Widget', 'align', commaDelimitedPropertyEditor);
+ this.registerPropertyEditor('qx.ui.core.Widget', 'stretch', commaDelimitedPropertyEditor);
+
+ this.registerPropertyEditor('qx.ui.core.Widget', 'clipLocation', commaDelimitedPropertyEditor);
+ this.registerPropertyEditor('qx.ui.core.Widget', 'clipDimension', commaDelimitedPropertyEditor);
+ this.registerPropertyEditor('qx.ui.core.Widget', 'clip', commaDelimitedPropertyEditor);
+
+ this.registerPropertyEditor('qx.ui.core.Widget', 'backgroundColor', evalPropertyEditor);
+ this.registerPropertyEditor('qx.ui.core.Widget', 'color', evalPropertyEditor);
+ this.registerPropertyEditor('qx.ui.core.Widget', 'border', evalPropertyEditor);
+
+
+ this.registerPropertyEditor('qx.ui.menu.Button', 'menu', referencePropertyEditor);
+ this.registerPropertyEditor('qx.ui.form.RadioButton', 'manager', referencePropertyEditor);
+ this.registerPropertyEditor('qx.ui.menu.RadioButton', 'group', referencePropertyEditor);
+
+
+ // a property editor that just tries to coerce the string value into a suitable type
+ this._coercePropertyEditor = {};
+ this._coercePropertyEditor.set = function(widget, name, value) {
+ self._setProperty(widget, name, self._coerce(value));
+ }
+
+}
+
+
+qx.Proto._coerce = function(value) {
+
+ // don't really care if its null
+ if (value == null) return value;
+
+ // is it alreay a javascript type
+ if (typeof value == 'object') return value;
+ if (typeof value == 'function') return value;
+ if (typeof value == 'number') return value;
+ if (typeof value == 'boolean') return value;
+ if (typeof value == 'date') return value;
+ if (typeof value == 'array') return value;
+
+ // is it a number ?
+ var n = new Number(value);
+ if (!isNaN(n)) return n.valueOf();
+
+ // is it a boolean ?
+ if (value == "true") return true;
+ if (value == "false") return false;
+
+ // is it a date ?
+ var d = Date.parse(value);
+ if (d != null && !isNaN(d)) return d;
+
+ // leave it as a string
+ if (typeof value == 'string') {
+ // convert empty string into null
+ if (value == "") return null;
+ }
+
+ return value;
+}
+
+qx.Proto._setProperty = function(widget, name, value) {
+ this._setProperties(widget, name, [value]);
+}
+
+qx.Proto._setProperties = function(widget, name, value) {
+
+ // TODO : find a cheaper way to find the setter
+ // NOTE : the name is LOWERCASE - hence we iterate all properties of the widget
+ // to try and find a matching one
+ var n = "set" + name;
+ for (var a in widget) {
+ if (n == a.toLowerCase()) {
+ var setter = widget[a];
+ break;
+ }
+ }
+ if (!setter && this._flags.strict) throw this._newError('no setter defined on widget instance', {widget:widget, property:name});
+ setter.apply(widget, value);
+}
+
+
+/*
+------------------------------------------------------------------------------------
+ UTILS
+------------------------------------------------------------------------------------
+*/
+
+/*
+2 format
+1. <qx.ui.basic.Atom/>
+3. <div qxtype="qx.ui.basic.Atom"/>
+*/
+qx.Proto._extractClassName = function(node) {
+ if (node.nodeName.toLowerCase() == "div") {
+ if (!node.attributes['qxtype'])
+ return null;
+ return node.attributes['qxtype'].value;
+ } else {
+ return node.nodeName;
+ }
+}
+
+qx.Proto._mapXmlAttribToObject = function(node) {
+ var r = {};
+ var c = node.attributes;
+ for (var i=0; i<c.length; i++) {
+ r[c[i].name.toLowerCase()] = c[i].value;
+ }
+ return r;
+}
+
+/*
+------------------------------------------------------------------------------------
+ EXCEPTION HANDLING / DEBUGGING
+------------------------------------------------------------------------------------
+*/
+
+qx.Proto._newError = function(message, data, exception) {
+ var m = message;
+ var joiner = "";
+ var d = "";
+ if (data) {
+ for (var p in data) {
+ d += joiner + p + "=" + data[p] + '';
+ joiner = " ";
+ }
+ m += " " + d + " ";
+ }
+ if (exception) {
+ m+= " error: " + exception + " ";
+ }
+ return new Error(m);
+}
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/client/Command.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/client/Command.js
new file mode 100644
index 0000000000..6ea2fd0d14
--- /dev/null
+++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/client/Command.js
@@ -0,0 +1,288 @@
+/* ************************************************************************
+
+ qooxdoo - the new era of web development
+
+ http://qooxdoo.org
+
+ Copyright:
+ 2004-2006 by 1&1 Internet AG, Germany, http://www.1and1.org
+
+ License:
+ LGPL 2.1: http://www.gnu.org/licenses/lgpl.html
+
+ Authors:
+ * Sebastian Werner (wpbasti)
+ * Andreas Ecker (ecker)
+ * Fabian Jakobs (fjakobs)
+
+************************************************************************ */
+
+/* ************************************************************************
+
+#module(ui_core)
+
+************************************************************************ */
+
+/**
+ * This contains a command with shortcut.
+ *
+ * Each command could be assigned to multiple widgets.
+ *
+ * @event execute {qx.event.type.DataEvent} when the command is executed.
+ *
+ * @param vShortcut (string) shortcuts can be composed of optional modifier
+ * keys Control, Alt, Shift, Meta and a non modifier key.
+ * If no non modifier key is specified, the second paramater is evaluated.
+ * The key must be seperated by a ''+'' or ''-'' character.
+ * Examples: Alt+F1, Control+C, Control+Alt+Enf
+ *
+ * @param vKeyCodeOrIdentifier (int) Additional key of the command. It is interpreted as a
+ * keyIdentifier if it is given as integer. Otherwhise it is interpreted as keyCode.
+ */
+qx.OO.defineClass("qx.client.Command", qx.core.Target,
+function(vShortcut, vKeyCodeOrIdentifier)
+{
+ qx.core.Target.call(this);
+
+ this._modifier = {};
+ this._key = null;
+
+ if (qx.util.Validation.isValid(vShortcut)) {
+ this.setShortcut(vShortcut);
+ }
+
+ if (qx.util.Validation.isValid(vKeyCodeOrIdentifier))
+ {
+ if (qx.util.Validation.isValidString(vKeyCodeOrIdentifier))
+ {
+ this.setKeyIdentifier(vKeyCodeOrIdentifier);
+ }
+ else if (qx.util.Validation.isValidNumber(vKeyCodeOrIdentifier))
+ {
+ this.warn("The use of keyCode in command is deprecated. Use keyIdentifier instead.");
+ this.setKeyCode(vKeyCodeOrIdentifier);
+ }
+ else
+ {
+ var msg = "vKeyCodeOrIdentifier must be of type string or number: " + vKeyCodeOrIdentifier;
+ this.error(msg);
+ throw msg;
+ }
+ }
+
+ // OSX warning for Alt key combinations
+ if (this._modifier.Alt && this._key && this._key.length == 1) {
+ if (
+ (this._key >= "A" && this._key <= "Z") ||
+ (this._key >= "0" && this._key <= "9")
+ ) {
+ this.warn("A shortcut containing Alt and a letter or number will not work under OS X!");
+ }
+ }
+ qx.event.handler.EventHandler.getInstance().addCommand(this);
+});
+
+
+/** the command shortcut */
+qx.OO.addProperty({ name : "shortcut", type : "string" });
+
+/**
+ * keyCode (Deprecated)
+ * Still there for compatibility with the old key handler/commands
+ */
+qx.OO.addProperty({ name : "keyCode", type : "number" });
+
+/** KeyIdentifier */
+qx.OO.addProperty({ name : "keyIdentifier", type : "string" });
+
+
+
+/*
+---------------------------------------------------------------------------
+ USER METHODS
+---------------------------------------------------------------------------
+*/
+
+/**
+ * Fire the "execute" event on this command.
+ *
+ * @param vTarget (Object)
+ */
+qx.Proto.execute = function(vTarget)
+{
+ if (this.hasEventListeners("execute")) {
+ this.dispatchEvent(new qx.event.type.DataEvent("execute", vTarget), true);
+ }
+
+ return false;
+};
+
+
+
+/*
+---------------------------------------------------------------------------
+ MODIFIER
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._modifyShortcut = function(propValue, propOldValue, propData)
+{
+ if (propValue)
+ {
+ this._modifier = {};
+ this._key = null;
+
+ // split string to get each key which must be pressed
+ // build a hash with active keys
+ var a = propValue.split(/[-+\s]+/);
+ var al = a.length;
+
+ for (var i=0; i<al; i++)
+ {
+ var identifier = qx.event.handler.KeyEventHandler.getInstance().oldKeyNameToKeyIdentifier(a[i]);
+
+ switch (identifier)
+ {
+ case "Control":
+ case "Shift":
+ case "Meta":
+ case "Alt":
+ this._modifier[identifier] = true;
+ break;
+
+ case "Unidentified":
+ var msg = "Not a valid key name for a command: " + a[i];
+ this.error(msg);
+ throw msg;
+
+ default:
+ if (this._key) {
+ var msg = "You can only specify one non modifier key!";
+ this.error(msg);
+ throw msg;
+ }
+ this._key = identifier;
+ }
+ }
+ }
+ return true;
+};
+
+
+
+/*
+---------------------------------------------------------------------------
+ INTERNAL MATCHING LOGIC
+---------------------------------------------------------------------------
+*/
+
+/**
+ * Checks wether the given key event matches the command's shortcut
+ *
+ * @param e (qx.event.type.KeyEvent) the key event object
+ * @return (boolean) wether the commands shortcut matches the key event
+ */
+qx.Proto._matchesKeyEvent = function(e)
+{
+ var key = this._key || this.getKeyIdentifier();
+ if (!key && !this.getKeyCode()) {
+ // no shortcut defined.
+ return;
+ }
+
+ // pre-check for check special keys
+ // we handle this here to omit to check this later again.
+ if (
+ (this._modifier.Shift && !e.getShiftKey()) ||
+ (this._modifier.Control && !e.getCtrlKey()) ||
+// (this._modifier.Meta && !e.getCtrlKey()) ||
+ (this._modifier.Alt && !e.getAltKey())
+ ) {
+ return false;
+ }
+
+ if (key)
+ {
+ if (key == e.getKeyIdentifier()) {
+ return true;
+ }
+ }
+ else
+ {
+ if (this.getKeyCode() == e.getKeyCode()) {
+ return true;
+ }
+ }
+
+ return false;
+};
+
+
+
+/*
+---------------------------------------------------------------------------
+ STRING CONVERTION
+---------------------------------------------------------------------------
+*/
+
+/**
+ * Returns the shortcut as string
+ *
+ * @return (string) shortcut
+ */
+qx.Proto.toString = function()
+{
+ var vShortcut = this.getShortcut();
+ var vKeyCode = this.getKeyCode();
+ var vString = "";
+ var vKeyIdentifier = this._key || this.getKeyIdentifier();
+
+ var vKeyString = "";
+ if (qx.util.Validation.isValidString(vKeyIdentifier))
+ {
+ vKeyString = vKeyIdentifier;
+ }
+ else if (qx.util.Validation.isValidNumber(vKeyCode))
+ {
+ var vTemp = qx.event.type.KeyEvent.codes[vKeyCode];
+ vKeyString = vTemp ? qx.lang.String.toFirstUp(vTemp) : String(vKeyCode);
+ }
+
+ if (qx.util.Validation.isValidString(vShortcut))
+ {
+ vString = vShortcut + "+" + vKeyString;
+ }
+ else if (qx.util.Validation.isValidNumber(vKeyCode))
+ {
+ vString = vKeyString;
+ }
+
+ return vString;
+};
+
+
+
+/*
+---------------------------------------------------------------------------
+ DISPOSER
+---------------------------------------------------------------------------
+*/
+
+/**
+ * Destructor
+ */
+qx.Proto.dispose = function()
+{
+ if (this.getDisposed()) {
+ return;
+ }
+
+ this._shortcutParts = null;
+
+ var vMgr = qx.event.handler.EventHandler.getInstance();
+ if (vMgr) {
+ vMgr.removeCommand(this);
+ }
+
+ return qx.core.Target.prototype.dispose.call(this);
+};
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/client/History.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/client/History.js
new file mode 100644
index 0000000000..e242d7c85a
--- /dev/null
+++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/client/History.js
@@ -0,0 +1,137 @@
+/* ************************************************************************
+
+ qooxdoo - the new era of web development
+
+ http://qooxdoo.org
+
+ Copyright:
+ 2004-2006 by 1&1 Internet AG, Germany, http://www.1and1.org
+
+ License:
+ LGPL 2.1: http://www.gnu.org/licenses/lgpl.html
+
+ Authors:
+ * Sebastian Werner (wpbasti)
+ * Andreas Ecker (ecker)
+
+************************************************************************ */
+
+/* ************************************************************************
+
+#resource(html:static/history)
+#require(qx.manager.object.AliasManager)
+
+************************************************************************ */
+
+/**
+ * A helper for using the browser history in JavaScript Applications without
+ * reloading the main page.
+ * <p>
+ * Adds entries to the browser history and fires a "request" event when one of
+ * the entries was requested by the user (e.g. by clicking on the back button).
+ * </p>
+ *
+ * @event request {qx.event.type.DataEvent} Fired when the user moved in the
+ * history. The data property of the event holds the command, which was
+ * passed to {@link #addToHistory}.
+ */
+qx.OO.defineClass("qx.client.History", qx.core.Target,
+function() {
+ qx.core.Target.call(this);
+
+ this._pageFlag = true;
+});
+
+
+/**
+ * Initializes the History. This method has to called by applications using this
+ * class once during initialization. Subsequent calls have no (negative) effect.
+ */
+qx.Proto.init = function() {
+ if (this._iframe == null) {
+ this._iframe = document.createElement("iframe");
+ this._iframe.style.visibility = "hidden";
+ document.body.appendChild(this._iframe);
+ }
+}
+
+
+/**
+ * Adds an entry to the browser history.
+ *
+ * @param command {string} a string representing the old state of the
+ * application. This command will be delivered in the data property of
+ * the "request" event.
+ * @param newTitle {string ? null} the page title to set after the history entry
+ * is done. This title should represent the new state of the application.
+ */
+qx.Proto.addToHistory = function(command, newTitle) {
+ if (command == this._currentCommand) {
+ document.title = newTitle;
+ } else {
+ if (this._iframe == null) {
+ throw new Error("You have to call init first!");
+ }
+
+ this._pageFlag = !this._pageFlag;
+ this._currentCommand = command;
+ this._newTitle = newTitle;
+
+ // NOTE: We need the command attribute to enforce a loading of the page
+ // (Otherwise we don't get an onload event).
+ // The browser will still cache commands loaded once.
+ // Without the onload-problem anchors would work, too.
+ // (Anchors would have the advantage that the helper is only loaded once)
+ this._iframe.src = this.getSetting("helperFile") + "?c=" + command;
+ }
+}
+
+
+/**
+ * Event handler. Called when the history helper page was loaded.
+ *
+ * @param location {Map} the location property of the window object of the
+ * helper page.
+ */
+qx.Proto._onHistoryLoad = function(location)
+{
+ try {
+ var equalsPos = location.search.indexOf("=");
+ var command = location.search.substring(equalsPos + 1);
+
+ if (this._newTitle) {
+ document.title = this._newTitle;
+ this._newTitle = null;
+ }
+
+ if (command != this._currentCommand) {
+ this._currentCommand = command;
+
+ this.createDispatchDataEvent("request", command);
+ }
+ } catch (exc) {
+ this.error("Handling history load failed", exc);
+ }
+
+ qx.ui.core.Widget.flushGlobalQueues();
+}
+
+
+/** The URL to the helper page. */
+qx.Settings.setDefault("helperFile", qx.Settings.getValueOfClass("qx.manager.object.AliasManager", "staticUri") + "/history/historyHelper.html");
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ DEFER SINGLETON INSTANCE
+---------------------------------------------------------------------------
+*/
+
+/**
+ * Singleton Instance Getter
+ */
+qx.Class.getInstance = qx.util.Return.returnInstance;
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/client/NativeWindow.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/client/NativeWindow.js
new file mode 100644
index 0000000000..69e9c2a87c
--- /dev/null
+++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/client/NativeWindow.js
@@ -0,0 +1,639 @@
+/* ************************************************************************
+
+ qooxdoo - the new era of web development
+
+ http://qooxdoo.org
+
+ Copyright:
+ 2004-2006 by 1&1 Internet AG, Germany, http://www.1and1.org
+
+ License:
+ LGPL 2.1: http://www.gnu.org/licenses/lgpl.html
+
+ Authors:
+ * Sebastian Werner (wpbasti)
+ * Andreas Ecker (ecker)
+
+************************************************************************ */
+
+/* ************************************************************************
+
+#require(qx.dom.Window)
+
+************************************************************************ */
+
+qx.OO.defineClass("qx.client.NativeWindow", qx.core.Target,
+function(vUrl, vName)
+{
+ qx.core.Target.call(this);
+
+
+ // ************************************************************************
+ // TIMER
+ // ************************************************************************
+
+ this._timer = new qx.client.Timer(100);
+ this._timer.addEventListener("interval", this._oninterval, this);
+
+
+ // ************************************************************************
+ // INITIAL PROPERTIES
+ // ************************************************************************
+
+ if (qx.util.Validation.isValidString(vUrl)) {
+ this.setUrl(vUrl);
+ }
+
+ if (qx.util.Validation.isValidString(vName)) {
+ this.setName(vName);
+ }
+});
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ PROPERTIES
+---------------------------------------------------------------------------
+*/
+
+/*!
+ If the window is open or closed
+*/
+qx.OO.addProperty({ name : "open", type : "boolean", defaultValue : false });
+
+/*!
+ The outer width of the window.
+*/
+qx.OO.addProperty({ name : "width", type : "number", defaultValue : 400, impl : "dimension" });
+
+/*!
+ The outer height of the window.
+*/
+qx.OO.addProperty({ name : "height", type : "number", defaultValue : 250, impl : "dimension" });
+
+/*!
+ The left screen coordinate of the window.
+*/
+qx.OO.addProperty({ name : "left", type : "number", defaultValue : 100, impl : "position" });
+
+/*!
+ The top screen coordinate of the window.
+*/
+qx.OO.addProperty({ name : "top", type : "number", defaultValue : 200, impl : "position" });
+
+/*!
+ Should be window be modal
+*/
+qx.OO.addProperty({ name : "modal", type : "boolean", defaultValue : false });
+
+/*!
+ Should be window be dependent on this application window
+*/
+qx.OO.addProperty({ name : "dependent", type : "boolean", defaultValue : true });
+
+/*!
+ The url
+*/
+qx.OO.addProperty({ name : "url", type : "string" });
+
+/*!
+ The window name
+*/
+qx.OO.addProperty({ name : "name", type : "string" });
+
+/*!
+ The text of the statusbar
+*/
+qx.OO.addProperty({ name : "status", type : "string", defaultValue : "Ready" });
+
+/*!
+ Should the statusbar be shown
+*/
+qx.OO.addProperty({ name : "showStatusbar", type : "boolean", defaultValue : false });
+
+/*!
+ Should the menubar be shown
+*/
+qx.OO.addProperty({ name : "showMenubar", type : "boolean", defaultValue : false });
+
+/*!
+ Should the location(bar) be shown
+*/
+qx.OO.addProperty({ name : "showLocation", type : "boolean", defaultValue : false });
+
+/*!
+ Should the toolbar be shown
+*/
+qx.OO.addProperty({ name : "showToolbar", type : "boolean", defaultValue : false });
+
+/*!
+ If the window is resizeable
+*/
+qx.OO.addProperty({ name : "resizeable", type : "boolean", defaultValue : true });
+
+/*!
+ If the window is able to scroll and has visible scrollbars if needed
+*/
+qx.OO.addProperty({ name : "allowScrollbars", type : "boolean", defaultValue : true });
+
+
+
+/*
+---------------------------------------------------------------------------
+ STATE
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._loaded = false;
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ PROPERTY GROUPS
+---------------------------------------------------------------------------
+*/
+
+qx.OO.addPropertyGroup({ name : "location", members : [ "left", "top" ]});
+qx.OO.addPropertyGroup({ name : "dimension", members : [ "width", "height" ]});
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ MODIFIERS
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._modifyPosition = function(propValue, propOldValue, propName)
+{
+ /*
+ http://www.microsoft.com/technet/prodtechnol/winxppro/maintain/sp2brows.mspx
+ Changes to Functionality in Microsoft Windows XP Service Pack 2
+ Part 5: Enhanced Browsing Security
+ URLACTION_FEATURE_WINDOW_RESTRICTIONS
+ Allow script-initiated windows without size or position constraints
+ Code: 2102
+ */
+
+ if (!this.isClosed())
+ {
+ try
+ {
+ this._window.moveTo(this.getLeft(), this.getTop());
+ }
+ catch(ex)
+ {
+ this.error("Cross-Domain Scripting problem: Could not move window!", ex);
+ }
+ }
+
+ return true;
+}
+
+qx.Proto._modifyDimension = function(propValue, propOldValue, propName)
+{
+ /*
+ http://www.microsoft.com/technet/prodtechnol/winxppro/maintain/sp2brows.mspx
+ Changes to Functionality in Microsoft Windows XP Service Pack 2
+ Part 5: Enhanced Browsing Security
+ URLACTION_FEATURE_WINDOW_RESTRICTIONS
+ Allow script-initiated windows without size or position constraints
+ Code: 2102
+ */
+
+ if (!this.isClosed())
+ {
+ try
+ {
+ this._window.resizeTo(this.getWidth(), this.getHeight());
+ }
+ catch(ex)
+ {
+ this.error("Cross-Domain Scripting problem: Could not resize window!", ex);
+ }
+ }
+
+ return true;
+}
+
+qx.Proto._modifyName = function(propValue, propOldValue, propName)
+{
+ if (!this.isClosed()) {
+ this._window.name = propValue;
+ }
+
+ return true;
+}
+
+qx.Proto._modifyUrl = function(propValue, propOldValue, propName)
+{
+ // String hack needed for old compressor (compile.py)
+ if(!this.isClosed()) {
+ this._window.location.replace(qx.util.Validation.isValidString(propValue) ? propValue : ("javascript:/" + "/"));
+ }
+
+ return true;
+}
+
+qx.Proto._modifyOpen = function(propValue, propOldValue, propData)
+{
+ propValue ? this._open() : this._close();
+ return true;
+}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ NAME
+---------------------------------------------------------------------------
+*/
+
+qx.Proto.getName = function()
+{
+ if (!this.isClosed())
+ {
+ try
+ {
+ var vName = this._window.name;
+ }
+ catch(ex)
+ {
+ return this._valueName;
+ }
+
+ if (vName == this._valueName)
+ {
+ return vName;
+ }
+ else
+ {
+ throw new Error("window name and name property are not identical");
+ }
+ }
+ else
+ {
+ return this._valueName;
+ }
+}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ UTILITY
+---------------------------------------------------------------------------
+*/
+
+qx.Proto.isClosed = function()
+{
+ var vClosed = true;
+
+ if (this._window)
+ {
+ try {
+ vClosed = this._window.closed;
+ } catch(ex) {}
+ }
+
+ return vClosed;
+}
+
+qx.Proto.open = function() {
+ this.setOpen(true);
+}
+
+qx.Proto.close = function() {
+ this.setOpen(false);
+}
+
+qx.Proto.isLoaded = function() {
+ return this._loaded;
+}
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ OPEN METHOD
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._open = function()
+{
+ var vConf = [];
+
+
+ /*
+ ------------------------------------------------------------------------------
+ PRE CONFIGURE WINDOW
+ ------------------------------------------------------------------------------
+ */
+
+ if (qx.util.Validation.isValidNumber(this.getWidth()))
+ {
+ vConf.push("width");
+ vConf.push("=");
+ vConf.push(this.getWidth());
+ vConf.push(",");
+ }
+
+ if (qx.util.Validation.isValidNumber(this.getHeight()))
+ {
+ vConf.push("height");
+ vConf.push("=");
+ vConf.push(this.getHeight());
+ vConf.push(",");
+ }
+
+ if (qx.util.Validation.isValidNumber(this.getLeft()))
+ {
+ vConf.push("left");
+ vConf.push("=");
+ vConf.push(this.getLeft());
+ vConf.push(",");
+ }
+
+ if (qx.util.Validation.isValidNumber(this.getTop()))
+ {
+ vConf.push("top");
+ vConf.push("=");
+ vConf.push(this.getTop());
+ vConf.push(",");
+ }
+
+
+
+ vConf.push("dependent");
+ vConf.push("=");
+ vConf.push(this.getDependent() ? "yes" : "no");
+ vConf.push(",");
+
+ vConf.push("resizable");
+ vConf.push("=");
+ vConf.push(this.getResizeable() ? "yes" : "no");
+ vConf.push(",");
+
+ vConf.push("status");
+ vConf.push("=");
+ vConf.push(this.getShowStatusbar() ? "yes" : "no");
+ vConf.push(",");
+
+ vConf.push("location");
+ vConf.push("=");
+ vConf.push(this.getShowLocation() ? "yes" : "no");
+ vConf.push(",");
+
+ vConf.push("menubar");
+ vConf.push("=");
+ vConf.push(this.getShowMenubar() ? "yes" : "no");
+ vConf.push(",");
+
+ vConf.push("toolbar");
+ vConf.push("=");
+ vConf.push(this.getShowToolbar() ? "yes" : "no");
+ vConf.push(",");
+
+ vConf.push("scrollbars");
+ vConf.push("=");
+ vConf.push(this.getAllowScrollbars() ? "yes" : "no");
+ vConf.push(",");
+
+ vConf.push("modal");
+ vConf.push("=");
+ vConf.push(this.getModal() ? "yes" : "no");
+ vConf.push(",");
+
+
+
+
+
+
+ /*
+ ------------------------------------------------------------------------------
+ OPEN WINDOW
+ ------------------------------------------------------------------------------
+ */
+
+ if (qx.util.Validation.isInvalidString(this.getName())) {
+ this.setName("qx_NativeWindow" + this.toHashCode());
+ }
+
+ this._window = window.open(this.getUrl(), this.getName(), vConf.join(""));
+
+ if (this.isClosed())
+ {
+ this.error("Window could not be opened. It seems, there is a popup blocker active!");
+ }
+ else
+ {
+ // This try-catch is needed because of cross domain issues (access rights)
+ try
+ {
+ this._window._native = this;
+ this._window.onload = this._onload;
+ }
+ catch(ex) {}
+
+ // start timer for close detection
+ this._timer.start();
+
+ // block original document
+ if (this.getModal()) {
+ qx.ui.core.ClientDocument.getInstance().block(this);
+ }
+ }
+}
+
+qx.Proto._close = function()
+{
+ if (!this._window) {
+ return;
+ }
+
+ // stop timer for close detection
+ this._timer.stop();
+
+ // release window again
+ if (this.getModal()){
+ qx.ui.core.ClientDocument.getInstance().release(this);
+ }
+
+ // finally close window
+ if (!this.isClosed()) {
+ this._window.close();
+ }
+
+ try
+ {
+ this._window._native = null;
+ this._window.onload = null;
+ }
+ catch(ex) {};
+
+ this._window = null;
+ this._loaded = false;
+
+ this.createDispatchEvent("close");
+}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ CENTER SUPPORT
+---------------------------------------------------------------------------
+*/
+
+qx.Proto.centerToScreen = function() {
+ return this._centerHelper((screen.width - this.getWidth()) / 2, (screen.height - this.getHeight()) / 2);
+}
+
+qx.Proto.centerToScreenArea = function() {
+ return this._centerHelper((screen.availWidth - this.getWidth()) / 2, (screen.availHeight - this.getHeight()) / 2);
+}
+
+qx.Proto.centerToOpener = function() {
+ return this._centerHelper(((qx.dom.Window.getInnerWidth(window) - this.getWidth()) / 2) + qx.dom.Location.getScreenBoxLeft(window.document.body), ((qx.dom.Window.getInnerHeight(window) - this.getHeight()) / 2) + qx.dom.Location.getScreenBoxTop(window.document.body));
+}
+
+qx.Proto._centerHelper = function(l, t)
+{
+ // set new values
+ this.setLeft(l);
+ this.setTop(t);
+
+ // focus window if opened
+ if (!this.isClosed()) {
+ this.focus();
+ }
+}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ FOCUS HANDLING
+---------------------------------------------------------------------------
+*/
+
+qx.Proto.focus = function()
+{
+ if (!this.isClosed()) {
+ this._window.focus();
+ }
+}
+
+qx.Proto.blur = function()
+{
+ if (!this.isClosed()) {
+ this._window.blur();
+ }
+}
+
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ EVENT HANDLING
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._oninterval = function(e)
+{
+ if (this.isClosed()) {
+ this.setOpen(false);
+ }
+ else if (!this._loaded)
+ {
+ // This try-catch is needed because of cross domain issues (access rights)
+ try
+ {
+ if (this._window.document && this._window.document.readyState == "complete")
+ {
+ this._loaded = true;
+ this.createDispatchEvent("load");
+ }
+ }
+ catch(ex) {};
+ }
+}
+
+qx.Proto._onload = function(e)
+{
+ var obj = this._native;
+
+ if (!obj._loaded)
+ {
+ obj._loaded = true;
+ obj.createDispatchEvent("load");
+ }
+}
+
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ DISPOSER
+---------------------------------------------------------------------------
+*/
+
+qx.Proto.dispose = function()
+{
+ if (this.getDisposed()) {
+ return;
+ }
+
+ if (this.getDependent()) {
+ this.close();
+ }
+
+ if (this._timer)
+ {
+ this._timer.stop();
+ this._timer = null;
+ }
+
+ if (this._window)
+ {
+ try
+ {
+ this._window._native = null;
+ this._window.onload = null;
+ }
+ catch(ex) {};
+
+ this._window = null;
+ }
+
+ return qx.core.Target.prototype.dispose.call(this);
+}
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/client/Timer.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/client/Timer.js
new file mode 100644
index 0000000000..674bbdb154
--- /dev/null
+++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/client/Timer.js
@@ -0,0 +1,183 @@
+/* ************************************************************************
+
+ qooxdoo - the new era of web development
+
+ http://qooxdoo.org
+
+ Copyright:
+ 2004-2006 by 1&1 Internet AG, Germany, http://www.1and1.org
+
+ License:
+ LGPL 2.1: http://www.gnu.org/licenses/lgpl.html
+
+ Authors:
+ * Sebastian Werner (wpbasti)
+ * Andreas Ecker (ecker)
+
+************************************************************************ */
+
+/* ************************************************************************
+
+#module(core)
+
+************************************************************************ */
+
+/**
+ * Global timer support. Simplifies javascript intervals for objects.
+ *
+ * @event interval {qx.event.type.Event}
+ */
+qx.OO.defineClass("qx.client.Timer", qx.core.Target,
+function(vInterval)
+{
+ qx.core.Target.call(this);
+
+ this.setEnabled(false);
+
+ if (qx.util.Validation.isValidNumber(vInterval)) {
+ this.setInterval(vInterval);
+ }
+
+ // Object wrapper to timer event
+ var o = this;
+ this.__oninterval = function() { o._oninterval(); }
+});
+
+qx.OO.addProperty({ name : "interval", type : "number", defaultValue : 1000 });
+
+qx.Proto._intervalHandle = null;
+
+
+
+/*
+---------------------------------------------------------------------------
+ MODIFIER
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._modifyEnabled = function(propValue, propOldValue, propData)
+{
+ if (propOldValue)
+ {
+ window.clearInterval(this._intervalHandle);
+ this._intervalHandle = null;
+ }
+ else if (propValue)
+ {
+ this._intervalHandle = window.setInterval(this.__oninterval, this.getInterval());
+ }
+
+ return true;
+}
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ USER-ACCESS
+---------------------------------------------------------------------------
+*/
+
+qx.Proto.start = function() {
+ this.setEnabled(true);
+}
+
+qx.Proto.startWith = function(vInterval)
+{
+ this.setInterval(vInterval);
+ this.start();
+}
+
+qx.Proto.stop = function() {
+ this.setEnabled(false);
+}
+
+qx.Proto.restart = function()
+{
+ this.stop();
+ this.start();
+}
+
+qx.Proto.restartWith = function(vInterval)
+{
+ this.stop();
+ this.startWith(vInterval);
+}
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ EVENT-MAPPER
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._oninterval = function()
+{
+ if (this.getEnabled()) {
+ this.createDispatchEvent("interval");
+ }
+}
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ DISPOSER
+---------------------------------------------------------------------------
+*/
+
+qx.Proto.dispose = function()
+{
+ if(this.getDisposed()) {
+ return;
+ }
+
+ // Stop interval
+ this.stop();
+
+ // Clear handle
+ if (this._intervalHandler)
+ {
+ window.clearInterval(this._intervalHandle);
+ this._intervalHandler = null;
+ }
+
+ // Clear object wrapper function
+ this.__oninterval = null;
+
+ // Call qx.core.Target to do the other dispose work
+ return qx.core.Target.prototype.dispose.call(this);
+}
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ HELPER
+---------------------------------------------------------------------------
+*/
+
+qx.client.Timer.once = function(vFunction, vObject, vTimeout)
+{
+ // Create time instance
+ var vTimer = new qx.client.Timer(vTimeout);
+
+ // Add event listener to interval
+ vTimer.addEventListener("interval", function(e)
+ {
+ vFunction.call(vObject, e);
+ vTimer.dispose();
+
+ vObject = null;
+ }, vObject);
+
+ // Directly start timer
+ vTimer.start();
+}