Upgrade to ExtJS 4.0.1 - Released 05/18/2011
[extjs.git] / docs / source / FeatureDetector.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-env-FeatureDetector'>/**
19 </span> * @class Ext.env.FeatureDetector
20  */
21 Ext.define('Ext.env.FeatureDetector', {
22
23     statics: {
24         defaultTests: {
25             Canvas: function() {
26                 var element = this.getTestElement('canvas');
27                 return !!(element &amp;&amp; element.getContext &amp;&amp; element.getContext('2d'));
28             },
29             SVG: function() {
30                 var doc = Ext.global.document;
31
32                 return !!(doc.createElementNS &amp;&amp; !!doc.createElementNS(&quot;http:/&quot; + &quot;/www.w3.org/2000/svg&quot;, &quot;svg&quot;).createSVGRect);
33             },
34             VML: function() {
35                 var element = this.getTestElement(),
36                     ret = false;
37
38                 element.innerHTML = &quot;&lt;!--[if vml]&gt;&lt;br&gt;&lt;br&gt;&lt;![endif]--&gt;&quot;;
39                 ret = (element.childNodes.length === 2);
40                 element.innerHTML = &quot;&quot;;
41
42                 return ret;
43             },
44             Touch: function() {
45                 return ('ontouchstart' in Ext.global) &amp;&amp; !(Ext.platform &amp;&amp; Ext.platform.name.match(/Windows|MacOSX|Linux/));
46             },
47             Orientation: function() {
48                 return ('orientation' in Ext.global);
49             },
50             Geolocation: function() {
51                 return !!Ext.global.navigator.geolocation;
52             },
53             SqlDatabase: function() {
54                 return !!Ext.global.openDatabase;
55             },
56             Websockets: function() {
57                 return 'WebSocket' in Ext.global;
58             },
59             History: function() {
60                 return !!(Ext.global.history &amp;&amp; Ext.global.history.pushState);
61             },
62             CSSTransforms: function() {
63                 return this.isStyleSupported('transform');
64             },
65             CSS3DTransforms: function() {
66                 return this.has('csstransforms') &amp;&amp; this.isStyleSupported('perspective');
67             },
68             CSSAnimations: function() {
69                 return this.isStyleSupported('animationName');
70             },
71             CSSTransitions: function() {
72                 return this.isStyleSupported('transitionProperty');
73             },
74             Audio: function() {
75                 return !!this.getTestElement('audio').canPlayType;
76             },
77             Video: function() {
78                 return !!this.getTestElement('video').canPlayType;
79             }
80         },
81
82         stylePrefixes: ['Webkit', 'Moz', 'O', 'ms']
83     },
84
85     constructor: function() {
86         this.tests = {};
87
88         this.testElements = {};
89
90         this.registerTests(this.self.defaultTests, true);
91
92         return this;
93     },
94
95     has: function(name) {
96         if (!this.hasTest(name)) {
97             return false;
98         }
99         else if (this.has.hasOwnProperty(name)) {
100             return this.has[name];
101         }
102         else {
103             return this.getTestResult(name);
104         }
105     },
106
107     getTestResult: function(name) {
108         return !!this.getTest(name).call(this);
109     },
110
111     getTestElement: function(tag) {
112         if (!tag) {
113             tag = 'div';
114         }
115
116         if (!this.testElements[tag]) {
117             this.testElements[tag] = Ext.global.document.createElement(tag);
118         }
119
120         return this.testElements[tag];
121     },
122
123     registerTest: function(name, fn, isDefault) {
124         //&lt;debug&gt;
125         if (this.hasTest(name)) {
126             Ext.Error.raise({
127                 sourceClass: &quot;Ext.env.FeatureDetector&quot;,
128                 sourceMethod: &quot;registerTest&quot;,
129                 msg: &quot;Test name &quot; + name + &quot; has already been registered&quot;
130             });
131         }
132         //&lt;debug&gt;
133
134         this.tests[name] = fn;
135
136         if (isDefault) {
137             this.has[name] = this.getTestResult(name);
138         }
139
140         return this;
141     },
142
143     registerTests: function(tests, isDefault) {
144         Ext.Object.each(tests, function(name, fn) {
145             this.registerTest(name, fn, isDefault);
146         }, this);
147
148         return this;
149     },
150
151     hasTest: function(name) {
152         return this.tests.hasOwnProperty(name);
153     },
154
155     getTest: function(name) {
156         //&lt;debug&gt;
157         if (!this.hasTest(name)) {
158             Ext.Error.raise({
159                 sourceClass: &quot;Ext.env.FeatureDetector&quot;,
160                 sourceMethod: &quot;getTest&quot;,
161                 msg: &quot;Test name &quot; + name + &quot; does not exist&quot;
162             });
163         }
164         //&lt;debug&gt;
165
166         return this.tests[name];
167     },
168
169     getTests: function() {
170         return this.tests;
171     },
172
173     isStyleSupported: function(name, tag) {
174         var elementStyle = this.getTestElement(tag).style,
175             cName = Ext.String.capitalize(name),
176             i = this.self.stylePrefixes.length;
177
178         if (elementStyle[name] !== undefined) {
179             return true;
180         }
181
182         while (i--) {
183             if (elementStyle[this.self.stylePrefixes[i] + cName] !== undefined) {
184                 return true;
185             }
186         }
187
188         return false;
189     },
190
191     isEventSupported: function(name, tag) {
192         var element = this.getTestElement(tag),
193             eventName = 'on' + name,
194             isSupported = false;
195
196         // When using `setAttribute`, IE skips &quot;unload&quot;, WebKit skips
197         // &quot;unload&quot; and &quot;resize&quot;, whereas `in` &quot;catches&quot; those
198         isSupported = (eventName in element);
199
200         if (!isSupported) {
201             if (element.setAttribute &amp;&amp; element.removeAttribute) {
202                 element.setAttribute(eventName, '');
203                 isSupported = typeof element[eventName] === 'function';
204
205                 // If property was created, &quot;remove it&quot; (by setting value to `undefined`)
206                 if (typeof element[eventName] !== 'undefined') {
207                     element[eventName] = undefined;
208                 }
209
210                 element.removeAttribute(eventName);
211             }
212         }
213
214         return isSupported;
215     }
216
217 }, function() {
218
219 /*
220  * Global convenient instance of {@link Ext.env.FeatureDetector Ext.env.FeatureDetector}
221  * @member Ext features
222  */
223 Ext.features = new Ext.env.FeatureDetector();
224
225 });
226 </pre>
227 </body>
228 </html>