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