📄 classfactory.js
字号:
} // accept superClasses defined as strings rather than references to the class object superClass = this.getClass(superClass); // create a new instance of the superClass to use as a prototype for this new class // note: instancePrototype.init() is deliberately not called here var instancePrototype = (superClass ? new superClass._instancePrototype._instanceConstructor() : {}); // create the class object for the new class: an object whose lookup pointer is the // superclass' ClassObject. var classObject = this._makeSubClass(superClass); // a constructor function that creates objects whose lookup pointer will be // instancePrototype. These created objects are instances of "subClass" instancePrototype._instanceConstructor = this._getConstructorFunction(instancePrototype); // setup the class object classObject.Class = className; classObject._isClassObject = true; // NOTE: important that we always assign _isInterface so that concrete subclasses of // interfaces have _isInterface:false classObject._isInterface = instancePrototype._isInterface = !!asInterface; classObject._superClass = superClass; // crosslink the instance prototype and class object classObject._instancePrototype = instancePrototype; // setup the instance prototype: these properties appear on all instances instancePrototype.Class = className; // crosslink the instance prototype and class object instancePrototype._classObject = classObject; // this exists mostly so that instances can reference their prototype instancePrototype._prototype = instancePrototype; // put all Classes in the special "isc" object isc[className] = classObject; // if we're in simple names mode (eg, not worried about name collisions), make the class // available as a global variable if (useSimpleNames) window[className] = classObject; this.classList[this.classList.length] = className // create a function in the isA singleton object to tell if an object is an instance of // this Class, eg, isA.ListGrid() isc.isA[className] = this.makeIsAFunc(className); // as a convenience, mix in a list of interfaces as part of the class definition if (interfaces != null) { if (!isc.isAn.Array(interfaces)) interfaces = [interfaces]; for (var i = 0; i < interfaces.length; i++) { //alert("Mixing " + interfaces[i] + " into " + className); this.mixInInterface(className, interfaces[i]); } } return classObject; }, makeIsAFunc : function (className) { if (this.isFirefox2 == null) { this.isFirefox2 = (isc.Browser.isFirefox && isc.Browser.geckoVersion >= 20061010); } if (this.isFirefox2) { return function (object) { if (object==null || object.isA==null || object.isA == isc.isA) return false; return object.isA(className); } } else { var template = this._isAFuncTemplate; template[1] = className; return new Function (this._objectString, template.join(isc._emptyString)); } }, // variables for creating "isA" functions for each class _objectString : "object", _isAFuncTemplate : [ "if(object==null||object.isA==null||object.isA==isc.isA)return false;return object.isA(isc.", null, // className ")" ], // make a class object for a new subclass of superClass _makeSubClass : function (superClass) { if (!superClass) return {}; // get the superClass' subclass constructor. The subclass constructor creates objects // whose lookup pointer will be superClass. It is created on the fly the first time a // class acquires a subclass (otherwise all leaf classes would have unnecessary // subclass constructors) var superSuperClass = superClass._superClass, subClassConstructor = superClass._subClassConstructor; if (! // if the superClass already has a subClassConstructor that differs from the // super-super class, use it (subClassConstructor && (superSuperClass == null || subClassConstructor !== superSuperClass._subClassConstructor)) ) { // otherwise we make it subClassConstructor = superClass._subClassConstructor = this._getConstructorFunction(superClass); } return new subClassConstructor(); }, //> @classMethod ClassFactory.getClass() // // Given a class name, return a pointer to the Class object for that class // // @param className (string) name of a class // @return (Class) Class object, or null if not found // @visibility external //< getClass : function (className) { // if it's a string, assume it's a className if (isc.isA.String(className)) { // see if isc[className] holds a ClassObject var classObject = isc[className]; if (classObject && isc.isA.ClassObject(classObject)) { return classObject; } } // if it's a class object, just return it if (isc.isA.ClassObject(className)) return className; // if it's an instance of some class, return the class object for the class if (isc.isAn.Instance(className)) return className._classObject; //if (isc.Log) { // isc.Log.logWarn("couldn't find class: " + className + // ", defined classes are: " + this.classList); //} return null; }, //> @classMethod ClassFactory.newInstance // // Given the name of a class, create an instance of that class. // // @param className (string) Name of a class. // (ClassObject) Actual class object to use. // @param [props] (object) Properties to apply to the instance. // @param [props2] (object) More properties to apply to the instance. // @param [props3] (object) Yet more properties to apply to the instance. // // @return (class) Pointer to the new class. // @visibility external //< // NOTE: ability to pass _constructor not documented until we have a more reasonable name for // this property. newInstance : function (className, props, props2, props3, props4, props5) { var classObject = this.getClass(className); // if we didn't get a classObject from getClass above, // and the first parameter is an object, // see if any of the properties objects passed have a ._constructor property, // which we'll treat as the classname if (classObject == null && isc.isAn.Object(className)) { var cons; for (var i = 0; i < arguments.length; i++) { var propsObj = arguments[i]; // Note: ._constructor is used rather than .constructor to resolve a // number of JS issues, as constructor is present by default on native // JS objects. // In the long run we want to rename this to something more elegant, like 'class' // and modify the css class-specific code to look for 'style' or 'baseStyle' rather // than className (or even getClass()). if (propsObj != null && propsObj._constructor != null) { cons = propsObj._constructor; } } // now fix up the props objects to include the first object // as a set of properties instead of just the class name props5 = props4; props4 = props3; props3 = props2; props2 = props; props = className; className = cons; // Safari and Mozilla both JS Error if the 'constructor' property set to a string // (typically because a user is trying to specify the className to use. (it's ok in IE) // Note: the 'constructor' property exists as a native function on a number of standard // JS objects, so we can't just check for constructor == null if (isc.isA.String(props.constructor)) { // If we don't yet have a constructor className, make use of this property - then // log a warning and remove it. if (className == null) className = props.constructor; isc.Log.logWarn("ClassFactory.newInstance() passed an object with illegal 'constructor' " + "property - removing this property from the final object. " + "To avoid seeing this message in the future, " + "specify the object's class using '_constructor'.", "ClassFactory"); props.constructor = null; } classObject = this.getClass(cons); } if (classObject == null) { //>DEBUG isc.Log.logWarn("newInstance(" + className + "): class not found", "ClassFactory"); //<DEBUG return null; } return classObject.newInstance(props, props2, props3, props4, props5); }, //> @classMethod ClassFactory._getConstructorFunction // // Given a <code>prototype</code> object, create a new constructor function that will // reference this prototype. This allows us to say <code>new constructor()</code> to // create a new object that is effectively a subclass of the original <code>prototype</code>. // // @param proto (object) Object to use as the prototype for new objects. // @return (function) Function that can be used to create new objects // based on the prototype. //< _getConstructorFunction : function (proto) { var cons = (isc.Browser.isSafari ? function () {} : new Function()); cons.prototype = proto; return cons; }, //> @classMethod ClassFactory.addGlobalID() // // Given an <code>object</code>, declare a unique global variable and link it to object so // object can be addressed in the global scope.<br><br> // // Note: If the object already has an 'ID' property, that is used, otherwise one is // generated automatically Note that if you pass an object.ID, it's up to you to ensure it // is unique in the global scope! // // @param object (object) Object to add global ID to. //< addGlobalID : function (object, ID, dontWarn) { // if an ID was passed, use that object.ID = ID || object.ID || this.getNextGlobalID(object); var wd = this.getWindow(); // if the ID is already taken, log a warning if (wd[object.ID] != null) { var instance = isc.isA.Canvas(wd[object.ID]); if (!dontWarn) { isc.Log.logWarn("ClassFactory.addGlobalID: ID:'" + object.ID + "' for object '" + object + "' collides with ID of existing object '" + wd[object.ID] + "'." + (instance ? " The pre-existing widget will be destroyed." : " The global reference to this object will be replaced")); } if (instance) wd[object.ID].destroy(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -