summaryrefslogtreecommitdiff
path: root/includes/js/dojo/_base/declare.js
diff options
context:
space:
mode:
Diffstat (limited to 'includes/js/dojo/_base/declare.js')
-rw-r--r--includes/js/dojo/_base/declare.js178
1 files changed, 178 insertions, 0 deletions
diff --git a/includes/js/dojo/_base/declare.js b/includes/js/dojo/_base/declare.js
new file mode 100644
index 0000000..6c2ec55
--- /dev/null
+++ b/includes/js/dojo/_base/declare.js
@@ -0,0 +1,178 @@
+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 CLA
+
+dojo.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();
+ // | }
+ // | );
+
+ // process superclass argument
+ // var dd=dojo.declare, mixins=null;
+ var dd = arguments.callee, mixins;
+ if(dojo.isArray(superclass)){
+ mixins = superclass;
+ superclass = mixins.shift();
+ }
+ // construct intermediate classes for mixins
+ if(mixins){
+ dojo.forEach(mixins, function(m){
+ if(!m){ throw(className + ": mixin #" + i + " is null"); } // It's likely a required module is not loaded
+ superclass = dd._delegate(superclass, m);
+ });
+ }
+ // prepare values
+ var 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;} } // 0[i] checks Object.prototype
+ // decorate prototype
+ dojo.extend(ctor, {declaredClass: className, _constructor: init, preamble: null}, props || 0);
+ // special help for IE
+ ctor.prototype.constructor = ctor;
+ // create named reference
+ return 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 prototype
+ var ctor = dojo.declare._makeCtor();
+ // cache ancestry
+ dojo.mixin(ctor, {superclass: bp, mixin: mp, extend: dojo.declare._extend});
+ // chain prototypes
+ if(base){ctor.prototype = dojo._delegate(bp);}
+ // add mixin and core
+ dojo.extend(ctor, dojo.declare._core, mp||0, {_constructor: null, preamble: null});
+ // special help for IE
+ ctor.prototype.constructor = ctor;
+ // name this class for debugging
+ ctor.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 anything
+ return 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 home
+ if(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 impedence 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 preamble
+ if((fn = c.prototype.preamble)){a = fn.apply(this, a) || a;}
+ // FIXME:
+ // need to provide an optional prototype-settable
+ // "_explicitSuper" property which disables this
+ // initialize superclass
+ if(ct&&ct.apply){ct.apply(this, a);}
+ // initialize mixin
+ if(mct&&mct.apply){mct.apply(this, a);}
+ // initialize self
+ if((ii=c.prototype._constructor)){ii.apply(this, args);}
+ // post construction
+ if(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 method
+ var p=ptype, c, m, f;
+ do{
+ c = p.constructor;
+ m = c.mixin;
+ // find method by name in our mixin ancestor
+ if(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 chain
+ p = c.superclass;
+ }while(p);
+ // if we couldn't find an ancestor in our primary chain, try a mixin chain
+ return !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;}
+ a = newArgs||args;
+ var c = args.callee, p = this.constructor.prototype, fn, mp;
+ // if not an instance override
+ if(this[name] != c || p[name] == c){
+ mp = this._findMethod(name, c, p, true);
+ if(!mp){throw(this.declaredClass + ': inherited method "' + name + '" mismatch');}
+ p = this._findMethod(name, c, mp, false);
+ }
+ fn = p && p[name];
+ if(!fn){throw(mp.declaredClass + ': inherited method "' + name + '" not found');}
+ // if the function exists, invoke it in our scope
+ return fn.apply(this, a);
+ }
+ }
+});
+
+}