4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <title>The source code</title>
6 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
7 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
8 <style type="text/css">
9 .highlight { display: block; background-color: #ddd; }
11 <script type="text/javascript">
12 function highlight() {
13 document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
17 <body onload="prettyPrint(); highlight();">
18 <pre class="prettyprint lang-js"><span id='Ext-env-FeatureDetector'>/**
19 </span> * Provides useful information about the current browser features.
20 * Don't instantiate directly, but use the {@link Ext#features} property instead.
22 Ext.define('Ext.env.FeatureDetector', {
26 <span id='Ext-env-FeatureDetector-property-Canvas'> /**
27 </span> * @property {Boolean}
28 * True if canvas element supported.
31 var element = this.getTestElement('canvas');
32 return !!(element && element.getContext && element.getContext('2d'));
34 <span id='Ext-env-FeatureDetector-property-SVG'> /**
35 </span> * @property {Boolean}
36 * True if SVG supported.
39 var doc = Ext.global.document;
41 return !!(doc.createElementNS && !!doc.createElementNS("http:/" + "/www.w3.org/2000/svg", "svg").createSVGRect);
43 <span id='Ext-env-FeatureDetector-property-VML'> /**
44 </span> * @property {Boolean}
45 * True if VML supported.
48 var element = this.getTestElement(),
51 element.innerHTML = "<!--[if vml]><br><br><![endif]-->";
52 ret = (element.childNodes.length === 2);
53 element.innerHTML = "";
57 <span id='Ext-env-FeatureDetector-property-Touch'> /**
58 </span> * @property {Boolean}
59 * True if we're in Sencha Touch environment.
62 return ('ontouchstart' in Ext.global) && !(Ext.platform && Ext.platform.name.match(/Windows|MacOSX|Linux/));
64 <span id='Ext-env-FeatureDetector-property-Orientation'> /**
65 </span> * @property {Boolean}
66 * True if orientation API supported.
68 Orientation: function() {
69 return ('orientation' in Ext.global);
71 <span id='Ext-env-FeatureDetector-property-Geolocation'> /**
72 </span> * @property {Boolean}
73 * True if geolocation API supported.
75 Geolocation: function() {
76 return !!Ext.global.navigator.geolocation;
78 <span id='Ext-env-FeatureDetector-property-SqlDatabase'> /**
79 </span> * @property {Boolean}
80 * True if openDatabase API supported.
82 SqlDatabase: function() {
83 return !!Ext.global.openDatabase;
85 <span id='Ext-env-FeatureDetector-property-Websockets'> /**
86 </span> * @property {Boolean}
87 * True if WebSocket API supported.
89 Websockets: function() {
90 return 'WebSocket' in Ext.global;
92 <span id='Ext-env-FeatureDetector-property-History'> /**
93 </span> * @property {Boolean}
94 * True if history.pushState supported.
97 return !!(Ext.global.history && Ext.global.history.pushState);
99 <span id='Ext-env-FeatureDetector-property-CSSTransforms'> /**
100 </span> * @property {Boolean}
101 * True if CSS transforms supported.
103 CSSTransforms: function() {
104 return this.isStyleSupported('transform');
106 <span id='Ext-env-FeatureDetector-property-CSS3DTransforms'> /**
107 </span> * @property {Boolean}
108 * True if CSS 3D transforms supported.
110 CSS3DTransforms: function() {
111 return this.has('csstransforms') && this.isStyleSupported('perspective');
113 <span id='Ext-env-FeatureDetector-property-CSSAnimations'> /**
114 </span> * @property {Boolean}
115 * True if CSS animations supported.
117 CSSAnimations: function() {
118 return this.isStyleSupported('animationName');
120 <span id='Ext-env-FeatureDetector-property-CSSTransitions'> /**
121 </span> * @property {Boolean}
122 * True if CSS transitions supported.
124 CSSTransitions: function() {
125 return this.isStyleSupported('transitionProperty');
127 <span id='Ext-env-FeatureDetector-property-Audio'> /**
128 </span> * @property {Boolean}
129 * True if audio element supported.
132 return !!this.getTestElement('audio').canPlayType;
134 <span id='Ext-env-FeatureDetector-property-Video'> /**
135 </span> * @property {Boolean}
136 * True if video element supported.
139 return !!this.getTestElement('video').canPlayType;
143 stylePrefixes: ['Webkit', 'Moz', 'O', 'ms']
146 constructor: function() {
149 this.testElements = {};
151 this.registerTests(this.self.defaultTests, true);
156 has: function(name) {
157 if (!this.hasTest(name)) {
160 else if (this.has.hasOwnProperty(name)) {
161 return this.has[name];
164 return this.getTestResult(name);
168 getTestResult: function(name) {
169 return !!this.getTest(name).call(this);
172 getTestElement: function(tag) {
177 if (!this.testElements[tag]) {
178 this.testElements[tag] = Ext.global.document.createElement(tag);
181 return this.testElements[tag];
184 registerTest: function(name, fn, isDefault) {
186 if (this.hasTest(name)) {
188 sourceClass: "Ext.env.FeatureDetector",
189 sourceMethod: "registerTest",
190 msg: "Test name " + name + " has already been registered"
195 this.tests[name] = fn;
198 this.has[name] = this.getTestResult(name);
204 registerTests: function(tests, isDefault) {
205 Ext.Object.each(tests, function(name, fn) {
206 this.registerTest(name, fn, isDefault);
212 hasTest: function(name) {
213 return this.tests.hasOwnProperty(name);
216 getTest: function(name) {
218 if (!this.hasTest(name)) {
220 sourceClass: "Ext.env.FeatureDetector",
221 sourceMethod: "getTest",
222 msg: "Test name " + name + " does not exist"
227 return this.tests[name];
230 getTests: function() {
234 isStyleSupported: function(name, tag) {
235 var elementStyle = this.getTestElement(tag).style,
236 cName = Ext.String.capitalize(name),
237 i = this.self.stylePrefixes.length;
239 if (elementStyle[name] !== undefined) {
244 if (elementStyle[this.self.stylePrefixes[i] + cName] !== undefined) {
252 isEventSupported: function(name, tag) {
253 var element = this.getTestElement(tag),
254 eventName = 'on' + name,
257 // When using `setAttribute`, IE skips "unload", WebKit skips
258 // "unload" and "resize", whereas `in` "catches" those
259 isSupported = (eventName in element);
262 if (element.setAttribute && element.removeAttribute) {
263 element.setAttribute(eventName, '');
264 isSupported = typeof element[eventName] === 'function';
266 // If property was created, "remove it" (by setting value to `undefined`)
267 if (typeof element[eventName] !== 'undefined') {
268 element[eventName] = undefined;
271 element.removeAttribute(eventName);
280 <span id='Ext-property-features'> /**
281 </span> * @property {Ext.env.FeatureDetector} features
283 * Global convenient instance of {@link Ext.env.FeatureDetector}.
285 Ext.features = new Ext.env.FeatureDetector();