4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <title>The source code</title>
6 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
7 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
8 <style type="text/css">
9 .highlight { display: block; background-color: #ddd; }
11 <script type="text/javascript">
12 function highlight() {
13 document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
17 <body onload="prettyPrint(); highlight();">
18 <pre class="prettyprint lang-js"><span id='Ext-Base'>/**
19 </span> * @author Jacky Nguyen <jacky@sencha.com>
20 * @docauthor Jacky Nguyen <jacky@sencha.com>
23 * The root of all classes created with {@link Ext#define}.
25 * Ext.Base is the building block of all Ext classes. All classes in Ext inherit from Ext.Base.
26 * All prototype and static members of this class are inherited by all other classes.
28 (function(flexSetter) {
30 var Base = Ext.Base = function() {};
32 $className: 'Ext.Base',
36 <span id='Ext-Base-property-self'> /**
37 </span> * Get the reference to the current class from which this object was instantiated. Unlike {@link Ext.Base#statics},
38 * `this.self` is scope-dependent and it's meant to be used for dynamic inheritance. See {@link Ext.Base#statics}
39 * for a detailed comparison
41 * Ext.define('My.Cat', {
43 * speciesName: 'Cat' // My.Cat.speciesName = 'Cat'
46 * constructor: function() {
47 * alert(this.self.speciesName); / dependent on 'this'
53 * return new this.self();
58 * Ext.define('My.SnowLeopard', {
61 * speciesName: 'Snow Leopard' // My.SnowLeopard.speciesName = 'Snow Leopard'
65 * var cat = new My.Cat(); // alerts 'Cat'
66 * var snowLeopard = new My.SnowLeopard(); // alerts 'Snow Leopard'
68 * var clone = snowLeopard.clone();
69 * alert(Ext.getClassName(clone)); // alerts 'My.SnowLeopard'
76 // Default constructor, simply returns `this`
77 constructor: function() {
81 //<feature classSystem.config>
82 <span id='Ext-Base-method-initConfig'> /**
83 </span> * Initialize configuration for this class. a typical example:
85 * Ext.define('My.awesome.Class', {
86 * // The default config
92 * constructor: function(config) {
93 * this.initConfig(config);
99 * var awesome = new My.awesome.Class({
100 * name: 'Super Awesome'
103 * alert(awesome.getName()); // 'Super Awesome'
106 * @param {Object} config
107 * @return {Object} mixins The mixin prototypes as key - value pairs
109 initConfig: function(config) {
110 if (!this.$configInited) {
111 this.config = Ext.Object.merge({}, this.config || {}, config || {});
113 this.applyConfig(this.config);
115 this.$configInited = true;
121 <span id='Ext-Base-method-setConfig'> /**
124 setConfig: function(config) {
125 this.applyConfig(config || {});
130 <span id='Ext-Base-property-applyConfig'> /**
133 applyConfig: flexSetter(function(name, value) {
134 var setter = 'set' + Ext.String.capitalize(name);
136 if (typeof this[setter] === 'function') {
137 this[setter].call(this, value);
144 <span id='Ext-Base-method-callParent'> /**
145 </span> * Call the parent's overridden method. For example:
147 * Ext.define('My.own.A', {
148 * constructor: function(test) {
153 * Ext.define('My.own.B', {
154 * extend: 'My.own.A',
156 * constructor: function(test) {
159 * this.callParent([test + 1]);
163 * Ext.define('My.own.C', {
164 * extend: 'My.own.B',
166 * constructor: function() {
167 * alert("Going to call parent's overriden constructor...");
169 * this.callParent(arguments);
173 * var a = new My.own.A(1); // alerts '1'
174 * var b = new My.own.B(1); // alerts '1', then alerts '2'
175 * var c = new My.own.C(2); // alerts "Going to call parent's overriden constructor..."
176 * // alerts '2', then alerts '3'
179 * @param {Array/Arguments} args The arguments, either an array or the `arguments` object
180 * from the current method, for example: `this.callParent(arguments)`
181 * @return {Object} Returns the result from the superclass' method
183 callParent: function(args) {
184 var method = this.callParent.caller,
185 parentClass, methodName;
187 if (!method.$owner) {
188 //<debug error>
189 if (!method.caller) {
191 sourceClass: Ext.getClassName(this),
192 sourceMethod: "callParent",
193 msg: "Attempting to call a protected method from the public scope, which is not allowed"
198 method = method.caller;
201 parentClass = method.$owner.superclass;
202 methodName = method.$name;
204 //<debug error>
205 if (!(methodName in parentClass)) {
207 sourceClass: Ext.getClassName(this),
208 sourceMethod: methodName,
209 msg: "this.callParent() was called but there's no such method (" + methodName +
210 ") found in the parent class (" + (Ext.getClassName(parentClass) || 'Object') + ")"
215 return parentClass[methodName].apply(this, args || []);
219 <span id='Ext-Base-method-statics'> /**
220 </span> * Get the reference to the class from which this object was instantiated. Note that unlike {@link Ext.Base#self},
221 * `this.statics()` is scope-independent and it always returns the class from which it was called, regardless of what
222 * `this` points to during run-time
224 * Ext.define('My.Cat', {
227 * speciesName: 'Cat' // My.Cat.speciesName = 'Cat'
230 * constructor: function() {
231 * var statics = this.statics();
233 * alert(statics.speciesName); // always equals to 'Cat' no matter what 'this' refers to
234 * // equivalent to: My.Cat.speciesName
236 * alert(this.self.speciesName); // dependent on 'this'
238 * statics.totalCreated++;
243 * clone: function() {
244 * var cloned = new this.self; // dependent on 'this'
246 * cloned.groupName = this.statics().speciesName; // equivalent to: My.Cat.speciesName
253 * Ext.define('My.SnowLeopard', {
257 * speciesName: 'Snow Leopard' // My.SnowLeopard.speciesName = 'Snow Leopard'
260 * constructor: function() {
265 * var cat = new My.Cat(); // alerts 'Cat', then alerts 'Cat'
267 * var snowLeopard = new My.SnowLeopard(); // alerts 'Cat', then alerts 'Snow Leopard'
269 * var clone = snowLeopard.clone();
270 * alert(Ext.getClassName(clone)); // alerts 'My.SnowLeopard'
271 * alert(clone.groupName); // alerts 'Cat'
273 * alert(My.Cat.totalCreated); // alerts 3
276 * @return {Ext.Class}
278 statics: function() {
279 var method = this.statics.caller,
286 return method.$owner;
289 <span id='Ext-Base-method-callOverridden'> /**
290 </span> * Call the original method that was previously overridden with {@link Ext.Base#override}
292 * Ext.define('My.Cat', {
293 * constructor: function() {
294 * alert("I'm a cat!");
301 * constructor: function() {
302 * alert("I'm going to be a cat!");
304 * var instance = this.callOverridden();
306 * alert("Meeeeoooowwww");
312 * var kitty = new My.Cat(); // alerts "I'm going to be a cat!"
313 * // alerts "I'm a cat!"
314 * // alerts "Meeeeoooowwww"
316 * @param {Array/Arguments} args The arguments, either an array or the `arguments` object
317 * @return {Object} Returns the result after calling the overridden method
320 callOverridden: function(args) {
321 var method = this.callOverridden.caller;
323 //<debug error>
324 if (!method.$owner) {
326 sourceClass: Ext.getClassName(this),
327 sourceMethod: "callOverridden",
328 msg: "Attempting to call a protected method from the public scope, which is not allowed"
332 if (!method.$previous) {
334 sourceClass: Ext.getClassName(this),
335 sourceMethod: "callOverridden",
336 msg: "this.callOverridden was called in '" + method.$name +
337 "' but this method has never been overridden"
342 return method.$previous.apply(this, args || []);
345 destroy: function() {}
348 // These static properties will be copied to every newly created class with {@link Ext#define}
349 Ext.apply(Ext.Base, {
350 <span id='Ext-Base-static-method-create'> /**
351 </span> * Create a new instance of this Class.
353 * Ext.define('My.cool.Class', {
357 * My.cool.Class.create({
361 * All parameters are passed to the constructor of the class.
363 * @return {Object} the created instance.
368 return Ext.create.apply(Ext, [this].concat(Array.prototype.slice.call(arguments, 0)));
371 <span id='Ext-Base-method-own'> /**
375 own: function(name, value) {
376 if (typeof value == 'function') {
377 this.ownMethod(name, value);
380 this.prototype[name] = value;
384 <span id='Ext-Base-method-ownMethod'> /**
388 ownMethod: function(name, fn) {
391 if (typeof fn.$owner !== 'undefined' && fn !== Ext.emptyFn) {
395 return originalFn.apply(this, arguments);
401 className = Ext.getClassName(this);
403 fn.displayName = className + '#' + name;
409 this.prototype[name] = fn;
412 <span id='Ext-Base-static-method-addStatics'> /**
413 </span> * Add / override static properties of this class.
415 * Ext.define('My.cool.Class', {
419 * My.cool.Class.addStatics({
420 * someProperty: 'someValue', // My.cool.Class.someProperty = 'someValue'
421 * method1: function() { ... }, // My.cool.Class.method1 = function() { ... };
422 * method2: function() { ... } // My.cool.Class.method2 = function() { ... };
425 * @param {Object} members
426 * @return {Ext.Base} this
430 addStatics: function(members) {
431 for (var name in members) {
432 if (members.hasOwnProperty(name)) {
433 this[name] = members[name];
440 <span id='Ext-Base-method-addInheritableStatics'> /**
442 * @param {Object} members
444 addInheritableStatics: function(members) {
445 var inheritableStatics,
446 hasInheritableStatics,
447 prototype = this.prototype,
450 inheritableStatics = prototype.$inheritableStatics;
451 hasInheritableStatics = prototype.$hasInheritableStatics;
453 if (!inheritableStatics) {
454 inheritableStatics = prototype.$inheritableStatics = [];
455 hasInheritableStatics = prototype.$hasInheritableStatics = {};
459 var className = Ext.getClassName(this);
462 for (name in members) {
463 if (members.hasOwnProperty(name)) {
464 member = members[name];
466 if (typeof member == 'function') {
467 member.displayName = className + '.' + name;
472 if (!hasInheritableStatics[name]) {
473 hasInheritableStatics[name] = true;
474 inheritableStatics.push(name);
482 <span id='Ext-Base-static-method-implement'> /**
483 </span> * Add methods / properties to the prototype of this class.
485 * Ext.define('My.awesome.Cat', {
486 * constructor: function() {
491 * My.awesome.Cat.implement({
493 * alert('Meowww...');
497 * var kitty = new My.awesome.Cat;
500 * @param {Object} members
504 implement: function(members) {
505 var prototype = this.prototype,
506 enumerables = Ext.enumerables,
509 var className = Ext.getClassName(this);
511 for (name in members) {
512 if (members.hasOwnProperty(name)) {
513 member = members[name];
515 if (typeof member === 'function') {
516 member.$owner = this;
520 member.displayName = className + '#' + name;
525 prototype[name] = member;
530 for (i = enumerables.length; i--;) {
531 name = enumerables[i];
533 if (members.hasOwnProperty(name)) {
534 member = members[name];
535 member.$owner = this;
537 prototype[name] = member;
543 <span id='Ext-Base-static-method-borrow'> /**
544 </span> * Borrow another class' members to the prototype of this class.
546 * Ext.define('Bank', {
548 * printMoney: function() {
553 * Ext.define('Thief', {
557 * Thief.borrow(Bank, ['money', 'printMoney']);
559 * var steve = new Thief();
561 * alert(steve.money); // alerts '$$$'
562 * steve.printMoney(); // alerts '$$$$$$$'
564 * @param {Ext.Base} fromClass The class to borrow members from
565 * @param {String/String[]} members The names of the members to borrow
566 * @return {Ext.Base} this
570 borrow: function(fromClass, members) {
571 var fromPrototype = fromClass.prototype,
574 members = Ext.Array.from(members);
576 for (i = 0, ln = members.length; i < ln; i++) {
579 this.own(member, fromPrototype[member]);
585 <span id='Ext-Base-static-method-override'> /**
586 </span> * Override prototype members of this class. Overridden methods can be invoked via
587 * {@link Ext.Base#callOverridden}
589 * Ext.define('My.Cat', {
590 * constructor: function() {
591 * alert("I'm a cat!");
598 * constructor: function() {
599 * alert("I'm going to be a cat!");
601 * var instance = this.callOverridden();
603 * alert("Meeeeoooowwww");
609 * var kitty = new My.Cat(); // alerts "I'm going to be a cat!"
610 * // alerts "I'm a cat!"
611 * // alerts "Meeeeoooowwww"
613 * @param {Object} members
614 * @return {Ext.Base} this
618 override: function(members) {
619 var prototype = this.prototype,
620 enumerables = Ext.enumerables,
621 name, i, member, previous;
623 if (arguments.length === 2) {
625 member = arguments[1];
627 if (typeof member == 'function') {
628 if (typeof prototype[name] == 'function') {
629 previous = prototype[name];
630 member.$previous = previous;
633 this.ownMethod(name, member);
636 prototype[name] = member;
642 for (name in members) {
643 if (members.hasOwnProperty(name)) {
644 member = members[name];
646 if (typeof member === 'function') {
647 if (typeof prototype[name] === 'function') {
648 previous = prototype[name];
649 member.$previous = previous;
652 this.ownMethod(name, member);
655 prototype[name] = member;
661 for (i = enumerables.length; i--;) {
662 name = enumerables[i];
664 if (members.hasOwnProperty(name)) {
665 if (typeof prototype[name] !== 'undefined') {
666 previous = prototype[name];
667 members[name].$previous = previous;
670 this.ownMethod(name, members[name]);
678 //<feature classSystem.mixins>
679 <span id='Ext-Base-method-mixin'> /**
680 </span> * Used internally by the mixins pre-processor
684 mixin: function(name, cls) {
685 var mixin = cls.prototype,
690 if (mixin.hasOwnProperty(key)) {
691 if (typeof my[key] === 'undefined' && key !== 'mixins' && key !== 'mixinId') {
692 if (typeof mixin[key] === 'function') {
695 if (typeof fn.$owner === 'undefined') {
696 this.ownMethod(key, fn);
703 my[key] = mixin[key];
706 //<feature classSystem.config>
707 else if (key === 'config' && my.config && mixin.config) {
708 Ext.Object.merge(my.config, mixin.config);
714 if (typeof mixin.onClassMixedIn !== 'undefined') {
715 mixin.onClassMixedIn.call(cls, this);
718 if (!my.hasOwnProperty('mixins')) {
719 if ('mixins' in my) {
720 my.mixins = Ext.Object.merge({}, my.mixins);
727 my.mixins[name] = mixin;
731 <span id='Ext-Base-static-method-getName'> /**
732 </span> * Get the current class' name in string format.
734 * Ext.define('My.cool.Class', {
735 * constructor: function() {
736 * alert(this.self.getName()); // alerts 'My.cool.Class'
740 * My.cool.Class.getName(); // 'My.cool.Class'
742 * @return {String} className
746 getName: function() {
747 return Ext.getClassName(this);
750 <span id='Ext-Base-static-method-createAlias'> /**
751 </span> * Create aliases for existing prototype methods. Example:
753 * Ext.define('My.cool.Class', {
754 * method1: function() { ... },
755 * method2: function() { ... }
758 * var test = new My.cool.Class();
760 * My.cool.Class.createAlias({
761 * method3: 'method1',
765 * test.method3(); // test.method1()
767 * My.cool.Class.createAlias('method5', 'method3');
769 * test.method5(); // test.method3() -> test.method1()
771 * @param {String/Object} alias The new method name, or an object to set multiple aliases. See
772 * {@link Ext.Function#flexSetter flexSetter}
773 * @param {String/Object} origin The original method name
778 createAlias: flexSetter(function(alias, origin) {
779 this.prototype[alias] = function() {
780 return this[origin].apply(this, arguments);
785 })(Ext.Function.flexSetter);