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