Blame | Last modification | View Log | RSS feed
if(!dojo._hasResource["dojo._base.declare"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.dojo._hasResource["dojo._base.declare"] = true;dojo.provide("dojo._base.declare");dojo.require("dojo._base.lang");// this file courtesy of the TurboAjax group, licensed under a Dojo CLAdojo.declare = function(/*String*/ className, /*Function|Function[]*/ superclass, /*Object*/ props){// summary:// Create a feature-rich constructor from compact notation// className:// The name of the constructor (loosely, a "class")// stored in the "declaredClass" property in the created prototype// superclass:// May be null, a Function, or an Array of Functions. If an array,// the first element is used as the prototypical ancestor and// any following Functions become mixin ancestors.// props:// An object whose properties are copied to the// created prototype.// Add an instance-initialization function by making it a property// named "constructor".// description:// Create a constructor using a compact notation for inheritance and// prototype extension.//// All superclasses (including mixins) must be Functions (not simple Objects).//// Mixin ancestors provide a type of multiple inheritance. Prototypes of mixin// ancestors are copied to the new class: changes to mixin prototypes will// not affect classes to which they have been mixed in.//// "className" is cached in "declaredClass" property of the new class.//// example:// | dojo.declare("my.classes.bar", my.classes.foo, {// | // properties to be added to the class prototype// | someValue: 2,// | // initialization function// | constructor: function(){// | this.myComplicatedObject = new ReallyComplicatedObject();// | },// | // other functions// | someMethod: function(){// | doStuff();// | }// | );// argument juggling (deprecated)if(dojo.isFunction(props)||(arguments.length>3)){dojo.deprecated("dojo.declare: for class '" + className + "' pass initializer function as 'constructor' property instead of as a separate argument.", "", "1.0");var c = props;props = arguments[3] || {};props.constructor = c;}// process superclass argument// var dd=dojo.declare, mixins=null;var dd=arguments.callee, mixins=null;if(dojo.isArray(superclass)){mixins = superclass;superclass = mixins.shift();}// construct intermediate classes for mixinsif(mixins){for(var i=0, m; i<mixins.length; i++){m = mixins[i];if(!m){throw("Mixin #" + i + " to declaration of " + className + " is null. It's likely a required module is not loaded.")};superclass = dd._delegate(superclass, m);}}// prepare valuesvar init=(props||0).constructor, ctor=dd._delegate(superclass), fn;// name methods (experimental)for(var i in props){if(dojo.isFunction(fn=props[i])&&(!0[i])){fn.nom=i;}}// decorate prototypedojo.extend(ctor, {declaredClass: className, _constructor: init, preamble: null}, props||0);// special help for IEctor.prototype.constructor = ctor;// create named referencereturn dojo.setObject(className, ctor); // Function}dojo.mixin(dojo.declare, {_delegate: function(base, mixin){var bp = (base||0).prototype, mp = (mixin||0).prototype;// fresh constructor, fresh prototypevar ctor = dojo.declare._makeCtor();// cache ancestrydojo.mixin(ctor, {superclass: bp, mixin: mp, extend: dojo.declare._extend});// chain prototypesif(base){ctor.prototype = dojo._delegate(bp);}// add mixin and coredojo.extend(ctor, dojo.declare._core, mp||0, {_constructor: null, preamble: null});// special help for IEctor.prototype.constructor = ctor;// name this class for debuggingctor.prototype.declaredClass = (bp||0).declaredClass + '_' + (mp||0).declaredClass;return ctor;},_extend: function(props){for(var i in props){if(dojo.isFunction(fn=props[i])&&(!0[i])){fn.nom=i;}}dojo.extend(this, props);},_makeCtor: function(){// we have to make a function, but don't want to close over anythingreturn function(){ this._construct(arguments); }},_core: {_construct: function(args){var c=args.callee, s=c.superclass, ct=s&&s.constructor, m=c.mixin, mct=m&&m.constructor, a=args, ii, fn;// side-effect of = used on purpose here, lint may complain, don't try this at homeif(a[0]){// FIXME: preambles for each mixin should be allowed// FIXME:// should we allow the preamble here NOT to modify the// default args, but instead to act on each mixin// independently of the class instance being constructed// (for impdedence matching)?// allow any first argument w/ a "preamble" property to act as a// class preamble (not exclusive of the prototype preamble)if(/*dojo.isFunction*/(fn = a[0]["preamble"])){a = fn.apply(this, a) || a;}}// prototype preambleif(fn=c.prototype.preamble){a = fn.apply(this, a) || a;}// FIXME:// need to provide an optional prototype-settable// "_explicitSuper" property which disables this// initialize superclassif(ct&&ct.apply){ct.apply(this, a);}// initialize mixinif(mct&&mct.apply){mct.apply(this, a);}// initialize selfif(ii=c.prototype._constructor){ii.apply(this, args);}// post constructionif(this.constructor.prototype==c.prototype && (ct=this.postscript)){ct.apply(this, args)};},_findMixin: function(mixin){var c = this.constructor, p, m;while(c){p = c.superclass;m = c.mixin;if(m==mixin || (m instanceof mixin.constructor)){return p;}if(m && (m=m._findMixin(mixin))){return m;}c = p && p.constructor;}},_findMethod: function(name, method, ptype, has){// consciously trading readability for bytes and speed in this low-level methodvar p=ptype, c, m, f;do{c = p.constructor;m = c.mixin;// find method by name in our mixin ancestorif(m && (m=this._findMethod(name, method, m, has))){return m};// if we found a named method that either exactly-is or exactly-is-not 'method'if((f=p[name])&&(has==(f==method))){return p};// ascend chainp = c.superclass;}while(p);// if we couldn't find an ancestor in our primary chain, try a mixin chainreturn !has && (p=this._findMixin(ptype)) && this._findMethod(name, method, p, has);},inherited: function(name, args, newArgs){// optionalize name argument (experimental)var a = arguments;if(!dojo.isString(a[0])){newArgs=args; args=name; name=args.callee.nom;}var c=args.callee, p=this.constructor.prototype, a=newArgs||args, fn, mp;// if not an instance overrideif(this[name]!=c || p[name]==c){mp = this._findMethod(name, c, p, true);if(!mp){throw(this.declaredClass + ': name argument ("' + name + '") to inherited must match callee (declare.js)');}p = this._findMethod(name, c, mp, false);}fn = p && p[name];// FIXME: perhaps we should throw here?if(!fn){console.debug(mp.declaredClass + ': no inherited "' + name + '" was found (declare.js)'); return;}// if the function exists, invoke it in our scopereturn fn.apply(this, a);}}});}