3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
18 * Determines information about the current platform the application is running on.
23 init : function(navigator) {
24 var platforms = this.platforms,
25 ln = platforms.length,
28 navigator = navigator || window.navigator;
30 for (i = 0; i < ln; i++) {
31 platform = platforms[i];
32 this[platform.identity] = platform.regex.test(navigator[platform.property]);
36 * @property Desktop True if the browser is running on a desktop machine
39 this.Desktop = this.Mac || this.Windows || (this.Linux && !this.Android);
41 * @property Tablet True if the browser is running on a tablet (iPad)
43 this.Tablet = this.iPad;
45 * @property Phone True if the browser is running on a phone.
48 this.Phone = !this.Desktop && !this.Tablet;
50 * @property iOS True if the browser is running on iOS
53 this.iOS = this.iPhone || this.iPad || this.iPod;
56 * @property Standalone Detects when application has been saved to homescreen.
59 this.Standalone = !!window.navigator.standalone;
63 * @property iPhone True when the browser is running on a iPhone
73 * @property iPod True when the browser is running on a iPod
83 * @property iPad True when the browser is running on a iPad
87 property: 'userAgent',
93 * @property Blackberry True when the browser is running on a Blackberry
97 property: 'userAgent',
99 identity: 'Blackberry'
103 * @property Android True when the browser is running on an Android device
107 property: 'userAgent',
113 * @property Mac True when the browser is running on a Mac
117 property: 'platform',
123 * @property Windows True when the browser is running on Windows
127 property: 'platform',
133 * @property Linux True when the browser is running on Linux
137 property: 'platform',
146 * @class Ext.supports
148 * Determines information about features are supported in the current environment
155 div = doc.createElement('div'),
161 '<div style="height:30px;width:50px;">',
162 '<div style="height:20px;width:20px;"></div>',
164 '<div style="width: 200px; height: 200px; position: relative; padding: 5px;">',
165 '<div style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></div>',
167 '<div style="float:left; background-color:transparent;"></div>'
170 doc.body.appendChild(div);
172 for (i = 0; i < ln; i++) {
174 this[test.identity] = test.fn.call(this, doc, div);
177 doc.body.removeChild(div);
181 * @property CSS3BoxShadow True if document environment supports the CSS3 box-shadow style.
184 CSS3BoxShadow: Ext.isDefined(document.documentElement.style.boxShadow),
187 * @property ClassList True if document environment supports the HTML5 classList API.
190 ClassList: !!document.documentElement.classList,
193 * @property OrientationChange True if the device supports orientation change
196 OrientationChange: ((typeof window.orientation != 'undefined') && ('onorientationchange' in window)),
199 * @property DeviceMotion True if the device supports device motion (acceleration and rotation rate)
202 DeviceMotion: ('ondevicemotion' in window),
205 * @property Touch True if the device supports touch
208 // is.Desktop is needed due to the bug in Chrome 5.0.375, Safari 3.1.2
209 // and Safari 4.0 (they all have 'ontouchstart' in the window object).
210 Touch: ('ontouchstart' in window) && (!Ext.is.Desktop),
214 * @property Transitions True if the device supports CSS3 Transitions
218 identity: 'Transitions',
219 fn: function(doc, div) {
227 TE = 'TransitionEnd',
228 transitionEndName = [
230 'transitionend', //Moz bucks the prefixing convention
239 for (; i < ln; i++) {
240 if (div.getStyle(prefix[i] + "TransitionProperty")) {
241 Ext.supports.CSS3Prefix = prefix[i];
242 Ext.supports.CSS3TransitionEnd = transitionEndName[i];
252 * @property RightMargin True if the device supports right margin.
253 * See https://bugs.webkit.org/show_bug.cgi?id=13343 for why this is needed.
257 identity: 'RightMargin',
258 fn: function(doc, div) {
259 var view = doc.defaultView;
260 return !(view && view.getComputedStyle(div.firstChild.firstChild, null).marginRight != '0px');
265 * @property DisplayChangeInputSelectionBug True if INPUT elements lose their
266 * selection when their display style is changed. Essentially, if a text input
267 * has focus and its display style is changed, the I-beam disappears.
269 * This bug is encountered due to the work around in place for the {@link #RightMargin}
270 * bug. This has been observed in Safari 4.0.4 and older, and appears to be fixed
271 * in Safari 5. It's not clear if Safari 4.1 has the bug, but it has the same WebKit
272 * version number as Safari 5 (according to http://unixpapa.com/js/gecko.html).
275 identity: 'DisplayChangeInputSelectionBug',
277 var webKitVersion = Ext.webKitVersion;
278 // WebKit but older than Safari 5 or Chrome 6:
279 return 0 < webKitVersion && webKitVersion < 533;
284 * @property DisplayChangeTextAreaSelectionBug True if TEXTAREA elements lose their
285 * selection when their display style is changed. Essentially, if a text area has
286 * focus and its display style is changed, the I-beam disappears.
288 * This bug is encountered due to the work around in place for the {@link #RightMargin}
289 * bug. This has been observed in Chrome 10 and Safari 5 and older, and appears to
290 * be fixed in Chrome 11.
293 identity: 'DisplayChangeTextAreaSelectionBug',
295 var webKitVersion = Ext.webKitVersion;
300 (Chrome) Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-US)
301 AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.127
303 (Safari) Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-us)
304 AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5
309 (Chrome) Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_7)
310 AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.57
313 return 0 < webKitVersion && webKitVersion < 534.24;
318 * @property TransparentColor True if the device supports transparent color
322 identity: 'TransparentColor',
323 fn: function(doc, div, view) {
324 view = doc.defaultView;
325 return !(view && view.getComputedStyle(div.lastChild, null).backgroundColor != 'transparent');
330 * @property ComputedStyle True if the browser supports document.defaultView.getComputedStyle()
334 identity: 'ComputedStyle',
335 fn: function(doc, div, view) {
336 view = doc.defaultView;
337 return view && view.getComputedStyle;
342 * @property SVG True if the device supports SVG
348 return !!doc.createElementNS && !!doc.createElementNS( "http:/" + "/www.w3.org/2000/svg", "svg").createSVGRect;
353 * @property Canvas True if the device supports Canvas
359 return !!doc.createElement('canvas').getContext;
364 * @property VML True if the device supports VML
370 var d = doc.createElement("div");
371 d.innerHTML = "<!--[if vml]><br><br><![endif]-->";
372 return (d.childNodes.length == 2);
377 * @property Float True if the device supports CSS float
382 fn: function(doc, div) {
383 return !!div.lastChild.style.cssFloat;
388 * @property AudioTag True if the device supports the HTML5 audio tag
392 identity: 'AudioTag',
394 return !!doc.createElement('audio').canPlayType;
399 * @property History True if the device supports HTML5 history
405 return !!(window.history && history.pushState);
410 * @property CSS3DTransform True if the device supports CSS3DTransform
414 identity: 'CSS3DTransform',
416 return (typeof WebKitCSSMatrix != 'undefined' && new WebKitCSSMatrix().hasOwnProperty('m41'));
421 * @property CSS3LinearGradient True if the device supports CSS3 linear gradients
425 identity: 'CSS3LinearGradient',
426 fn: function(doc, div) {
427 var property = 'background-image:',
428 webkit = '-webkit-gradient(linear, left top, right bottom, from(black), to(white))',
429 w3c = 'linear-gradient(left top, black, white)',
431 options = [property + webkit, property + w3c, property + moz];
433 div.style.cssText = options.join(';');
435 return ("" + div.style.backgroundImage).indexOf('gradient') !== -1;
440 * @property CSS3BorderRadius True if the device supports CSS3 border radius
444 identity: 'CSS3BorderRadius',
445 fn: function(doc, div) {
446 var domPrefixes = ['borderRadius', 'BorderRadius', 'MozBorderRadius', 'WebkitBorderRadius', 'OBorderRadius', 'KhtmlBorderRadius'],
449 for (i = 0; i < domPrefixes.length; i++) {
450 if (document.body.style[domPrefixes[i]] !== undefined) {
459 * @property GeoLocation True if the device supports GeoLocation
463 identity: 'GeoLocation',
465 return (typeof navigator != 'undefined' && typeof navigator.geolocation != 'undefined') || (typeof google != 'undefined' && typeof google.gears != 'undefined');
469 * @property MouseEnterLeave True if the browser supports mouseenter and mouseleave events
473 identity: 'MouseEnterLeave',
474 fn: function(doc, div){
475 return ('onmouseenter' in div && 'onmouseleave' in div);
479 * @property MouseWheel True if the browser supports the mousewheel event
483 identity: 'MouseWheel',
484 fn: function(doc, div) {
485 return ('onmousewheel' in div);
489 * @property Opacity True if the browser supports normal css opacity
494 fn: function(doc, div){
495 // Not a strict equal comparison in case opacity can be converted to a number.
496 if (Ext.isIE6 || Ext.isIE7 || Ext.isIE8) {
499 div.firstChild.style.cssText = 'opacity:0.73';
500 return div.firstChild.style.opacity == '0.73';
504 * @property Placeholder True if the browser supports the HTML5 placeholder attribute on inputs
508 identity: 'Placeholder',
510 return 'placeholder' in doc.createElement('input');
515 * @property Direct2DBug True if when asking for an element's dimension via offsetWidth or offsetHeight,
516 * getBoundingClientRect, etc. the browser returns the subpixel width rounded to the nearest pixel.
520 identity: 'Direct2DBug',
522 return Ext.isString(document.body.style.msTransformOrigin);
526 * @property BoundingClientRect True if the browser supports the getBoundingClientRect method on elements
530 identity: 'BoundingClientRect',
531 fn: function(doc, div) {
532 return Ext.isFunction(div.getBoundingClientRect);
536 identity: 'IncludePaddingInWidthCalculation',
537 fn: function(doc, div){
538 var el = Ext.get(div.childNodes[1].firstChild);
539 return el.getWidth() == 210;
543 identity: 'IncludePaddingInHeightCalculation',
544 fn: function(doc, div){
545 var el = Ext.get(div.childNodes[1].firstChild);
546 return el.getHeight() == 210;
551 * @property ArraySort True if the Array sort native method isn't bugged.
555 identity: 'ArraySort',
557 var a = [1,2,3,4,5].sort(function(){ return 0; });
558 return a[0] === 1 && a[1] === 2 && a[2] === 3 && a[3] === 4 && a[4] === 5;
562 * @property Range True if browser support document.createRange native method.
568 return !!document.createRange;
572 * @property CreateContextualFragment True if browser support CreateContextualFragment range native methods.
576 identity: 'CreateContextualFragment',
578 var range = Ext.supports.Range ? document.createRange() : false;
580 return range && !!range.createContextualFragment;
585 * @property WindowOnError True if browser supports window.onerror.
589 identity: 'WindowOnError',
591 // sadly, we cannot feature detect this...
592 return Ext.isIE || Ext.isGecko || Ext.webKitVersion >= 534.16; // Chrome 10+