Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / docs / source / Support.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-is'>/**
19 </span> * @class Ext.is
20  * 
21  * Determines information about the current platform the application is running on.
22  * 
23  * @singleton
24  */
25 Ext.is = {
26     init : function(navigator) {
27         var platforms = this.platforms,
28             ln = platforms.length,
29             i, platform;
30
31         navigator = navigator || window.navigator;
32
33         for (i = 0; i &lt; ln; i++) {
34             platform = platforms[i];
35             this[platform.identity] = platform.regex.test(navigator[platform.property]);
36         }
37
38 <span id='Ext-is-property-Desktop'>        /**
39 </span>         * @property Desktop True if the browser is running on a desktop machine
40          * @type {Boolean}
41          */
42         this.Desktop = this.Mac || this.Windows || (this.Linux &amp;&amp; !this.Android);
43 <span id='Ext-is-property-Tablet'>        /**
44 </span>         * @property Tablet True if the browser is running on a tablet (iPad)
45          */
46         this.Tablet = this.iPad;
47 <span id='Ext-is-property-Phone'>        /**
48 </span>         * @property Phone True if the browser is running on a phone.
49          * @type {Boolean}
50          */
51         this.Phone = !this.Desktop &amp;&amp; !this.Tablet;
52 <span id='Ext-is-property-iOS'>        /**
53 </span>         * @property iOS True if the browser is running on iOS
54          * @type {Boolean}
55          */
56         this.iOS = this.iPhone || this.iPad || this.iPod;
57         
58 <span id='Ext-is-property-Standalone'>        /**
59 </span>         * @property Standalone Detects when application has been saved to homescreen.
60          * @type {Boolean}
61          */
62         this.Standalone = !!window.navigator.standalone;
63     },
64     
65 <span id='Ext-is-property-iPhone'>    /**
66 </span>     * @property iPhone True when the browser is running on a iPhone
67      * @type {Boolean}
68      */
69     platforms: [{
70         property: 'platform',
71         regex: /iPhone/i,
72         identity: 'iPhone'
73     },
74     
75 <span id='Ext-is-property-iPod'>    /**
76 </span>     * @property iPod True when the browser is running on a iPod
77      * @type {Boolean}
78      */
79     {
80         property: 'platform',
81         regex: /iPod/i,
82         identity: 'iPod'
83     },
84     
85 <span id='Ext-is-property-iPad'>    /**
86 </span>     * @property iPad True when the browser is running on a iPad
87      * @type {Boolean}
88      */
89     {
90         property: 'userAgent',
91         regex: /iPad/i,
92         identity: 'iPad'
93     },
94     
95 <span id='Ext-is-property-Blackberry'>    /**
96 </span>     * @property Blackberry True when the browser is running on a Blackberry
97      * @type {Boolean}
98      */
99     {
100         property: 'userAgent',
101         regex: /Blackberry/i,
102         identity: 'Blackberry'
103     },
104     
105 <span id='Ext-is-property-Android'>    /**
106 </span>     * @property Android True when the browser is running on an Android device
107      * @type {Boolean}
108      */
109     {
110         property: 'userAgent',
111         regex: /Android/i,
112         identity: 'Android'
113     },
114     
115 <span id='Ext-is-property-Mac'>    /**
116 </span>     * @property Mac True when the browser is running on a Mac
117      * @type {Boolean}
118      */
119     {
120         property: 'platform',
121         regex: /Mac/i,
122         identity: 'Mac'
123     },
124     
125 <span id='Ext-is-property-Windows'>    /**
126 </span>     * @property Windows True when the browser is running on Windows
127      * @type {Boolean}
128      */
129     {
130         property: 'platform',
131         regex: /Win/i,
132         identity: 'Windows'
133     },
134     
135 <span id='Ext-is-property-Linux'>    /**
136 </span>     * @property Linux True when the browser is running on Linux
137      * @type {Boolean}
138      */
139     {
140         property: 'platform',
141         regex: /Linux/i,
142         identity: 'Linux'
143     }]
144 };
145
146 Ext.is.init();
147
148 <span id='Ext-supports'>/**
149 </span> * @class Ext.supports
150  *
151  * Determines information about features are supported in the current environment
152  * 
153  * @singleton
154  */
155 Ext.supports = {
156     init : function() {
157         var doc = document,
158             div = doc.createElement('div'),
159             tests = this.tests,
160             ln = tests.length,
161             i, test;
162
163         div.innerHTML = [
164             '&lt;div style=&quot;height:30px;width:50px;&quot;&gt;',
165                 '&lt;div style=&quot;height:20px;width:20px;&quot;&gt;&lt;/div&gt;',
166             '&lt;/div&gt;',
167             '&lt;div style=&quot;width: 200px; height: 200px; position: relative; padding: 5px;&quot;&gt;',
168                 '&lt;div style=&quot;position: absolute; top: 0; left: 0; width: 100%; height: 100%;&quot;&gt;&lt;/div&gt;',
169             '&lt;/div&gt;',
170             '&lt;div style=&quot;float:left; background-color:transparent;&quot;&gt;&lt;/div&gt;'
171         ].join('');
172
173         doc.body.appendChild(div);
174
175         for (i = 0; i &lt; ln; i++) {
176             test = tests[i];
177             this[test.identity] = test.fn.call(this, doc, div);
178         }
179
180         doc.body.removeChild(div);
181     },
182
183 <span id='Ext-supports-property-CSS3BoxShadow'>    /**
184 </span>     * @property CSS3BoxShadow True if document environment supports the CSS3 box-shadow style.
185      * @type {Boolean}
186      */
187     CSS3BoxShadow: Ext.isDefined(document.documentElement.style.boxShadow),
188
189 <span id='Ext-supports-property-ClassList'>    /**
190 </span>     * @property ClassList True if document environment supports the HTML5 classList API.
191      * @type {Boolean}
192      */
193     ClassList: !!document.documentElement.classList,
194
195 <span id='Ext-supports-property-OrientationChange'>    /**
196 </span>     * @property OrientationChange True if the device supports orientation change
197      * @type {Boolean}
198      */
199     OrientationChange: ((typeof window.orientation != 'undefined') &amp;&amp; ('onorientationchange' in window)),
200     
201 <span id='Ext-supports-property-DeviceMotion'>    /**
202 </span>     * @property DeviceMotion True if the device supports device motion (acceleration and rotation rate)
203      * @type {Boolean}
204      */
205     DeviceMotion: ('ondevicemotion' in window),
206     
207 <span id='Ext-supports-property-Touch'>    /**
208 </span>     * @property Touch True if the device supports touch
209      * @type {Boolean}
210      */
211     // is.Desktop is needed due to the bug in Chrome 5.0.375, Safari 3.1.2
212     // and Safari 4.0 (they all have 'ontouchstart' in the window object).
213     Touch: ('ontouchstart' in window) &amp;&amp; (!Ext.is.Desktop),
214
215     tests: [
216 <span id='Ext-supports-property-Transitions'>        /**
217 </span>         * @property Transitions True if the device supports CSS3 Transitions
218          * @type {Boolean}
219          */
220         {
221             identity: 'Transitions',
222             fn: function(doc, div) {
223                 var prefix = [
224                         'webkit',
225                         'Moz',
226                         'o',
227                         'ms',
228                         'khtml'
229                     ],
230                     TE = 'TransitionEnd',
231                     transitionEndName = [
232                         prefix[0] + TE,
233                         'transitionend', //Moz bucks the prefixing convention
234                         prefix[2] + TE,
235                         prefix[3] + TE,
236                         prefix[4] + TE
237                     ],
238                     ln = prefix.length,
239                     i = 0,
240                     out = false;
241                 div = Ext.get(div);
242                 for (; i &lt; ln; i++) {
243                     if (div.getStyle(prefix[i] + &quot;TransitionProperty&quot;)) {
244                         Ext.supports.CSS3Prefix = prefix[i];
245                         Ext.supports.CSS3TransitionEnd = transitionEndName[i];
246                         out = true;
247                         break;
248                     }
249                 }
250                 return out;
251             }
252         },
253         
254 <span id='Ext-supports-property-RightMargin'>        /**
255 </span>         * @property RightMargin True if the device supports right margin.
256          * See https://bugs.webkit.org/show_bug.cgi?id=13343 for why this is needed.
257          * @type {Boolean}
258          */
259         {
260             identity: 'RightMargin',
261             fn: function(doc, div) {
262                 var view = doc.defaultView;
263                 return !(view &amp;&amp; view.getComputedStyle(div.firstChild.firstChild, null).marginRight != '0px');
264             }
265         },
266
267 <span id='Ext-supports-property-DisplayChangeInputSelectionBug'>        /**
268 </span>         * @property DisplayChangeInputSelectionBug True if INPUT elements lose their
269          * selection when their display style is changed. Essentially, if a text input
270          * has focus and its display style is changed, the I-beam disappears.
271          * 
272          * This bug is encountered due to the work around in place for the {@link #RightMargin}
273          * bug. This has been observed in Safari 4.0.4 and older, and appears to be fixed
274          * in Safari 5. It's not clear if Safari 4.1 has the bug, but it has the same WebKit
275          * version number as Safari 5 (according to http://unixpapa.com/js/gecko.html).
276          */
277         {
278             identity: 'DisplayChangeInputSelectionBug',
279             fn: function() {
280                 var webKitVersion = Ext.webKitVersion;
281                 // WebKit but older than Safari 5 or Chrome 6:
282                 return 0 &lt; webKitVersion &amp;&amp; webKitVersion &lt; 533;
283             }
284         },
285
286 <span id='Ext-supports-property-DisplayChangeTextAreaSelectionBug'>        /**
287 </span>         * @property DisplayChangeTextAreaSelectionBug True if TEXTAREA elements lose their
288          * selection when their display style is changed. Essentially, if a text area has
289          * focus and its display style is changed, the I-beam disappears.
290          *
291          * This bug is encountered due to the work around in place for the {@link #RightMargin}
292          * bug. This has been observed in Chrome 10 and Safari 5 and older, and appears to
293          * be fixed in Chrome 11.
294          */
295         {
296             identity: 'DisplayChangeTextAreaSelectionBug',
297             fn: function() {
298                 var webKitVersion = Ext.webKitVersion;
299
300                 /*
301                 Has bug w/textarea:
302
303                 (Chrome) Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-US)
304                             AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.127
305                             Safari/534.16
306                 (Safari) Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-us)
307                             AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5
308                             Safari/533.21.1
309
310                 No bug:
311
312                 (Chrome) Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_7)
313                             AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.57
314                             Safari/534.24
315                 */
316                 return 0 &lt; webKitVersion &amp;&amp; webKitVersion &lt; 534.24;
317             }
318         },
319
320 <span id='Ext-supports-property-TransparentColor'>        /**
321 </span>         * @property TransparentColor True if the device supports transparent color
322          * @type {Boolean}
323          */
324         {
325             identity: 'TransparentColor',
326             fn: function(doc, div, view) {
327                 view = doc.defaultView;
328                 return !(view &amp;&amp; view.getComputedStyle(div.lastChild, null).backgroundColor != 'transparent');
329             }
330         },
331
332 <span id='Ext-supports-property-ComputedStyle'>        /**
333 </span>         * @property ComputedStyle True if the browser supports document.defaultView.getComputedStyle()
334          * @type {Boolean}
335          */
336         {
337             identity: 'ComputedStyle',
338             fn: function(doc, div, view) {
339                 view = doc.defaultView;
340                 return view &amp;&amp; view.getComputedStyle;
341             }
342         },
343         
344 <span id='Ext-supports-property-SVG'>        /**
345 </span>         * @property SVG True if the device supports SVG
346          * @type {Boolean}
347          */
348         {
349             identity: 'Svg',
350             fn: function(doc) {
351                 return !!doc.createElementNS &amp;&amp; !!doc.createElementNS( &quot;http:/&quot; + &quot;/www.w3.org/2000/svg&quot;, &quot;svg&quot;).createSVGRect;
352             }
353         },
354     
355 <span id='Ext-supports-property-Canvas'>        /**
356 </span>         * @property Canvas True if the device supports Canvas
357          * @type {Boolean}
358          */
359         {
360             identity: 'Canvas',
361             fn: function(doc) {
362                 return !!doc.createElement('canvas').getContext;
363             }
364         },
365         
366 <span id='Ext-supports-property-VML'>        /**
367 </span>         * @property VML True if the device supports VML
368          * @type {Boolean}
369          */
370         {
371             identity: 'Vml',
372             fn: function(doc) {
373                 var d = doc.createElement(&quot;div&quot;);
374                 d.innerHTML = &quot;&lt;!--[if vml]&gt;&lt;br&gt;&lt;br&gt;&lt;![endif]--&gt;&quot;;
375                 return (d.childNodes.length == 2);
376             }
377         },
378         
379 <span id='Ext-supports-property-Float'>        /**
380 </span>         * @property Float True if the device supports CSS float
381          * @type {Boolean}
382          */
383         {
384             identity: 'Float',
385             fn: function(doc, div) {
386                 return !!div.lastChild.style.cssFloat;
387             }
388         },
389         
390 <span id='Ext-supports-property-AudioTag'>        /**
391 </span>         * @property AudioTag True if the device supports the HTML5 audio tag
392          * @type {Boolean}
393          */
394         {
395             identity: 'AudioTag',
396             fn: function(doc) {
397                 return !!doc.createElement('audio').canPlayType;
398             }
399         },
400         
401 <span id='Ext-supports-property-History'>        /**
402 </span>         * @property History True if the device supports HTML5 history
403          * @type {Boolean}
404          */
405         {
406             identity: 'History',
407             fn: function() {
408                 return !!(window.history &amp;&amp; history.pushState);
409             }
410         },
411         
412 <span id='Ext-supports-property-CSS3DTransform'>        /**
413 </span>         * @property CSS3DTransform True if the device supports CSS3DTransform
414          * @type {Boolean}
415          */
416         {
417             identity: 'CSS3DTransform',
418             fn: function() {
419                 return (typeof WebKitCSSMatrix != 'undefined' &amp;&amp; new WebKitCSSMatrix().hasOwnProperty('m41'));
420             }
421         },
422
423 <span id='Ext-supports-property-CSS3LinearGradient'>            /**
424 </span>         * @property CSS3LinearGradient True if the device supports CSS3 linear gradients
425          * @type {Boolean}
426          */
427         {
428             identity: 'CSS3LinearGradient',
429             fn: function(doc, div) {
430                 var property = 'background-image:',
431                     webkit   = '-webkit-gradient(linear, left top, right bottom, from(black), to(white))',
432                     w3c      = 'linear-gradient(left top, black, white)',
433                     moz      = '-moz-' + w3c,
434                     options  = [property + webkit, property + w3c, property + moz];
435                 
436                 div.style.cssText = options.join(';');
437                 
438                 return (&quot;&quot; + div.style.backgroundImage).indexOf('gradient') !== -1;
439             }
440         },
441         
442 <span id='Ext-supports-property-CSS3BorderRadius'>        /**
443 </span>         * @property CSS3BorderRadius True if the device supports CSS3 border radius
444          * @type {Boolean}
445          */
446         {
447             identity: 'CSS3BorderRadius',
448             fn: function(doc, div) {
449                 var domPrefixes = ['borderRadius', 'BorderRadius', 'MozBorderRadius', 'WebkitBorderRadius', 'OBorderRadius', 'KhtmlBorderRadius'],
450                     pass = false,
451                     i;
452                 for (i = 0; i &lt; domPrefixes.length; i++) {
453                     if (document.body.style[domPrefixes[i]] !== undefined) {
454                         return true;
455                     }
456                 }
457                 return pass;
458             }
459         },
460         
461 <span id='Ext-supports-property-GeoLocation'>        /**
462 </span>         * @property GeoLocation True if the device supports GeoLocation
463          * @type {Boolean}
464          */
465         {
466             identity: 'GeoLocation',
467             fn: function() {
468                 return (typeof navigator != 'undefined' &amp;&amp; typeof navigator.geolocation != 'undefined') || (typeof google != 'undefined' &amp;&amp; typeof google.gears != 'undefined');
469             }
470         },
471 <span id='Ext-supports-property-MouseEnterLeave'>        /**
472 </span>         * @property MouseEnterLeave True if the browser supports mouseenter and mouseleave events
473          * @type {Boolean}
474          */
475         {
476             identity: 'MouseEnterLeave',
477             fn: function(doc, div){
478                 return ('onmouseenter' in div &amp;&amp; 'onmouseleave' in div);
479             }
480         },
481 <span id='Ext-supports-property-MouseWheel'>        /**
482 </span>         * @property MouseWheel True if the browser supports the mousewheel event
483          * @type {Boolean}
484          */
485         {
486             identity: 'MouseWheel',
487             fn: function(doc, div) {
488                 return ('onmousewheel' in div);
489             }
490         },
491 <span id='Ext-supports-property-Opacity'>        /**
492 </span>         * @property Opacity True if the browser supports normal css opacity
493          * @type {Boolean}
494          */
495         {
496             identity: 'Opacity',
497             fn: function(doc, div){
498                 // Not a strict equal comparison in case opacity can be converted to a number.
499                 if (Ext.isIE6 || Ext.isIE7 || Ext.isIE8) {
500                     return false;
501                 }
502                 div.firstChild.style.cssText = 'opacity:0.73';
503                 return div.firstChild.style.opacity == '0.73';
504             }
505         },
506 <span id='Ext-supports-property-Placeholder'>        /**
507 </span>         * @property Placeholder True if the browser supports the HTML5 placeholder attribute on inputs
508          * @type {Boolean}
509          */
510         {
511             identity: 'Placeholder',
512             fn: function(doc) {
513                 return 'placeholder' in doc.createElement('input');
514             }
515         },
516         
517 <span id='Ext-supports-property-Direct2DBug'>        /**
518 </span>         * @property Direct2DBug True if when asking for an element's dimension via offsetWidth or offsetHeight, 
519          * getBoundingClientRect, etc. the browser returns the subpixel width rounded to the nearest pixel.
520          * @type {Boolean}
521          */
522         {
523             identity: 'Direct2DBug',
524             fn: function() {
525                 return Ext.isString(document.body.style.msTransformOrigin);
526             }
527         },
528 <span id='Ext-supports-property-BoundingClientRect'>        /**
529 </span>         * @property BoundingClientRect True if the browser supports the getBoundingClientRect method on elements
530          * @type {Boolean}
531          */
532         {
533             identity: 'BoundingClientRect',
534             fn: function(doc, div) {
535                 return Ext.isFunction(div.getBoundingClientRect);
536             }
537         },
538         {
539             identity: 'IncludePaddingInWidthCalculation',
540             fn: function(doc, div){
541                 var el = Ext.get(div.childNodes[1].firstChild);
542                 return el.getWidth() == 210;
543             }
544         },
545         {
546             identity: 'IncludePaddingInHeightCalculation',
547             fn: function(doc, div){
548                 var el = Ext.get(div.childNodes[1].firstChild);
549                 return el.getHeight() == 210;
550             }
551         },
552         
553 <span id='Ext-supports-property-ArraySort'>        /**
554 </span>         * @property ArraySort True if the Array sort native method isn't bugged.
555          * @type {Boolean}
556          */
557         {
558             identity: 'ArraySort',
559             fn: function() {
560                 var a = [1,2,3,4,5].sort(function(){ return 0; });
561                 return a[0] === 1 &amp;&amp; a[1] === 2 &amp;&amp; a[2] === 3 &amp;&amp; a[3] === 4 &amp;&amp; a[4] === 5;
562             }
563         },
564 <span id='Ext-supports-property-Range'>        /**
565 </span>         * @property Range True if browser support document.createRange native method.
566          * @type {Boolean}
567          */
568         {
569             identity: 'Range',
570             fn: function() {
571                 return !!document.createRange;
572             }
573         },
574 <span id='Ext-supports-property-CreateContextualFragment'>        /**
575 </span>         * @property CreateContextualFragment True if browser support CreateContextualFragment range native methods.
576          * @type {Boolean}
577          */
578         {
579             identity: 'CreateContextualFragment',
580             fn: function() {
581                 var range = Ext.supports.Range ? document.createRange() : false;
582                 
583                 return range &amp;&amp; !!range.createContextualFragment;
584             }
585         },
586
587 <span id='Ext-supports-property-WindowOnError'>        /**
588 </span>         * @property WindowOnError True if browser supports window.onerror.
589          * @type {Boolean}
590          */
591         {
592             identity: 'WindowOnError',
593             fn: function () {
594                 // sadly, we cannot feature detect this...
595                 return Ext.isIE || Ext.isGecko || Ext.webKitVersion &gt;= 534.16; // Chrome 10+
596             }
597         }
598     ]
599 };
600 </pre>
601 </body>
602 </html>