]> git.wh0rd.org - tt-rss.git/blob - lib/dojo/_base/declare.js.uncompressed.js
upgrade dojo to 1.8.3 (refs #570)
[tt-rss.git] / lib / dojo / _base / declare.js.uncompressed.js
1 define("dojo/_base/declare", ["./kernel", "../has", "./lang"], function(dojo, has, lang){
2 // module:
3 // dojo/_base/declare
4
5 var mix = lang.mixin, op = Object.prototype, opts = op.toString,
6 xtor = new Function, counter = 0, cname = "constructor";
7
8 function err(msg, cls){ throw new Error("declare" + (cls ? " " + cls : "") + ": " + msg); }
9
10 // C3 Method Resolution Order (see http://www.python.org/download/releases/2.3/mro/)
11 function c3mro(bases, className){
12 var result = [], roots = [{cls: 0, refs: []}], nameMap = {}, clsCount = 1,
13 l = bases.length, i = 0, j, lin, base, top, proto, rec, name, refs;
14
15 // build a list of bases naming them if needed
16 for(; i < l; ++i){
17 base = bases[i];
18 if(!base){
19 err("mixin #" + i + " is unknown. Did you use dojo.require to pull it in?", className);
20 }else if(opts.call(base) != "[object Function]"){
21 err("mixin #" + i + " is not a callable constructor.", className);
22 }
23 lin = base._meta ? base._meta.bases : [base];
24 top = 0;
25 // add bases to the name map
26 for(j = lin.length - 1; j >= 0; --j){
27 proto = lin[j].prototype;
28 if(!proto.hasOwnProperty("declaredClass")){
29 proto.declaredClass = "uniqName_" + (counter++);
30 }
31 name = proto.declaredClass;
32 if(!nameMap.hasOwnProperty(name)){
33 nameMap[name] = {count: 0, refs: [], cls: lin[j]};
34 ++clsCount;
35 }
36 rec = nameMap[name];
37 if(top && top !== rec){
38 rec.refs.push(top);
39 ++top.count;
40 }
41 top = rec;
42 }
43 ++top.count;
44 roots[0].refs.push(top);
45 }
46
47 // remove classes without external references recursively
48 while(roots.length){
49 top = roots.pop();
50 result.push(top.cls);
51 --clsCount;
52 // optimization: follow a single-linked chain
53 while(refs = top.refs, refs.length == 1){
54 top = refs[0];
55 if(!top || --top.count){
56 // branch or end of chain => do not end to roots
57 top = 0;
58 break;
59 }
60 result.push(top.cls);
61 --clsCount;
62 }
63 if(top){
64 // branch
65 for(i = 0, l = refs.length; i < l; ++i){
66 top = refs[i];
67 if(!--top.count){
68 roots.push(top);
69 }
70 }
71 }
72 }
73 if(clsCount){
74 err("can't build consistent linearization", className);
75 }
76
77 // calculate the superclass offset
78 base = bases[0];
79 result[0] = base ?
80 base._meta && base === result[result.length - base._meta.bases.length] ?
81 base._meta.bases.length : 1 : 0;
82
83 return result;
84 }
85
86 function inherited(args, a, f){
87 var name, chains, bases, caller, meta, base, proto, opf, pos,
88 cache = this._inherited = this._inherited || {};
89
90 // crack arguments
91 if(typeof args == "string"){
92 name = args;
93 args = a;
94 a = f;
95 }
96 f = 0;
97
98 caller = args.callee;
99 name = name || caller.nom;
100 if(!name){
101 err("can't deduce a name to call inherited()", this.declaredClass);
102 }
103
104 meta = this.constructor._meta;
105 bases = meta.bases;
106
107 pos = cache.p;
108 if(name != cname){
109 // method
110 if(cache.c !== caller){
111 // cache bust
112 pos = 0;
113 base = bases[0];
114 meta = base._meta;
115 if(meta.hidden[name] !== caller){
116 // error detection
117 chains = meta.chains;
118 if(chains && typeof chains[name] == "string"){
119 err("calling chained method with inherited: " + name, this.declaredClass);
120 }
121 // find caller
122 do{
123 meta = base._meta;
124 proto = base.prototype;
125 if(meta && (proto[name] === caller && proto.hasOwnProperty(name) || meta.hidden[name] === caller)){
126 break;
127 }
128 }while(base = bases[++pos]); // intentional assignment
129 pos = base ? pos : -1;
130 }
131 }
132 // find next
133 base = bases[++pos];
134 if(base){
135 proto = base.prototype;
136 if(base._meta && proto.hasOwnProperty(name)){
137 f = proto[name];
138 }else{
139 opf = op[name];
140 do{
141 proto = base.prototype;
142 f = proto[name];
143 if(f && (base._meta ? proto.hasOwnProperty(name) : f !== opf)){
144 break;
145 }
146 }while(base = bases[++pos]); // intentional assignment
147 }
148 }
149 f = base && f || op[name];
150 }else{
151 // constructor
152 if(cache.c !== caller){
153 // cache bust
154 pos = 0;
155 meta = bases[0]._meta;
156 if(meta && meta.ctor !== caller){
157 // error detection
158 chains = meta.chains;
159 if(!chains || chains.constructor !== "manual"){
160 err("calling chained constructor with inherited", this.declaredClass);
161 }
162 // find caller
163 while(base = bases[++pos]){ // intentional assignment
164 meta = base._meta;
165 if(meta && meta.ctor === caller){
166 break;
167 }
168 }
169 pos = base ? pos : -1;
170 }
171 }
172 // find next
173 while(base = bases[++pos]){ // intentional assignment
174 meta = base._meta;
175 f = meta ? meta.ctor : base;
176 if(f){
177 break;
178 }
179 }
180 f = base && f;
181 }
182
183 // cache the found super method
184 cache.c = f;
185 cache.p = pos;
186
187 // now we have the result
188 if(f){
189 return a === true ? f : f.apply(this, a || args);
190 }
191 // intentionally no return if a super method was not found
192 }
193
194 function getInherited(name, args){
195 if(typeof name == "string"){
196 return this.__inherited(name, args, true);
197 }
198 return this.__inherited(name, true);
199 }
200
201 function inherited__debug(args, a1, a2){
202 var f = this.getInherited(args, a1);
203 if(f){ return f.apply(this, a2 || a1 || args); }
204 // intentionally no return if a super method was not found
205 }
206
207 var inheritedImpl = dojo.config.isDebug ? inherited__debug : inherited;
208
209 // emulation of "instanceof"
210 function isInstanceOf(cls){
211 var bases = this.constructor._meta.bases;
212 for(var i = 0, l = bases.length; i < l; ++i){
213 if(bases[i] === cls){
214 return true;
215 }
216 }
217 return this instanceof cls;
218 }
219
220 function mixOwn(target, source){
221 // add props adding metadata for incoming functions skipping a constructor
222 for(var name in source){
223 if(name != cname && source.hasOwnProperty(name)){
224 target[name] = source[name];
225 }
226 }
227 if(has("bug-for-in-skips-shadowed")){
228 for(var extraNames= lang._extraNames, i= extraNames.length; i;){
229 name = extraNames[--i];
230 if(name != cname && source.hasOwnProperty(name)){
231 target[name] = source[name];
232 }
233 }
234 }
235 }
236
237 // implementation of safe mixin function
238 function safeMixin(target, source){
239 // summary:
240 // Mix in properties skipping a constructor and decorating functions
241 // like it is done by declare().
242 // target: Object
243 // Target object to accept new properties.
244 // source: Object
245 // Source object for new properties.
246 // description:
247 // This function is used to mix in properties like lang.mixin does,
248 // but it skips a constructor property and decorates functions like
249 // declare() does.
250 //
251 // It is meant to be used with classes and objects produced with
252 // declare. Functions mixed in with dojo.safeMixin can use
253 // this.inherited() like normal methods.
254 //
255 // This function is used to implement extend() method of a constructor
256 // produced with declare().
257 //
258 // example:
259 // | var A = declare(null, {
260 // | m1: function(){
261 // | console.log("A.m1");
262 // | },
263 // | m2: function(){
264 // | console.log("A.m2");
265 // | }
266 // | });
267 // | var B = declare(A, {
268 // | m1: function(){
269 // | this.inherited(arguments);
270 // | console.log("B.m1");
271 // | }
272 // | });
273 // | B.extend({
274 // | m2: function(){
275 // | this.inherited(arguments);
276 // | console.log("B.m2");
277 // | }
278 // | });
279 // | var x = new B();
280 // | dojo.safeMixin(x, {
281 // | m1: function(){
282 // | this.inherited(arguments);
283 // | console.log("X.m1");
284 // | },
285 // | m2: function(){
286 // | this.inherited(arguments);
287 // | console.log("X.m2");
288 // | }
289 // | });
290 // | x.m2();
291 // | // prints:
292 // | // A.m1
293 // | // B.m1
294 // | // X.m1
295
296 var name, t;
297 // add props adding metadata for incoming functions skipping a constructor
298 for(name in source){
299 t = source[name];
300 if((t !== op[name] || !(name in op)) && name != cname){
301 if(opts.call(t) == "[object Function]"){
302 // non-trivial function method => attach its name
303 t.nom = name;
304 }
305 target[name] = t;
306 }
307 }
308 if(has("bug-for-in-skips-shadowed")){
309 for(var extraNames= lang._extraNames, i= extraNames.length; i;){
310 name = extraNames[--i];
311 t = source[name];
312 if((t !== op[name] || !(name in op)) && name != cname){
313 if(opts.call(t) == "[object Function]"){
314 // non-trivial function method => attach its name
315 t.nom = name;
316 }
317 target[name] = t;
318 }
319 }
320 }
321 return target;
322 }
323
324 function extend(source){
325 declare.safeMixin(this.prototype, source);
326 return this;
327 }
328
329 function createSubclass(mixins){
330 return declare([this].concat(mixins));
331 }
332
333 // chained constructor compatible with the legacy declare()
334 function chainedConstructor(bases, ctorSpecial){
335 return function(){
336 var a = arguments, args = a, a0 = a[0], f, i, m,
337 l = bases.length, preArgs;
338
339 if(!(this instanceof a.callee)){
340 // not called via new, so force it
341 return applyNew(a);
342 }
343
344 //this._inherited = {};
345 // perform the shaman's rituals of the original declare()
346 // 1) call two types of the preamble
347 if(ctorSpecial && (a0 && a0.preamble || this.preamble)){
348 // full blown ritual
349 preArgs = new Array(bases.length);
350 // prepare parameters
351 preArgs[0] = a;
352 for(i = 0;;){
353 // process the preamble of the 1st argument
354 a0 = a[0];
355 if(a0){
356 f = a0.preamble;
357 if(f){
358 a = f.apply(this, a) || a;
359 }
360 }
361 // process the preamble of this class
362 f = bases[i].prototype;
363 f = f.hasOwnProperty("preamble") && f.preamble;
364 if(f){
365 a = f.apply(this, a) || a;
366 }
367 // one peculiarity of the preamble:
368 // it is called if it is not needed,
369 // e.g., there is no constructor to call
370 // let's watch for the last constructor
371 // (see ticket #9795)
372 if(++i == l){
373 break;
374 }
375 preArgs[i] = a;
376 }
377 }
378 // 2) call all non-trivial constructors using prepared arguments
379 for(i = l - 1; i >= 0; --i){
380 f = bases[i];
381 m = f._meta;
382 f = m ? m.ctor : f;
383 if(f){
384 f.apply(this, preArgs ? preArgs[i] : a);
385 }
386 }
387 // 3) continue the original ritual: call the postscript
388 f = this.postscript;
389 if(f){
390 f.apply(this, args);
391 }
392 };
393 }
394
395
396 // chained constructor compatible with the legacy declare()
397 function singleConstructor(ctor, ctorSpecial){
398 return function(){
399 var a = arguments, t = a, a0 = a[0], f;
400
401 if(!(this instanceof a.callee)){
402 // not called via new, so force it
403 return applyNew(a);
404 }
405
406 //this._inherited = {};
407 // perform the shaman's rituals of the original declare()
408 // 1) call two types of the preamble
409 if(ctorSpecial){
410 // full blown ritual
411 if(a0){
412 // process the preamble of the 1st argument
413 f = a0.preamble;
414 if(f){
415 t = f.apply(this, t) || t;
416 }
417 }
418 f = this.preamble;
419 if(f){
420 // process the preamble of this class
421 f.apply(this, t);
422 // one peculiarity of the preamble:
423 // it is called even if it is not needed,
424 // e.g., there is no constructor to call
425 // let's watch for the last constructor
426 // (see ticket #9795)
427 }
428 }
429 // 2) call a constructor
430 if(ctor){
431 ctor.apply(this, a);
432 }
433 // 3) continue the original ritual: call the postscript
434 f = this.postscript;
435 if(f){
436 f.apply(this, a);
437 }
438 };
439 }
440
441 // plain vanilla constructor (can use inherited() to call its base constructor)
442 function simpleConstructor(bases){
443 return function(){
444 var a = arguments, i = 0, f, m;
445
446 if(!(this instanceof a.callee)){
447 // not called via new, so force it
448 return applyNew(a);
449 }
450
451 //this._inherited = {};
452 // perform the shaman's rituals of the original declare()
453 // 1) do not call the preamble
454 // 2) call the top constructor (it can use this.inherited())
455 for(; f = bases[i]; ++i){ // intentional assignment
456 m = f._meta;
457 f = m ? m.ctor : f;
458 if(f){
459 f.apply(this, a);
460 break;
461 }
462 }
463 // 3) call the postscript
464 f = this.postscript;
465 if(f){
466 f.apply(this, a);
467 }
468 };
469 }
470
471 function chain(name, bases, reversed){
472 return function(){
473 var b, m, f, i = 0, step = 1;
474 if(reversed){
475 i = bases.length - 1;
476 step = -1;
477 }
478 for(; b = bases[i]; i += step){ // intentional assignment
479 m = b._meta;
480 f = (m ? m.hidden : b.prototype)[name];
481 if(f){
482 f.apply(this, arguments);
483 }
484 }
485 };
486 }
487
488 // forceNew(ctor)
489 // return a new object that inherits from ctor.prototype but
490 // without actually running ctor on the object.
491 function forceNew(ctor){
492 // create object with correct prototype using a do-nothing
493 // constructor
494 xtor.prototype = ctor.prototype;
495 var t = new xtor;
496 xtor.prototype = null; // clean up
497 return t;
498 }
499
500 // applyNew(args)
501 // just like 'new ctor()' except that the constructor and its arguments come
502 // from args, which must be an array or an arguments object
503 function applyNew(args){
504 // create an object with ctor's prototype but without
505 // calling ctor on it.
506 var ctor = args.callee, t = forceNew(ctor);
507 // execute the real constructor on the new object
508 ctor.apply(t, args);
509 return t;
510 }
511
512 function declare(className, superclass, props){
513 // summary:
514 // Create a feature-rich constructor from compact notation.
515 // className: String?
516 // The optional name of the constructor (loosely, a "class")
517 // stored in the "declaredClass" property in the created prototype.
518 // It will be used as a global name for a created constructor.
519 // superclass: Function|Function[]
520 // May be null, a Function, or an Array of Functions. This argument
521 // specifies a list of bases (the left-most one is the most deepest
522 // base).
523 // props: Object
524 // An object whose properties are copied to the created prototype.
525 // Add an instance-initialization function by making it a property
526 // named "constructor".
527 // returns: dojo/_base/declare.__DeclareCreatedObject
528 // New constructor function.
529 // description:
530 // Create a constructor using a compact notation for inheritance and
531 // prototype extension.
532 //
533 // Mixin ancestors provide a type of multiple inheritance.
534 // Prototypes of mixin ancestors are copied to the new class:
535 // changes to mixin prototypes will not affect classes to which
536 // they have been mixed in.
537 //
538 // Ancestors can be compound classes created by this version of
539 // declare(). In complex cases all base classes are going to be
540 // linearized according to C3 MRO algorithm
541 // (see http://www.python.org/download/releases/2.3/mro/ for more
542 // details).
543 //
544 // "className" is cached in "declaredClass" property of the new class,
545 // if it was supplied. The immediate super class will be cached in
546 // "superclass" property of the new class.
547 //
548 // Methods in "props" will be copied and modified: "nom" property
549 // (the declared name of the method) will be added to all copied
550 // functions to help identify them for the internal machinery. Be
551 // very careful, while reusing methods: if you use the same
552 // function under different names, it can produce errors in some
553 // cases.
554 //
555 // It is possible to use constructors created "manually" (without
556 // declare()) as bases. They will be called as usual during the
557 // creation of an instance, their methods will be chained, and even
558 // called by "this.inherited()".
559 //
560 // Special property "-chains-" governs how to chain methods. It is
561 // a dictionary, which uses method names as keys, and hint strings
562 // as values. If a hint string is "after", this method will be
563 // called after methods of its base classes. If a hint string is
564 // "before", this method will be called before methods of its base
565 // classes.
566 //
567 // If "constructor" is not mentioned in "-chains-" property, it will
568 // be chained using the legacy mode: using "after" chaining,
569 // calling preamble() method before each constructor, if available,
570 // and calling postscript() after all constructors were executed.
571 // If the hint is "after", it is chained as a regular method, but
572 // postscript() will be called after the chain of constructors.
573 // "constructor" cannot be chained "before", but it allows
574 // a special hint string: "manual", which means that constructors
575 // are not going to be chained in any way, and programmer will call
576 // them manually using this.inherited(). In the latter case
577 // postscript() will be called after the construction.
578 //
579 // All chaining hints are "inherited" from base classes and
580 // potentially can be overridden. Be very careful when overriding
581 // hints! Make sure that all chained methods can work in a proposed
582 // manner of chaining.
583 //
584 // Once a method was chained, it is impossible to unchain it. The
585 // only exception is "constructor". You don't need to define a
586 // method in order to supply a chaining hint.
587 //
588 // If a method is chained, it cannot use this.inherited() because
589 // all other methods in the hierarchy will be called automatically.
590 //
591 // Usually constructors and initializers of any kind are chained
592 // using "after" and destructors of any kind are chained as
593 // "before". Note that chaining assumes that chained methods do not
594 // return any value: any returned value will be discarded.
595 //
596 // example:
597 // | declare("my.classes.bar", my.classes.foo, {
598 // | // properties to be added to the class prototype
599 // | someValue: 2,
600 // | // initialization function
601 // | constructor: function(){
602 // | this.myComplicatedObject = new ReallyComplicatedObject();
603 // | },
604 // | // other functions
605 // | someMethod: function(){
606 // | doStuff();
607 // | }
608 // | });
609 //
610 // example:
611 // | var MyBase = declare(null, {
612 // | // constructor, properties, and methods go here
613 // | // ...
614 // | });
615 // | var MyClass1 = declare(MyBase, {
616 // | // constructor, properties, and methods go here
617 // | // ...
618 // | });
619 // | var MyClass2 = declare(MyBase, {
620 // | // constructor, properties, and methods go here
621 // | // ...
622 // | });
623 // | var MyDiamond = declare([MyClass1, MyClass2], {
624 // | // constructor, properties, and methods go here
625 // | // ...
626 // | });
627 //
628 // example:
629 // | var F = function(){ console.log("raw constructor"); };
630 // | F.prototype.method = function(){
631 // | console.log("raw method");
632 // | };
633 // | var A = declare(F, {
634 // | constructor: function(){
635 // | console.log("A.constructor");
636 // | },
637 // | method: function(){
638 // | console.log("before calling F.method...");
639 // | this.inherited(arguments);
640 // | console.log("...back in A");
641 // | }
642 // | });
643 // | new A().method();
644 // | // will print:
645 // | // raw constructor
646 // | // A.constructor
647 // | // before calling F.method...
648 // | // raw method
649 // | // ...back in A
650 //
651 // example:
652 // | var A = declare(null, {
653 // | "-chains-": {
654 // | destroy: "before"
655 // | }
656 // | });
657 // | var B = declare(A, {
658 // | constructor: function(){
659 // | console.log("B.constructor");
660 // | },
661 // | destroy: function(){
662 // | console.log("B.destroy");
663 // | }
664 // | });
665 // | var C = declare(B, {
666 // | constructor: function(){
667 // | console.log("C.constructor");
668 // | },
669 // | destroy: function(){
670 // | console.log("C.destroy");
671 // | }
672 // | });
673 // | new C().destroy();
674 // | // prints:
675 // | // B.constructor
676 // | // C.constructor
677 // | // C.destroy
678 // | // B.destroy
679 //
680 // example:
681 // | var A = declare(null, {
682 // | "-chains-": {
683 // | constructor: "manual"
684 // | }
685 // | });
686 // | var B = declare(A, {
687 // | constructor: function(){
688 // | // ...
689 // | // call the base constructor with new parameters
690 // | this.inherited(arguments, [1, 2, 3]);
691 // | // ...
692 // | }
693 // | });
694 //
695 // example:
696 // | var A = declare(null, {
697 // | "-chains-": {
698 // | m1: "before"
699 // | },
700 // | m1: function(){
701 // | console.log("A.m1");
702 // | },
703 // | m2: function(){
704 // | console.log("A.m2");
705 // | }
706 // | });
707 // | var B = declare(A, {
708 // | "-chains-": {
709 // | m2: "after"
710 // | },
711 // | m1: function(){
712 // | console.log("B.m1");
713 // | },
714 // | m2: function(){
715 // | console.log("B.m2");
716 // | }
717 // | });
718 // | var x = new B();
719 // | x.m1();
720 // | // prints:
721 // | // B.m1
722 // | // A.m1
723 // | x.m2();
724 // | // prints:
725 // | // A.m2
726 // | // B.m2
727
728 // crack parameters
729 if(typeof className != "string"){
730 props = superclass;
731 superclass = className;
732 className = "";
733 }
734 props = props || {};
735
736 var proto, i, t, ctor, name, bases, chains, mixins = 1, parents = superclass;
737
738 // build a prototype
739 if(opts.call(superclass) == "[object Array]"){
740 // C3 MRO
741 bases = c3mro(superclass, className);
742 t = bases[0];
743 mixins = bases.length - t;
744 superclass = bases[mixins];
745 }else{
746 bases = [0];
747 if(superclass){
748 if(opts.call(superclass) == "[object Function]"){
749 t = superclass._meta;
750 bases = bases.concat(t ? t.bases : superclass);
751 }else{
752 err("base class is not a callable constructor.", className);
753 }
754 }else if(superclass !== null){
755 err("unknown base class. Did you use dojo.require to pull it in?", className);
756 }
757 }
758 if(superclass){
759 for(i = mixins - 1;; --i){
760 proto = forceNew(superclass);
761 if(!i){
762 // stop if nothing to add (the last base)
763 break;
764 }
765 // mix in properties
766 t = bases[i];
767 (t._meta ? mixOwn : mix)(proto, t.prototype);
768 // chain in new constructor
769 ctor = new Function;
770 ctor.superclass = superclass;
771 ctor.prototype = proto;
772 superclass = proto.constructor = ctor;
773 }
774 }else{
775 proto = {};
776 }
777 // add all properties
778 declare.safeMixin(proto, props);
779 // add constructor
780 t = props.constructor;
781 if(t !== op.constructor){
782 t.nom = cname;
783 proto.constructor = t;
784 }
785
786 // collect chains and flags
787 for(i = mixins - 1; i; --i){ // intentional assignment
788 t = bases[i]._meta;
789 if(t && t.chains){
790 chains = mix(chains || {}, t.chains);
791 }
792 }
793 if(proto["-chains-"]){
794 chains = mix(chains || {}, proto["-chains-"]);
795 }
796
797 // build ctor
798 t = !chains || !chains.hasOwnProperty(cname);
799 bases[0] = ctor = (chains && chains.constructor === "manual") ? simpleConstructor(bases) :
800 (bases.length == 1 ? singleConstructor(props.constructor, t) : chainedConstructor(bases, t));
801
802 // add meta information to the constructor
803 ctor._meta = {bases: bases, hidden: props, chains: chains,
804 parents: parents, ctor: props.constructor};
805 ctor.superclass = superclass && superclass.prototype;
806 ctor.extend = extend;
807 ctor.createSubclass = createSubclass;
808 ctor.prototype = proto;
809 proto.constructor = ctor;
810
811 // add "standard" methods to the prototype
812 proto.getInherited = getInherited;
813 proto.isInstanceOf = isInstanceOf;
814 proto.inherited = inheritedImpl;
815 proto.__inherited = inherited;
816
817 // add name if specified
818 if(className){
819 proto.declaredClass = className;
820 lang.setObject(className, ctor);
821 }
822
823 // build chains and add them to the prototype
824 if(chains){
825 for(name in chains){
826 if(proto[name] && typeof chains[name] == "string" && name != cname){
827 t = proto[name] = chain(name, bases, chains[name] === "after");
828 t.nom = name;
829 }
830 }
831 }
832 // chained methods do not return values
833 // no need to chain "invisible" functions
834
835 return ctor; // Function
836 }
837
838 /*=====
839 declare.__DeclareCreatedObject = {
840 // summary:
841 // dojo/_base/declare() returns a constructor `C`. `new C()` returns an Object with the following
842 // methods, in addition to the methods and properties specified via the arguments passed to declare().
843
844 inherited: function(name, args, newArgs){
845 // summary:
846 // Calls a super method.
847 // name: String?
848 // The optional method name. Should be the same as the caller's
849 // name. Usually "name" is specified in complex dynamic cases, when
850 // the calling method was dynamically added, undecorated by
851 // declare(), and it cannot be determined.
852 // args: Arguments
853 // The caller supply this argument, which should be the original
854 // "arguments".
855 // newArgs: Object?
856 // If "true", the found function will be returned without
857 // executing it.
858 // If Array, it will be used to call a super method. Otherwise
859 // "args" will be used.
860 // returns:
861 // Whatever is returned by a super method, or a super method itself,
862 // if "true" was specified as newArgs.
863 // description:
864 // This method is used inside method of classes produced with
865 // declare() to call a super method (next in the chain). It is
866 // used for manually controlled chaining. Consider using the regular
867 // chaining, because it is faster. Use "this.inherited()" only in
868 // complex cases.
869 //
870 // This method cannot me called from automatically chained
871 // constructors including the case of a special (legacy)
872 // constructor chaining. It cannot be called from chained methods.
873 //
874 // If "this.inherited()" cannot find the next-in-chain method, it
875 // does nothing and returns "undefined". The last method in chain
876 // can be a default method implemented in Object, which will be
877 // called last.
878 //
879 // If "name" is specified, it is assumed that the method that
880 // received "args" is the parent method for this call. It is looked
881 // up in the chain list and if it is found the next-in-chain method
882 // is called. If it is not found, the first-in-chain method is
883 // called.
884 //
885 // If "name" is not specified, it will be derived from the calling
886 // method (using a methoid property "nom").
887 //
888 // example:
889 // | var B = declare(A, {
890 // | method1: function(a, b, c){
891 // | this.inherited(arguments);
892 // | },
893 // | method2: function(a, b){
894 // | return this.inherited(arguments, [a + b]);
895 // | }
896 // | });
897 // | // next method is not in the chain list because it is added
898 // | // manually after the class was created.
899 // | B.prototype.method3 = function(){
900 // | console.log("This is a dynamically-added method.");
901 // | this.inherited("method3", arguments);
902 // | };
903 // example:
904 // | var B = declare(A, {
905 // | method: function(a, b){
906 // | var super = this.inherited(arguments, true);
907 // | // ...
908 // | if(!super){
909 // | console.log("there is no super method");
910 // | return 0;
911 // | }
912 // | return super.apply(this, arguments);
913 // | }
914 // | });
915 return {}; // Object
916 },
917
918 getInherited: function(name, args){
919 // summary:
920 // Returns a super method.
921 // name: String?
922 // The optional method name. Should be the same as the caller's
923 // name. Usually "name" is specified in complex dynamic cases, when
924 // the calling method was dynamically added, undecorated by
925 // declare(), and it cannot be determined.
926 // args: Arguments
927 // The caller supply this argument, which should be the original
928 // "arguments".
929 // returns:
930 // Returns a super method (Function) or "undefined".
931 // description:
932 // This method is a convenience method for "this.inherited()".
933 // It uses the same algorithm but instead of executing a super
934 // method, it returns it, or "undefined" if not found.
935 //
936 // example:
937 // | var B = declare(A, {
938 // | method: function(a, b){
939 // | var super = this.getInherited(arguments);
940 // | // ...
941 // | if(!super){
942 // | console.log("there is no super method");
943 // | return 0;
944 // | }
945 // | return super.apply(this, arguments);
946 // | }
947 // | });
948 return {}; // Object
949 },
950
951 isInstanceOf: function(cls){
952 // summary:
953 // Checks the inheritance chain to see if it is inherited from this
954 // class.
955 // cls: Function
956 // Class constructor.
957 // returns:
958 // "true", if this object is inherited from this class, "false"
959 // otherwise.
960 // description:
961 // This method is used with instances of classes produced with
962 // declare() to determine of they support a certain interface or
963 // not. It models "instanceof" operator.
964 //
965 // example:
966 // | var A = declare(null, {
967 // | // constructor, properties, and methods go here
968 // | // ...
969 // | });
970 // | var B = declare(null, {
971 // | // constructor, properties, and methods go here
972 // | // ...
973 // | });
974 // | var C = declare([A, B], {
975 // | // constructor, properties, and methods go here
976 // | // ...
977 // | });
978 // | var D = declare(A, {
979 // | // constructor, properties, and methods go here
980 // | // ...
981 // | });
982 // |
983 // | var a = new A(), b = new B(), c = new C(), d = new D();
984 // |
985 // | console.log(a.isInstanceOf(A)); // true
986 // | console.log(b.isInstanceOf(A)); // false
987 // | console.log(c.isInstanceOf(A)); // true
988 // | console.log(d.isInstanceOf(A)); // true
989 // |
990 // | console.log(a.isInstanceOf(B)); // false
991 // | console.log(b.isInstanceOf(B)); // true
992 // | console.log(c.isInstanceOf(B)); // true
993 // | console.log(d.isInstanceOf(B)); // false
994 // |
995 // | console.log(a.isInstanceOf(C)); // false
996 // | console.log(b.isInstanceOf(C)); // false
997 // | console.log(c.isInstanceOf(C)); // true
998 // | console.log(d.isInstanceOf(C)); // false
999 // |
1000 // | console.log(a.isInstanceOf(D)); // false
1001 // | console.log(b.isInstanceOf(D)); // false
1002 // | console.log(c.isInstanceOf(D)); // false
1003 // | console.log(d.isInstanceOf(D)); // true
1004 return {}; // Object
1005 },
1006
1007 extend: function(source){
1008 // summary:
1009 // Adds all properties and methods of source to constructor's
1010 // prototype, making them available to all instances created with
1011 // constructor. This method is specific to constructors created with
1012 // declare().
1013 // source: Object
1014 // Source object which properties are going to be copied to the
1015 // constructor's prototype.
1016 // description:
1017 // Adds source properties to the constructor's prototype. It can
1018 // override existing properties.
1019 //
1020 // This method is similar to dojo.extend function, but it is specific
1021 // to constructors produced by declare(). It is implemented
1022 // using dojo.safeMixin, and it skips a constructor property,
1023 // and properly decorates copied functions.
1024 //
1025 // example:
1026 // | var A = declare(null, {
1027 // | m1: function(){},
1028 // | s1: "Popokatepetl"
1029 // | });
1030 // | A.extend({
1031 // | m1: function(){},
1032 // | m2: function(){},
1033 // | f1: true,
1034 // | d1: 42
1035 // | });
1036 }
1037 };
1038 =====*/
1039
1040 // For back-compat, remove for 2.0
1041 dojo.safeMixin = declare.safeMixin = safeMixin;
1042 dojo.declare = declare;
1043
1044 return declare;
1045 });