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