/* ************************************************************************ qooxdoo - the new era of web development http://qooxdoo.org Copyright: 2004-2007 1&1 Internet AG, Germany, http://www.1and1.org License: LGPL: http://www.gnu.org/licenses/lgpl.html EPL: http://www.eclipse.org/org/documents/epl-v10.php See the LICENSE file in the project's top-level directory for details. Authors: * Sebastian Werner (wpbasti) * Andreas Ecker (ecker) ************************************************************************ */ /* ************************************************************************ #id(qx.OO) #module(core) #after(qx.Settings) #load(qx.lang.Core) #load(qx.lang.Function) #optional(qx.event.type.DataEvent) ************************************************************************ */ // Usage of this hacky construct to make qx.OO available inside the API viewer qx.OO = {}; qx.OO.defineClass = function() {}; qx.Class = qx.OO; qx.OO.defineClass("qx.OO"); qx.Class.classes = {}; qx.Class.setter = {}; qx.Class.getter = {}; qx.Class.resetter = {}; qx.Class.values = {}; qx.Class.propertyNumber = 0; /* --------------------------------------------------------------------------- DEFINE CLASS IMPLEMENTATION --------------------------------------------------------------------------- */ /** * define a new qooxdoo class * All classes should be defined in this way. * * @param vClassName {String} fully qualified class name (e.g. "qx.ui.form.Button") * @param vSuper {Object} super class * @param vConstructor {Function} the constructor of the new class */ qx.Class.defineClass = function(vClassName, vSuper, vConstructor) { var vSplitName = vClassName.split("."); var vNameLength = vSplitName.length-1; var vTempObject = window; // Setting up namespace for (var i=0; i 4 || arguments.length == 0) { throw new Error("Invalid number of arguments for property " + p.name + ": " + arguments); } try { var ret = qx.lang.Array.fromShortHand(qx.lang.Array.fromArguments(arguments)); } catch(ex) { throw new Error("Invalid shorthand values for property " + p.name + ": " + arguments + ": " + ex); } var s = p.setter; var l = s.length; for (var i=0; i 1) { newValue = qx.lang.Array.fromArguments(arguments); } // support converter methods if (p.hasConvert) { try { newValue = p.convert.call(this, newValue, p); } catch(ex) { throw new Error("Attention! Could not convert new value for " + p.name + ": " + newValue + ": " + ex); } } var oldValue = this[valueKey]; if (newValue === oldValue) { return newValue; } if (!(p.allowNull && newValue == null)) { if (p.hasType && typeof newValue !== p.type) { return this.error("Attention! The value \"" + newValue + "\" is an invalid value for the property \"" + p.name + "\" which must be typeof \"" + p.type + "\" but is typeof \"" + typeof newValue + "\"!", new Error()); } if (p.hasInstance && !(newValue instanceof qx.OO.classes[p.instance])) { return this.error("Attention! The value \"" + newValue + "\" is an invalid value for the property \"" + p.name + "\" which must be an instance of \"" + p.instance + "\"!", new Error()); } if (p.hasClassName && newValue.classname != p.classname) { return this.error("Attention! The value \"" + newValue + "\" is an invalid value for the property \"" + p.name + "\" which must be an object with the classname \"" + p.classname + "\"!", new Error()); } if (p.hasPossibleValues && newValue != null && !qx.lang.Array.contains(p.possibleValues, newValue)) { return this.error("Failed to save value for " + p.name + ". '" + newValue + "' is not a possible value!", new Error()); } } // Allow to check and transform the new value before storage if (this[checkKey]) { try { newValue = this[checkKey](newValue, p); // Don't do anything if new value is indentical to old value if (newValue === oldValue) { return newValue; } } catch(ex) { return this.error("Failed to check property " + p.name, ex); } } // Store new value this[valueKey] = newValue; // Check if there is a modifier implementation if (this[modifyKey]) { try { var r = this[modifyKey](newValue, oldValue, p); if (!r) { return this.error("Modification of property \"" + p.name + "\" failed without exception (" + r + ")", new Error()); } } catch(ex) { return this.error("Modification of property \"" + p.name + "\" failed with exception", ex); } } // Unit detection support if (p.hasUnitDetection) { this[unitDetectionKey](p, newValue); } // Auto queue addition support if (p.addToQueue) { this.addToQueue(p.name); } else if (p.addToQueueRuntime) { this.addToQueueRuntime(p.name); } // Auto state queue addition support if (p.addToStateQueue) { this.addToStateQueue(); } // Create Event if (this.hasEventListeners && this.hasEventListeners(changeKey)) { try { this.createDispatchDataEvent(changeKey, newValue); } catch(ex) { throw new Error("Property " + p.name + " modified: Failed to dispatch change event: " + ex); } } return newValue; }; } else { // building setFoo(): Setup new value, do type and change detection, converting types, call unit detection, ... pp["set" + p.method] = function(newValue) { // this.debug("Fast Setter: " + p.name); var oldValue = this[valueKey]; if (newValue === oldValue) { return newValue; } if (!(p.allowNull && newValue == null)) { if (p.hasType && typeof newValue !== p.type) { return this.error("Attention! The value \"" + newValue + "\" is an invalid value for the property \"" + p.name + "\" which must be typeof \"" + p.type + "\" but is typeof \"" + typeof newValue + "\"!", new Error()); } } // Allow to check and transform the new value before storage if (this[checkKey]) { try { newValue = this[checkKey](newValue, p); // Don't do anything if new value is indentical to old value if (newValue === oldValue) { return newValue; } } catch(ex) { return this.error("Failed to check property " + p.name, ex); } } // Store new value this[valueKey] = newValue; // Check if there is a modifier implementation if (this[modifyKey]) { try { var r = this[modifyKey](newValue, oldValue, p); if (!r) { var valueStr = new String(newValue).substring(0, 50); return this.error("Setting property \"" + p.name + "\" to \"" + valueStr + "\" failed without exception (" + r + ")", new Error()); } } catch(ex) { var valueStr = new String(newValue).substring(0, 50); return this.error("Setting property \"" + p.name + "\" to \"" + valueStr + "\" failed with exception", ex); } } // Create Event if (this.hasEventListeners && this.hasEventListeners(changeKey)) { var vEvent = new qx.event.type.DataEvent(changeKey, newValue, oldValue, false); vEvent.setTarget(this); try { this.dispatchEvent(vEvent, true); } catch(ex) { throw new Error("Property " + p.name + " modified: Failed to dispatch change event: " + ex); } } return newValue; }; } // building user configured get alias for property if (typeof p.getAlias === "string") { pp[p.getAlias] = pp["get" + p.method]; } // building user configured set alias for property if (typeof p.setAlias === "string") { pp[p.setAlias] = pp["set" + p.method]; } } qx.Class.changeProperty = qx.OO._createProperty; qx.Class.addProperty = function(p) { qx.OO.propertyNumber++; qx.OO._createProperty(p); // add property to (all) property list if (typeof qx.Proto._properties !== "string") { qx.Proto._properties = p.name; } else { qx.Proto._properties += "," + p.name; } // add property to object property list switch(p.type) { case undefined: case "object": case "function": if (typeof qx.Proto._objectproperties !== "string") { qx.Proto._objectproperties = p.name; } else { qx.Proto._objectproperties += "," + p.name; } } } qx.Class.inheritField = function(vField, vData) { qx.lang.Object.carefullyMergeWith(vData, qx.Super.prototype[vField]); qx.Proto[vField] = vData; } qx.Class.isAvailable = function(vClassName) { return qx.OO.classes[vClassName] != null; }