Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / docs / source / Ext-more.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5   <title>The source code</title>
6   <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../prettify/prettify.js"></script>
8   <style type="text/css">
9     .highlight { display: block; background-color: #ddd; }
10   </style>
11   <script type="text/javascript">
12     function highlight() {
13       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
14     }
15   </script>
16 </head>
17 <body onload="prettyPrint(); highlight();">
18   <pre class="prettyprint lang-js"><span id='Ext'>/**
19 </span> * @class Ext
20
21  The Ext namespace (global object) encapsulates all classes, singletons, and utility methods provided by Sencha's libraries.&lt;/p&gt;
22  Most user interface Components are at a lower level of nesting in the namespace, but many common utility functions are provided
23  as direct properties of the Ext namespace.
24
25  Also many frequently used methods from other classes are provided as shortcuts within the Ext namespace.
26  For example {@link Ext#getCmp Ext.getCmp} aliases {@link Ext.ComponentManager#get Ext.ComponentManager.get}.
27
28  Many applications are initiated with {@link Ext#onReady Ext.onReady} which is called once the DOM is ready.
29  This ensures all scripts have been loaded, preventing dependency issues. For example
30
31      Ext.onReady(function(){
32          new Ext.Component({
33              renderTo: document.body,
34              html: 'DOM ready!'
35          });
36      });
37
38 For more information about how to use the Ext classes, see
39
40 - &lt;a href=&quot;http://www.sencha.com/learn/&quot;&gt;The Learning Center&lt;/a&gt;
41 - &lt;a href=&quot;http://www.sencha.com/learn/Ext_FAQ&quot;&gt;The FAQ&lt;/a&gt;
42 - &lt;a href=&quot;http://www.sencha.com/forum/&quot;&gt;The forums&lt;/a&gt;
43
44  * @singleton
45  * @markdown
46  */
47 Ext.apply(Ext, {
48     userAgent: navigator.userAgent.toLowerCase(),
49     cache: {},
50     idSeed: 1000,
51     BLANK_IMAGE_URL : 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',
52     isStrict: document.compatMode == &quot;CSS1Compat&quot;,
53     windowId: 'ext-window',
54     documentId: 'ext-document',
55
56 <span id='Ext-property-isReady'>    /**
57 </span>     * True when the document is fully initialized and ready for action
58      * @type Boolean
59      */
60     isReady: false,
61
62 <span id='Ext-property-enableGarbageCollector'>    /**
63 </span>     * True to automatically uncache orphaned Ext.core.Elements periodically (defaults to true)
64      * @type Boolean
65      */
66     enableGarbageCollector: true,
67
68 <span id='Ext-property-enableListenerCollection'>    /**
69 </span>     * True to automatically purge event listeners during garbageCollection (defaults to true).
70      * @type Boolean
71      */
72     enableListenerCollection: true,
73
74 <span id='Ext-method-id'>    /**
75 </span>     * Generates unique ids. If the element already has an id, it is unchanged
76      * @param {Mixed} el (optional) The element to generate an id for
77      * @param {String} prefix (optional) Id prefix (defaults &quot;ext-gen&quot;)
78      * @return {String} The generated Id.
79      */
80     id: function(el, prefix) {
81         var me = this,
82             sandboxPrefix = '';
83         el = Ext.getDom(el, true) || {};
84         if (el === document) {
85             el.id = me.documentId;
86         }
87         else if (el === window) {
88             el.id = me.windowId;
89         }
90         if (!el.id) {
91             if (me.isSandboxed) {
92                 if (!me.uniqueGlobalNamespace) {
93                     me.getUniqueGlobalNamespace();
94                 }
95                 sandboxPrefix = me.uniqueGlobalNamespace + '-';
96             }
97             el.id = sandboxPrefix + (prefix || &quot;ext-gen&quot;) + (++Ext.idSeed);
98         }
99         return el.id;
100     },
101
102 <span id='Ext-method-getBody'>    /**
103 </span>     * Returns the current document body as an {@link Ext.core.Element}.
104      * @return Ext.core.Element The document body
105      */
106     getBody: function() {
107         return Ext.get(document.body || false);
108     },
109
110 <span id='Ext-method-getHead'>    /**
111 </span>     * Returns the current document head as an {@link Ext.core.Element}.
112      * @return Ext.core.Element The document head
113      * @method
114      */
115     getHead: function() {
116         var head;
117
118         return function() {
119             if (head == undefined) {
120                 head = Ext.get(document.getElementsByTagName(&quot;head&quot;)[0]);
121             }
122
123             return head;
124         };
125     }(),
126
127 <span id='Ext-method-getDoc'>    /**
128 </span>     * Returns the current HTML document object as an {@link Ext.core.Element}.
129      * @return Ext.core.Element The document
130      */
131     getDoc: function() {
132         return Ext.get(document);
133     },
134
135 <span id='Ext-method-getCmp'>    /**
136 </span>     * This is shorthand reference to {@link Ext.ComponentManager#get}.
137      * Looks up an existing {@link Ext.Component Component} by {@link Ext.Component#id id}
138      * @param {String} id The component {@link Ext.Component#id id}
139      * @return Ext.Component The Component, &lt;tt&gt;undefined&lt;/tt&gt; if not found, or &lt;tt&gt;null&lt;/tt&gt; if a
140      * Class was found.
141     */
142     getCmp: function(id) {
143         return Ext.ComponentManager.get(id);
144     },
145
146 <span id='Ext-method-getOrientation'>    /**
147 </span>     * Returns the current orientation of the mobile device
148      * @return {String} Either 'portrait' or 'landscape'
149      */
150     getOrientation: function() {
151         return window.innerHeight &gt; window.innerWidth ? 'portrait' : 'landscape';
152     },
153
154 <span id='Ext-method-destroy'>    /**
155 </span>     * Attempts to destroy any objects passed to it by removing all event listeners, removing them from the
156      * DOM (if applicable) and calling their destroy functions (if available).  This method is primarily
157      * intended for arguments of type {@link Ext.core.Element} and {@link Ext.Component}, but any subclass of
158      * {@link Ext.util.Observable} can be passed in.  Any number of elements and/or components can be
159      * passed into this function in a single call as separate arguments.
160      * @param {Mixed} arg1 An {@link Ext.core.Element}, {@link Ext.Component}, or an Array of either of these to destroy
161      * @param {Mixed} arg2 (optional)
162      * @param {Mixed} etc... (optional)
163      */
164     destroy: function() {
165         var ln = arguments.length,
166         i, arg;
167
168         for (i = 0; i &lt; ln; i++) {
169             arg = arguments[i];
170             if (arg) {
171                 if (Ext.isArray(arg)) {
172                     this.destroy.apply(this, arg);
173                 }
174                 else if (Ext.isFunction(arg.destroy)) {
175                     arg.destroy();
176                 }
177                 else if (arg.dom) {
178                     arg.remove();
179                 }
180             }
181         }
182     },
183
184 <span id='Ext-method-callback'>    /**
185 </span>     * Execute a callback function in a particular scope. If no function is passed the call is ignored.
186      * 
187      * For example, these lines are equivalent:
188      * 
189      *     Ext.callback(myFunc, this, [arg1, arg2]);
190      *     Ext.isFunction(myFunc) &amp;&amp; myFunc.apply(this, [arg1, arg2]);
191      * 
192      * @param {Function} callback The callback to execute
193      * @param {Object} scope (optional) The scope to execute in
194      * @param {Array} args (optional) The arguments to pass to the function
195      * @param {Number} delay (optional) Pass a number to delay the call by a number of milliseconds.
196      */
197     callback: function(callback, scope, args, delay){
198         if(Ext.isFunction(callback)){
199             args = args || [];
200             scope = scope || window;
201             if (delay) {
202                 Ext.defer(callback, delay, scope, args);
203             } else {
204                 callback.apply(scope, args);
205             }
206         }
207     },
208
209 <span id='Ext-method-htmlEncode'>    /**
210 </span>     * Convert certain characters (&amp;, &lt;, &gt;, and ') to their HTML character equivalents for literal display in web pages.
211      * @param {String} value The string to encode
212      * @return {String} The encoded text
213      */
214     htmlEncode : function(value) {
215         return Ext.String.htmlEncode(value);
216     },
217
218 <span id='Ext-method-htmlDecode'>    /**
219 </span>     * Convert certain characters (&amp;, &lt;, &gt;, and ') from their HTML character equivalents.
220      * @param {String} value The string to decode
221      * @return {String} The decoded text
222      */
223     htmlDecode : function(value) {
224          return Ext.String.htmlDecode(value);
225     },
226
227 <span id='Ext-method-urlAppend'>    /**
228 </span>     * Appends content to the query string of a URL, handling logic for whether to place
229      * a question mark or ampersand.
230      * @param {String} url The URL to append to.
231      * @param {String} s The content to append to the URL.
232      * @return (String) The resulting URL
233      */
234     urlAppend : function(url, s) {
235         if (!Ext.isEmpty(s)) {
236             return url + (url.indexOf('?') === -1 ? '?' : '&amp;') + s;
237         }
238         return url;
239     }
240 });
241
242
243 Ext.ns = Ext.namespace;
244
245 // for old browsers
246 window.undefined = window.undefined;
247
248 <span id='Ext'>/**
249 </span> * @class Ext
250  * Ext core utilities and functions.
251  * @singleton
252  */
253 (function(){
254     var check = function(regex){
255             return regex.test(Ext.userAgent);
256         },
257         docMode = document.documentMode,
258         isOpera = check(/opera/),
259         isOpera10_5 = isOpera &amp;&amp; check(/version\/10\.5/),
260         isChrome = check(/\bchrome\b/),
261         isWebKit = check(/webkit/),
262         isSafari = !isChrome &amp;&amp; check(/safari/),
263         isSafari2 = isSafari &amp;&amp; check(/applewebkit\/4/), // unique to Safari 2
264         isSafari3 = isSafari &amp;&amp; check(/version\/3/),
265         isSafari4 = isSafari &amp;&amp; check(/version\/4/),
266         isIE = !isOpera &amp;&amp; check(/msie/),
267         isIE7 = isIE &amp;&amp; (check(/msie 7/) || docMode == 7),
268         isIE8 = isIE &amp;&amp; (check(/msie 8/) &amp;&amp; docMode != 7 &amp;&amp; docMode != 9 || docMode == 8),
269         isIE9 = isIE &amp;&amp; (check(/msie 9/) &amp;&amp; docMode != 7 &amp;&amp; docMode != 8 || docMode == 9),
270         isIE6 = isIE &amp;&amp; check(/msie 6/),
271         isGecko = !isWebKit &amp;&amp; check(/gecko/),
272         isGecko3 = isGecko &amp;&amp; check(/rv:1\.9/),
273         isGecko4 = isGecko &amp;&amp; check(/rv:2\.0/),
274         isFF3_0 = isGecko3 &amp;&amp; check(/rv:1\.9\.0/),
275         isFF3_5 = isGecko3 &amp;&amp; check(/rv:1\.9\.1/),
276         isFF3_6 = isGecko3 &amp;&amp; check(/rv:1\.9\.2/),
277         isWindows = check(/windows|win32/),
278         isMac = check(/macintosh|mac os x/),
279         isLinux = check(/linux/),
280         scrollbarSize = null,
281         webKitVersion = isWebKit &amp;&amp; (/webkit\/(\d+\.\d+)/.exec(Ext.userAgent));
282
283     // remove css image flicker
284     try {
285         document.execCommand(&quot;BackgroundImageCache&quot;, false, true);
286     } catch(e) {}
287
288     Ext.setVersion('extjs', '4.0.2');
289     Ext.apply(Ext, {
290 <span id='Ext-property-SSL_SECURE_URL'>        /**
291 </span>         * URL to a blank file used by Ext when in secure mode for iframe src and onReady src to prevent
292          * the IE insecure content warning (&lt;tt&gt;'about:blank'&lt;/tt&gt;, except for IE in secure mode, which is &lt;tt&gt;'javascript:&quot;&quot;'&lt;/tt&gt;).
293          * @type String
294          */
295         SSL_SECURE_URL : Ext.isSecure &amp;&amp; isIE ? 'javascript:&quot;&quot;' : 'about:blank',
296
297 <span id='Ext-property-enableFx'>        /**
298 </span>         * True if the {@link Ext.fx.Anim} Class is available
299          * @type Boolean
300          * @property enableFx
301          */
302
303 <span id='Ext-property-scopeResetCSS'>        /**
304 </span>         * True to scope the reset CSS to be just applied to Ext components. Note that this wraps root containers
305          * with an additional element. Also remember that when you turn on this option, you have to use ext-all-scoped {
306          * unless you use the bootstrap.js to load your javascript, in which case it will be handled for you.
307          * @type Boolean
308          */
309         scopeResetCSS : Ext.buildSettings.scopeResetCSS,
310
311 <span id='Ext-property-enableNestedListenerRemoval'>        /**
312 </span>         * EXPERIMENTAL - True to cascade listener removal to child elements when an element is removed.
313          * Currently not optimized for performance.
314          * @type Boolean
315          */
316         enableNestedListenerRemoval : false,
317
318 <span id='Ext-property-USE_NATIVE_JSON'>        /**
319 </span>         * Indicates whether to use native browser parsing for JSON methods.
320          * This option is ignored if the browser does not support native JSON methods.
321          * &lt;b&gt;Note: Native JSON methods will not work with objects that have functions.
322          * Also, property names must be quoted, otherwise the data will not parse.&lt;/b&gt; (Defaults to false)
323          * @type Boolean
324          */
325         USE_NATIVE_JSON : false,
326
327 <span id='Ext-method-getDom'>        /**
328 </span>         * Return the dom node for the passed String (id), dom node, or Ext.core.Element.
329          * Optional 'strict' flag is needed for IE since it can return 'name' and
330          * 'id' elements by using getElementById.
331          * Here are some examples:
332          * &lt;pre&gt;&lt;code&gt;
333 // gets dom node based on id
334 var elDom = Ext.getDom('elId');
335 // gets dom node based on the dom node
336 var elDom1 = Ext.getDom(elDom);
337
338 // If we don&amp;#39;t know if we are working with an
339 // Ext.core.Element or a dom node use Ext.getDom
340 function(el){
341     var dom = Ext.getDom(el);
342     // do something with the dom node
343 }
344          * &lt;/code&gt;&lt;/pre&gt;
345          * &lt;b&gt;Note&lt;/b&gt;: the dom node to be found actually needs to exist (be rendered, etc)
346          * when this method is called to be successful.
347          * @param {Mixed} el
348          * @return HTMLElement
349          */
350         getDom : function(el, strict) {
351             if (!el || !document) {
352                 return null;
353             }
354             if (el.dom) {
355                 return el.dom;
356             } else {
357                 if (typeof el == 'string') {
358                     var e = document.getElementById(el);
359                     // IE returns elements with the 'name' and 'id' attribute.
360                     // we do a strict check to return the element with only the id attribute
361                     if (e &amp;&amp; isIE &amp;&amp; strict) {
362                         if (el == e.getAttribute('id')) {
363                             return e;
364                         } else {
365                             return null;
366                         }
367                     }
368                     return e;
369                 } else {
370                     return el;
371                 }
372             }
373         },
374
375 <span id='Ext-method-removeNode'>        /**
376 </span>         * Removes a DOM node from the document.
377          * &lt;p&gt;Removes this element from the document, removes all DOM event listeners, and deletes the cache reference.
378          * All DOM event listeners are removed from this element. If {@link Ext#enableNestedListenerRemoval Ext.enableNestedListenerRemoval} is
379          * &lt;code&gt;true&lt;/code&gt;, then DOM event listeners are also removed from all child nodes. The body node
380          * will be ignored if passed in.&lt;/p&gt;
381          * @param {HTMLElement} node The node to remove
382          * @method
383          */
384         removeNode : isIE6 || isIE7 ? function() {
385             var d;
386             return function(n){
387                 if(n &amp;&amp; n.tagName != 'BODY'){
388                     (Ext.enableNestedListenerRemoval) ? Ext.EventManager.purgeElement(n) : Ext.EventManager.removeAll(n);
389                     d = d || document.createElement('div');
390                     d.appendChild(n);
391                     d.innerHTML = '';
392                     delete Ext.cache[n.id];
393                 }
394             };
395         }() : function(n) {
396             if (n &amp;&amp; n.parentNode &amp;&amp; n.tagName != 'BODY') {
397                 (Ext.enableNestedListenerRemoval) ? Ext.EventManager.purgeElement(n) : Ext.EventManager.removeAll(n);
398                 n.parentNode.removeChild(n);
399                 delete Ext.cache[n.id];
400             }
401         },
402
403 <span id='Ext-property-isOpera'>        /**
404 </span>         * True if the detected browser is Opera.
405          * @type Boolean
406          */
407         isOpera : isOpera,
408
409 <span id='Ext-property-isOpera10_5'>        /**
410 </span>         * True if the detected browser is Opera 10.5x.
411          * @type Boolean
412          */
413         isOpera10_5 : isOpera10_5,
414
415 <span id='Ext-property-isWebKit'>        /**
416 </span>         * True if the detected browser uses WebKit.
417          * @type Boolean
418          */
419         isWebKit : isWebKit,
420
421 <span id='Ext-property-isChrome'>        /**
422 </span>         * True if the detected browser is Chrome.
423          * @type Boolean
424          */
425         isChrome : isChrome,
426
427 <span id='Ext-property-isSafari'>        /**
428 </span>         * True if the detected browser is Safari.
429          * @type Boolean
430          */
431         isSafari : isSafari,
432
433 <span id='Ext-property-isSafari3'>        /**
434 </span>         * True if the detected browser is Safari 3.x.
435          * @type Boolean
436          */
437         isSafari3 : isSafari3,
438
439 <span id='Ext-property-isSafari4'>        /**
440 </span>         * True if the detected browser is Safari 4.x.
441          * @type Boolean
442          */
443         isSafari4 : isSafari4,
444
445 <span id='Ext-property-isSafari2'>        /**
446 </span>         * True if the detected browser is Safari 2.x.
447          * @type Boolean
448          */
449         isSafari2 : isSafari2,
450
451 <span id='Ext-property-isIE'>        /**
452 </span>         * True if the detected browser is Internet Explorer.
453          * @type Boolean
454          */
455         isIE : isIE,
456
457 <span id='Ext-property-isIE6'>        /**
458 </span>         * True if the detected browser is Internet Explorer 6.x.
459          * @type Boolean
460          */
461         isIE6 : isIE6,
462
463 <span id='Ext-property-isIE7'>        /**
464 </span>         * True if the detected browser is Internet Explorer 7.x.
465          * @type Boolean
466          */
467         isIE7 : isIE7,
468
469 <span id='Ext-property-isIE8'>        /**
470 </span>         * True if the detected browser is Internet Explorer 8.x.
471          * @type Boolean
472          */
473         isIE8 : isIE8,
474
475 <span id='Ext-property-isIE9'>        /**
476 </span>         * True if the detected browser is Internet Explorer 9.x.
477          * @type Boolean
478          */
479         isIE9 : isIE9,
480
481 <span id='Ext-property-isGecko'>        /**
482 </span>         * True if the detected browser uses the Gecko layout engine (e.g. Mozilla, Firefox).
483          * @type Boolean
484          */
485         isGecko : isGecko,
486
487 <span id='Ext-property-isGecko3'>        /**
488 </span>         * True if the detected browser uses a Gecko 1.9+ layout engine (e.g. Firefox 3.x).
489          * @type Boolean
490          */
491         isGecko3 : isGecko3,
492
493 <span id='Ext-property-isGecko4'>        /**
494 </span>         * True if the detected browser uses a Gecko 2.0+ layout engine (e.g. Firefox 4.x).
495          * @type Boolean
496          */
497         isGecko4 : isGecko4,
498
499 <span id='Ext-property-isFF3_0'>        /**
500 </span>         * True if the detected browser uses FireFox 3.0
501          * @type Boolean
502          */
503
504         isFF3_0 : isFF3_0,
505 <span id='Ext-property-isFF3_5'>        /**
506 </span>         * True if the detected browser uses FireFox 3.5
507          * @type Boolean
508          */
509
510         isFF3_5 : isFF3_5,
511 <span id='Ext-property-isFF3_6'>        /**
512 </span>         * True if the detected browser uses FireFox 3.6
513          * @type Boolean
514          */
515         isFF3_6 : isFF3_6,
516
517 <span id='Ext-property-isLinux'>        /**
518 </span>         * True if the detected platform is Linux.
519          * @type Boolean
520          */
521         isLinux : isLinux,
522
523 <span id='Ext-property-isWindows'>        /**
524 </span>         * True if the detected platform is Windows.
525          * @type Boolean
526          */
527         isWindows : isWindows,
528
529 <span id='Ext-property-isMac'>        /**
530 </span>         * True if the detected platform is Mac OS.
531          * @type Boolean
532          */
533         isMac : isMac,
534
535 <span id='Ext-property-webKitVersion'>        /**
536 </span>         * The current version of WebKit (-1 if the browser does not use WebKit).
537          * @type Float
538          */
539         webKitVersion: webKitVersion ? parseFloat(webKitVersion[1]) : -1,
540
541 <span id='Ext-property-BLANK_IMAGE_URL'>        /**
542 </span>         * URL to a 1x1 transparent gif image used by Ext to create inline icons with CSS background images.
543          * In older versions of IE, this defaults to &quot;http://sencha.com/s.gif&quot; and you should change this to a URL on your server.
544          * For other browsers it uses an inline data URL.
545          * @type String
546          */
547         BLANK_IMAGE_URL : (isIE6 || isIE7) ? 'http:/' + '/www.sencha.com/s.gif' : 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',
548
549 <span id='Ext-method-value'>        /**
550 </span>         * &lt;p&gt;Utility method for returning a default value if the passed value is empty.&lt;/p&gt;
551          * &lt;p&gt;The value is deemed to be empty if it is&lt;div class=&quot;mdetail-params&quot;&gt;&lt;ul&gt;
552          * &lt;li&gt;null&lt;/li&gt;
553          * &lt;li&gt;undefined&lt;/li&gt;
554          * &lt;li&gt;an empty array&lt;/li&gt;
555          * &lt;li&gt;a zero length string (Unless the &lt;tt&gt;allowBlank&lt;/tt&gt; parameter is &lt;tt&gt;true&lt;/tt&gt;)&lt;/li&gt;
556          * &lt;/ul&gt;&lt;/div&gt;
557          * @param {Mixed} value The value to test
558          * @param {Mixed} defaultValue The value to return if the original value is empty
559          * @param {Boolean} allowBlank (optional) true to allow zero length strings to qualify as non-empty (defaults to false)
560          * @return {Mixed} value, if non-empty, else defaultValue
561          * @deprecated 4.0.0 Use {@link Ext#valueFrom} instead
562          */
563         value : function(v, defaultValue, allowBlank){
564             return Ext.isEmpty(v, allowBlank) ? defaultValue : v;
565         },
566
567 <span id='Ext-method-escapeRe'>        /**
568 </span>         * Escapes the passed string for use in a regular expression
569          * @param {String} str
570          * @return {String}
571          * @deprecated 4.0.0 Use {@link Ext.String#escapeRegex} instead
572          */
573         escapeRe : function(s) {
574             return s.replace(/([-.*+?^${}()|[\]\/\\])/g, &quot;\\$1&quot;);
575         },
576
577 <span id='Ext-method-addBehaviors'>        /**
578 </span>         * Applies event listeners to elements by selectors when the document is ready.
579          * The event name is specified with an &lt;tt&gt;&amp;#64;&lt;/tt&gt; suffix.
580          * &lt;pre&gt;&lt;code&gt;
581 Ext.addBehaviors({
582     // add a listener for click on all anchors in element with id foo
583     '#foo a&amp;#64;click' : function(e, t){
584         // do something
585     },
586
587     // add the same listener to multiple selectors (separated by comma BEFORE the &amp;#64;)
588     '#foo a, #bar span.some-class&amp;#64;mouseover' : function(){
589         // do something
590     }
591 });
592          * &lt;/code&gt;&lt;/pre&gt;
593          * @param {Object} obj The list of behaviors to apply
594          */
595         addBehaviors : function(o){
596             if(!Ext.isReady){
597                 Ext.onReady(function(){
598                     Ext.addBehaviors(o);
599                 });
600             } else {
601                 var cache = {}, // simple cache for applying multiple behaviors to same selector does query multiple times
602                     parts,
603                     b,
604                     s;
605                 for (b in o) {
606                     if ((parts = b.split('@'))[1]) { // for Object prototype breakers
607                         s = parts[0];
608                         if(!cache[s]){
609                             cache[s] = Ext.select(s);
610                         }
611                         cache[s].on(parts[1], o[b]);
612                     }
613                 }
614                 cache = null;
615             }
616         },
617
618 <span id='Ext-method-getScrollbarSize'>        /**
619 </span>         * Returns the size of the browser scrollbars. This can differ depending on
620          * operating system settings, such as the theme or font size.
621          * @param {Boolean} force (optional) true to force a recalculation of the value.
622          * @return {Object} An object containing the width of a vertical scrollbar and the
623          * height of a horizontal scrollbar.
624          */
625         getScrollbarSize: function (force) {
626             if(!Ext.isReady){
627                 return 0;
628             }
629
630             if(force === true || scrollbarSize === null){
631                 // BrowserBug: IE9
632                 // When IE9 positions an element offscreen via offsets, the offsetWidth is
633                 // inaccurately reported. For IE9 only, we render on screen before removing.
634                 var cssClass = Ext.isIE9 ? '' : Ext.baseCSSPrefix + 'hide-offsets',
635                     // Append our div, do our calculation and then remove it
636                     div = Ext.getBody().createChild('&lt;div class=&quot;' + cssClass + '&quot; style=&quot;width:100px;height:50px;overflow:hidden;&quot;&gt;&lt;div style=&quot;height:200px;&quot;&gt;&lt;/div&gt;&lt;/div&gt;'),
637                     child = div.child('div', true),
638                     w1 = child.offsetWidth;
639
640                 div.setStyle('overflow', (Ext.isWebKit || Ext.isGecko) ? 'auto' : 'scroll');
641
642                 var w2 = child.offsetWidth, width = w1 - w2;
643                 div.remove();
644
645                 // We assume width == height for now. TODO: is this always true?
646                 scrollbarSize = { width: width, height: width };
647             }
648
649             return scrollbarSize;
650         },
651
652 <span id='Ext-method-getScrollBarWidth'>        /**
653 </span>         * Utility method for getting the width of the browser's vertical scrollbar. This
654          * can differ depending on operating system settings, such as the theme or font size.
655          *
656          * This method is deprected in favor of {@link #getScrollbarSize}.
657          *
658          * @param {Boolean} force (optional) true to force a recalculation of the value.
659          * @return {Number} The width of a vertical scrollbar.
660          * @deprecated
661          */
662         getScrollBarWidth: function(force){
663             var size = Ext.getScrollbarSize(force);
664             return size.width + 2; // legacy fudge factor
665         },
666
667 <span id='Ext-method-copyTo'>        /**
668 </span>         * Copies a set of named properties fom the source object to the destination object.
669          *
670          * Example:
671          *
672          *     ImageComponent = Ext.extend(Ext.Component, {
673          *         initComponent: function() {
674          *             this.autoEl = { tag: 'img' };
675          *             MyComponent.superclass.initComponent.apply(this, arguments);
676          *             this.initialBox = Ext.copyTo({}, this.initialConfig, 'x,y,width,height');
677          *         }
678          *     });
679          *
680          * Important note: To borrow class prototype methods, use {@link Ext.Base#borrow} instead.
681          *
682          * @param {Object} dest The destination object.
683          * @param {Object} source The source object.
684          * @param {Array/String} names Either an Array of property names, or a comma-delimited list
685          * of property names to copy.
686          * @param {Boolean} usePrototypeKeys (Optional) Defaults to false. Pass true to copy keys off of the prototype as well as the instance.
687          * @return {Object} The modified object.
688          */
689         copyTo : function(dest, source, names, usePrototypeKeys){
690             if(typeof names == 'string'){
691                 names = names.split(/[,;\s]/);
692             }
693             Ext.each(names, function(name){
694                 if(usePrototypeKeys || source.hasOwnProperty(name)){
695                     dest[name] = source[name];
696                 }
697             }, this);
698             return dest;
699         },
700
701 <span id='Ext-method-destroyMembers'>        /**
702 </span>         * Attempts to destroy and then remove a set of named properties of the passed object.
703          * @param {Object} o The object (most likely a Component) who's properties you wish to destroy.
704          * @param {Mixed} arg1 The name of the property to destroy and remove from the object.
705          * @param {Mixed} etc... More property names to destroy and remove.
706          */
707         destroyMembers : function(o){
708             for (var i = 1, a = arguments, len = a.length; i &lt; len; i++) {
709                 Ext.destroy(o[a[i]]);
710                 delete o[a[i]];
711             }
712         },
713
714 <span id='Ext-method-log'>        /**
715 </span>         * Logs a message. If a console is present it will be used. On Opera, the method
716          * &quot;opera.postError&quot; is called. In other cases, the message is logged to an array
717          * &quot;Ext.log.out&quot;. An attached debugger can watch this array and view the log. The
718          * log buffer is limited to a maximum of &quot;Ext.log.max&quot; entries (defaults to 100).
719          *
720          * If additional parameters are passed, they are joined and appended to the message.
721          * 
722          * This method does nothing in a release build.
723          *
724          * @param {String|Object} message The message to log or an options object with any
725          * of the following properties:
726          *
727          *  - `msg`: The message to log (required).
728          *  - `level`: One of: &quot;error&quot;, &quot;warn&quot;, &quot;info&quot; or &quot;log&quot; (the default is &quot;log&quot;).
729          *  - `dump`: An object to dump to the log as part of the message.
730          *  - `stack`: True to include a stack trace in the log.
731          * @markdown
732          */
733         log : function (message) {
734             //&lt;debug&gt;
735             var options, dump,
736                 con = Ext.global.console,
737                 log = Ext.log,
738                 level = 'log',
739                 stack,
740                 members,
741                 member;
742
743             if (!Ext.isString(message)) {
744                 options = message;
745                 message = options.msg || '';
746                 level = options.level || level;
747                 dump = options.dump;
748                 stack = options.stack;
749
750                 if (dump &amp;&amp; !(con &amp;&amp; con.dir)) {
751                     members = [];
752
753                     // Cannot use Ext.encode since it can recurse endlessly (if we're lucky)
754                     // ...and the data could be prettier!
755                     Ext.Object.each(dump, function (name, value) {
756                         if (typeof(value) === &quot;function&quot;) {
757                             return;
758                         }
759
760                         if (!Ext.isDefined(value) || value === null ||
761                                 Ext.isDate(value) ||
762                                 Ext.isString(value) || (typeof(value) == &quot;number&quot;) ||
763                                 Ext.isBoolean(value)) {
764                             member = Ext.encode(value);
765                         } else if (Ext.isArray(value)) {
766                             member = '[ ]';
767                         } else if (Ext.isObject(value)) {
768                             member = '{ }';
769                         } else {
770                             member = 'undefined';
771                         }
772                         members.push(Ext.encode(name) + ': ' + member);
773                     });
774
775                     if (members.length) {
776                         message += ' \nData: {\n  ' + members.join(',\n  ') + '\n}';
777                     }
778                     dump = null;
779                 }
780             }
781
782             if (arguments.length &gt; 1) {
783                 message += Array.prototype.slice.call(arguments, 1).join('');
784             }
785
786             // Not obvious, but 'console' comes and goes when Firebug is turned on/off, so
787             // an early test may fail either direction if Firebug is toggled.
788             //
789             if (con) { // if (Firebug-like console)
790                 if (con[level]) {
791                     con[level](message);
792                 } else {
793                     con.log(message);
794                 }
795
796                 if (dump) {
797                     con.dir(dump);
798                 }
799
800                 if (stack &amp;&amp; con.trace) {
801                     // Firebug's console.error() includes a trace already...
802                     if (!con.firebug || level != 'error') {
803                         con.trace();
804                     }
805                 }
806             } else {
807                 // w/o console, all messages are equal, so munge the level into the message:
808                 if (level != 'log') {
809                     message = level.toUpperCase() + ': ' + message;
810                 }
811
812                 if (Ext.isOpera) {
813                     opera.postError(message);
814                 } else {
815                     var out = log.out || (log.out = []),
816                         max = log.max || (log.max = 100);
817
818                     if (out.length &gt;= max) {
819                         // this formula allows out.max to change (via debugger), where the
820                         // more obvious &quot;max/4&quot; would not quite be the same
821                         Ext.Array.erase(out, 0, out.length - 3 * Math.floor(max / 4)); // keep newest 75%
822                     }
823
824                     out.push(message);
825                 }
826             }
827
828             // Mostly informational, but the Ext.Error notifier uses them:
829             var counters = log.counters ||
830                           (log.counters = { error: 0, warn: 0, info: 0, log: 0 });
831
832             ++counters[level];
833             //&lt;/debug&gt;
834         },
835
836 <span id='Ext-method-partition'>        /**
837 </span>         * Partitions the set into two sets: a true set and a false set.
838          * Example:
839          * Example2:
840          * &lt;pre&gt;&lt;code&gt;
841 // Example 1:
842 Ext.partition([true, false, true, true, false]); // [[true, true, true], [false, false]]
843
844 // Example 2:
845 Ext.partition(
846     Ext.query(&quot;p&quot;),
847     function(val){
848         return val.className == &quot;class1&quot;
849     }
850 );
851 // true are those paragraph elements with a className of &quot;class1&quot;,
852 // false set are those that do not have that className.
853          * &lt;/code&gt;&lt;/pre&gt;
854          * @param {Array|NodeList} arr The array to partition
855          * @param {Function} truth (optional) a function to determine truth.  If this is omitted the element
856          * itself must be able to be evaluated for its truthfulness.
857          * @return {Array} [array of truish values, array of falsy values]
858          * @deprecated 4.0.0 Will be removed in the next major version
859          */
860         partition : function(arr, truth){
861             var ret = [[],[]];
862             Ext.each(arr, function(v, i, a) {
863                 ret[ (truth &amp;&amp; truth(v, i, a)) || (!truth &amp;&amp; v) ? 0 : 1].push(v);
864             });
865             return ret;
866         },
867
868 <span id='Ext-method-invoke'>        /**
869 </span>         * Invokes a method on each item in an Array.
870          * &lt;pre&gt;&lt;code&gt;
871 // Example:
872 Ext.invoke(Ext.query(&quot;p&quot;), &quot;getAttribute&quot;, &quot;id&quot;);
873 // [el1.getAttribute(&quot;id&quot;), el2.getAttribute(&quot;id&quot;), ..., elN.getAttribute(&quot;id&quot;)]
874          * &lt;/code&gt;&lt;/pre&gt;
875          * @param {Array|NodeList} arr The Array of items to invoke the method on.
876          * @param {String} methodName The method name to invoke.
877          * @param {...*} args Arguments to send into the method invocation.
878          * @return {Array} The results of invoking the method on each item in the array.
879          * @deprecated 4.0.0 Will be removed in the next major version
880          */
881         invoke : function(arr, methodName){
882             var ret = [],
883                 args = Array.prototype.slice.call(arguments, 2);
884             Ext.each(arr, function(v,i) {
885                 if (v &amp;&amp; typeof v[methodName] == 'function') {
886                     ret.push(v[methodName].apply(v, args));
887                 } else {
888                     ret.push(undefined);
889                 }
890             });
891             return ret;
892         },
893
894 <span id='Ext-method-zip'>        /**
895 </span>         * &lt;p&gt;Zips N sets together.&lt;/p&gt;
896          * &lt;pre&gt;&lt;code&gt;
897 // Example 1:
898 Ext.zip([1,2,3],[4,5,6]); // [[1,4],[2,5],[3,6]]
899 // Example 2:
900 Ext.zip(
901     [ &quot;+&quot;, &quot;-&quot;, &quot;+&quot;],
902     [  12,  10,  22],
903     [  43,  15,  96],
904     function(a, b, c){
905         return &quot;$&quot; + a + &quot;&quot; + b + &quot;.&quot; + c
906     }
907 ); // [&quot;$+12.43&quot;, &quot;$-10.15&quot;, &quot;$+22.96&quot;]
908          * &lt;/code&gt;&lt;/pre&gt;
909          * @param {Arrays|NodeLists} arr This argument may be repeated. Array(s) to contribute values.
910          * @param {Function} zipper (optional) The last item in the argument list. This will drive how the items are zipped together.
911          * @return {Array} The zipped set.
912          * @deprecated 4.0.0 Will be removed in the next major version
913          */
914         zip : function(){
915             var parts = Ext.partition(arguments, function( val ){ return typeof val != 'function'; }),
916                 arrs = parts[0],
917                 fn = parts[1][0],
918                 len = Ext.max(Ext.pluck(arrs, &quot;length&quot;)),
919                 ret = [];
920
921             for (var i = 0; i &lt; len; i++) {
922                 ret[i] = [];
923                 if(fn){
924                     ret[i] = fn.apply(fn, Ext.pluck(arrs, i));
925                 }else{
926                     for (var j = 0, aLen = arrs.length; j &lt; aLen; j++){
927                         ret[i].push( arrs[j][i] );
928                     }
929                 }
930             }
931             return ret;
932         },
933
934 <span id='Ext-method-toSentence'>        /**
935 </span>         * Turns an array into a sentence, joined by a specified connector - e.g.:
936          * Ext.toSentence(['Adama', 'Tigh', 'Roslin']); //'Adama, Tigh and Roslin'
937          * Ext.toSentence(['Adama', 'Tigh', 'Roslin'], 'or'); //'Adama, Tigh or Roslin'
938          * @param {Array} items The array to create a sentence from
939          * @param {String} connector The string to use to connect the last two words. Usually 'and' or 'or' - defaults to 'and'.
940          * @return {String} The sentence string
941          * @deprecated 4.0.0 Will be removed in the next major version
942          */
943         toSentence: function(items, connector) {
944             var length = items.length;
945
946             if (length &lt;= 1) {
947                 return items[0];
948             } else {
949                 var head = items.slice(0, length - 1),
950                     tail = items[length - 1];
951
952                 return Ext.util.Format.format(&quot;{0} {1} {2}&quot;, head.join(&quot;, &quot;), connector || 'and', tail);
953             }
954         },
955
956 <span id='Ext-property-useShims'>        /**
957 </span>         * By default, Ext intelligently decides whether floating elements should be shimmed. If you are using flash,
958          * you may want to set this to true.
959          * @type Boolean
960          */
961         useShims: isIE6
962     });
963 })();
964
965 <span id='Ext-method-application'>/**
966 </span> * Loads Ext.app.Application class and starts it up with given configuration after the page is ready.
967  *
968  * See Ext.app.Application for details.
969  *
970  * @param {Object} config
971  */
972 Ext.application = function(config) {
973     Ext.require('Ext.app.Application');
974
975     Ext.onReady(function() {
976         Ext.create('Ext.app.Application', config);
977     });
978 };
979 </pre>
980 </body>
981 </html>