/*
|
This file is part of Ext JS 4.2
|
|
Copyright (c) 2011-2013 Sencha Inc
|
|
Contact: http://www.sencha.com/contact
|
|
GNU General Public License Usage
|
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.
|
|
If you are unsure which license is appropriate for your use, please contact the sales department
|
at http://www.sencha.com/contact.
|
|
Build date: 2013-05-16 14:36:50 (f9be68accb407158ba2b1be2c226a6ce1f649314)
|
*/
|
// @tag extras,core
|
// @require perf/Monitor.js
|
// @define Ext.Supports
|
|
/**
|
* @class Ext.is
|
*
|
* Determines information about the current platform the application is running on.
|
*
|
* @singleton
|
*/
|
Ext.is = {
|
init : function(navigator) {
|
var platforms = this.platforms,
|
ln = platforms.length,
|
i, platform;
|
|
navigator = navigator || window.navigator;
|
|
for (i = 0; i < ln; i++) {
|
platform = platforms[i];
|
this[platform.identity] = platform.regex.test(navigator[platform.property]);
|
}
|
|
/**
|
* @property Desktop True if the browser is running on a desktop machine
|
* @type {Boolean}
|
*/
|
this.Desktop = this.Mac || this.Windows || (this.Linux && !this.Android);
|
/**
|
* @property Tablet True if the browser is running on a tablet (iPad)
|
*/
|
this.Tablet = this.iPad;
|
/**
|
* @property Phone True if the browser is running on a phone.
|
* @type {Boolean}
|
*/
|
this.Phone = !this.Desktop && !this.Tablet;
|
/**
|
* @property iOS True if the browser is running on iOS
|
* @type {Boolean}
|
*/
|
this.iOS = this.iPhone || this.iPad || this.iPod;
|
|
/**
|
* @property Standalone Detects when application has been saved to homescreen.
|
* @type {Boolean}
|
*/
|
this.Standalone = !!window.navigator.standalone;
|
},
|
|
/**
|
* @property iPhone True when the browser is running on a iPhone
|
* @type {Boolean}
|
*/
|
platforms: [{
|
property: 'platform',
|
regex: /iPhone/i,
|
identity: 'iPhone'
|
},
|
|
/**
|
* @property iPod True when the browser is running on a iPod
|
* @type {Boolean}
|
*/
|
{
|
property: 'platform',
|
regex: /iPod/i,
|
identity: 'iPod'
|
},
|
|
/**
|
* @property iPad True when the browser is running on a iPad
|
* @type {Boolean}
|
*/
|
{
|
property: 'userAgent',
|
regex: /iPad/i,
|
identity: 'iPad'
|
},
|
|
/**
|
* @property Blackberry True when the browser is running on a Blackberry
|
* @type {Boolean}
|
*/
|
{
|
property: 'userAgent',
|
regex: /Blackberry/i,
|
identity: 'Blackberry'
|
},
|
|
/**
|
* @property Android True when the browser is running on an Android device
|
* @type {Boolean}
|
*/
|
{
|
property: 'userAgent',
|
regex: /Android/i,
|
identity: 'Android'
|
},
|
|
/**
|
* @property Mac True when the browser is running on a Mac
|
* @type {Boolean}
|
*/
|
{
|
property: 'platform',
|
regex: /Mac/i,
|
identity: 'Mac'
|
},
|
|
/**
|
* @property Windows True when the browser is running on Windows
|
* @type {Boolean}
|
*/
|
{
|
property: 'platform',
|
regex: /Win/i,
|
identity: 'Windows'
|
},
|
|
/**
|
* @property Linux True when the browser is running on Linux
|
* @type {Boolean}
|
*/
|
{
|
property: 'platform',
|
regex: /Linux/i,
|
identity: 'Linux'
|
}]
|
};
|
|
Ext.is.init();
|
|
/**
|
* @class Ext.supports
|
*
|
* Determines information about features are supported in the current environment
|
*
|
* @singleton
|
*/
|
(function(){
|
|
// this is a local copy of certain logic from (Abstract)Element.getStyle
|
// to break a dependancy between the supports mechanism and Element
|
// use this instead of element references to check for styling info
|
var getStyle = function(element, styleName){
|
var view = element.ownerDocument.defaultView,
|
style = (view ? view.getComputedStyle(element, null) : element.currentStyle) || element.style;
|
return style[styleName];
|
},
|
supportsVectors = {
|
'IE6-quirks': [0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0],
|
'IE6-strict': [0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,1,0,1,1,0,0,1,0,1,0,0,0],
|
'IE7-quirks': [0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0],
|
'IE7-strict': [0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,1,0,0,1,0,1,0,0,0],
|
'IE8-quirks': [0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0],
|
'IE8-strict': [0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,1,0,0,1,0,1,0,0,1],
|
'IE9-quirks': [0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,1,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0],
|
'IE9-strict': [0,1,0,0,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,0,0,0,0,1],
|
'IE10-quirks': [1,1,0,0,1,1,1,1,0,1,1,1,0,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,0,0,0,0,1],
|
'IE10-strict': [1,1,0,0,1,1,1,1,0,1,1,1,0,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,0,0,0,0,1]
|
};
|
|
function getBrowserKey() {
|
var browser = Ext.isIE6 ? 'IE6' : Ext.isIE7 ? 'IE7' : Ext.isIE8 ? 'IE8' :
|
Ext.isIE9 ? 'IE9': Ext.isIE10 ? 'IE10' : '';
|
|
return browser ? browser + (Ext.isStrict ? '-strict' : '-quirks') : '';
|
}
|
|
Ext.supports = {
|
/**
|
* Runs feature detection routines and sets the various flags. This is called when
|
* the scripts loads (very early) and again at {@link Ext#onReady}. Some detections
|
* are flagged as `early` and run immediately. Others that require the document body
|
* will not run until ready.
|
*
|
* Each test is run only once, so calling this method from an onReady function is safe
|
* and ensures that all flags have been set.
|
* @markdown
|
* @private
|
*/
|
init : function() {
|
var me = this,
|
doc = document,
|
toRun = me.toRun || me.tests,
|
n = toRun.length,
|
div = n && Ext.isReady && doc.createElement('div'),
|
notRun = [],
|
browserKey = getBrowserKey(),
|
test, vector, value;
|
|
if (div) {
|
div.innerHTML = [
|
'<div style="height:30px;width:50px;">',
|
'<div style="height:20px;width:20px;"></div>',
|
'</div>',
|
'<div style="width: 200px; height: 200px; position: relative; padding: 5px;">',
|
'<div style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></div>',
|
'</div>',
|
'<div style="position: absolute; left: 10%; top: 10%;"></div>',
|
'<div style="float:left; background-color:transparent;"></div>'
|
].join('');
|
|
doc.body.appendChild(div);
|
}
|
|
vector = supportsVectors[browserKey];
|
while (n--) {
|
test = toRun[n];
|
value = vector && vector[n];
|
if (value !== undefined) {
|
me[test.identity] = value;
|
} else if (div || test.early) {
|
me[test.identity] = test.fn.call(me, doc, div);
|
} else {
|
notRun.push(test);
|
}
|
}
|
|
if (div) {
|
doc.body.removeChild(div);
|
}
|
|
me.toRun = notRun;
|
},
|
|
//<debug>
|
/**
|
* Generates a support vector for the current browser/mode. The result can be
|
* added to supportsVectors to eliminate feature detection at startup time.
|
* @private
|
*/
|
generateVector: function() {
|
var tests = this.tests,
|
vector = [],
|
i = 0,
|
ln = tests.length,
|
test;
|
|
for (; i < ln; i++) {
|
test = tests[i];
|
vector.push(this[test.identity] ? 1 : 0);
|
}
|
return vector;
|
},
|
//</debug>
|
|
/**
|
* @property PointerEvents True if document environment supports the CSS3 pointer-events style.
|
* @type {Boolean}
|
*/
|
PointerEvents: 'pointerEvents' in document.documentElement.style,
|
|
// IE10/Win8 throws "Access Denied" accessing window.localStorage, so this test
|
// needs to have a try/catch
|
/**
|
* @property LocalStorage True if localStorage is supported
|
*/
|
LocalStorage: (function() {
|
try {
|
return 'localStorage' in window && window['localStorage'] !== null;
|
} catch (e) {
|
return false;
|
}
|
})(),
|
|
/**
|
* @property CSS3BoxShadow True if document environment supports the CSS3 box-shadow style.
|
* @type {Boolean}
|
*/
|
CSS3BoxShadow: 'boxShadow' in document.documentElement.style || 'WebkitBoxShadow' in document.documentElement.style || 'MozBoxShadow' in document.documentElement.style,
|
|
/**
|
* @property ClassList True if document environment supports the HTML5 classList API.
|
* @type {Boolean}
|
*/
|
ClassList: !!document.documentElement.classList,
|
|
/**
|
* @property OrientationChange True if the device supports orientation change
|
* @type {Boolean}
|
*/
|
OrientationChange: ((typeof window.orientation != 'undefined') && ('onorientationchange' in window)),
|
|
/**
|
* @property DeviceMotion True if the device supports device motion (acceleration and rotation rate)
|
* @type {Boolean}
|
*/
|
DeviceMotion: ('ondevicemotion' in window),
|
|
/**
|
* @property Touch True if the device supports touch
|
* @type {Boolean}
|
*/
|
// is.Desktop is needed due to the bug in Chrome 5.0.375, Safari 3.1.2
|
// and Safari 4.0 (they all have 'ontouchstart' in the window object).
|
Touch: ('ontouchstart' in window) && (!Ext.is.Desktop),
|
|
/**
|
* @property TimeoutActualLateness True if the browser passes the "actualLateness" parameter to
|
* setTimeout. See: https://developer.mozilla.org/en/DOM/window.setTimeout
|
* @type {Boolean}
|
*/
|
TimeoutActualLateness: (function(){
|
setTimeout(function(){
|
Ext.supports.TimeoutActualLateness = arguments.length !== 0;
|
}, 0);
|
}()),
|
|
tests: [
|
/**
|
* @property Transitions True if the device supports CSS3 Transitions
|
* @type {Boolean}
|
*/
|
{
|
identity: 'Transitions',
|
fn: function(doc, div) {
|
var prefix = [
|
'webkit',
|
'Moz',
|
'o',
|
'ms',
|
'khtml'
|
],
|
TE = 'TransitionEnd',
|
transitionEndName = [
|
prefix[0] + TE,
|
'transitionend', //Moz bucks the prefixing convention
|
prefix[2] + TE,
|
prefix[3] + TE,
|
prefix[4] + TE
|
],
|
ln = prefix.length,
|
i = 0,
|
out = false;
|
|
for (; i < ln; i++) {
|
if (getStyle(div, prefix[i] + "TransitionProperty")) {
|
Ext.supports.CSS3Prefix = prefix[i];
|
Ext.supports.CSS3TransitionEnd = transitionEndName[i];
|
out = true;
|
break;
|
}
|
}
|
return out;
|
}
|
},
|
|
/**
|
* @property RightMargin True if the device supports right margin.
|
* See https://bugs.webkit.org/show_bug.cgi?id=13343 for why this is needed.
|
* @type {Boolean}
|
*/
|
{
|
identity: 'RightMargin',
|
fn: function(doc, div) {
|
var view = doc.defaultView;
|
return !(view && view.getComputedStyle(div.firstChild.firstChild, null).marginRight != '0px');
|
}
|
},
|
|
/**
|
* @property DisplayChangeInputSelectionBug True if INPUT elements lose their
|
* selection when their display style is changed. Essentially, if a text input
|
* has focus and its display style is changed, the I-beam disappears.
|
*
|
* This bug is encountered due to the work around in place for the {@link #RightMargin}
|
* bug. This has been observed in Safari 4.0.4 and older, and appears to be fixed
|
* in Safari 5. It's not clear if Safari 4.1 has the bug, but it has the same WebKit
|
* version number as Safari 5 (according to http://unixpapa.com/js/gecko.html).
|
*/
|
{
|
identity: 'DisplayChangeInputSelectionBug',
|
early: true,
|
fn: function() {
|
var webKitVersion = Ext.webKitVersion;
|
// WebKit but older than Safari 5 or Chrome 6:
|
return 0 < webKitVersion && webKitVersion < 533;
|
}
|
},
|
|
/**
|
* @property DisplayChangeTextAreaSelectionBug True if TEXTAREA elements lose their
|
* selection when their display style is changed. Essentially, if a text area has
|
* focus and its display style is changed, the I-beam disappears.
|
*
|
* This bug is encountered due to the work around in place for the {@link #RightMargin}
|
* bug. This has been observed in Chrome 10 and Safari 5 and older, and appears to
|
* be fixed in Chrome 11.
|
*/
|
{
|
identity: 'DisplayChangeTextAreaSelectionBug',
|
early: true,
|
fn: function() {
|
var webKitVersion = Ext.webKitVersion;
|
|
/*
|
Has bug w/textarea:
|
|
(Chrome) Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-US)
|
AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.127
|
Safari/534.16
|
(Safari) Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-us)
|
AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5
|
Safari/533.21.1
|
|
No bug:
|
|
(Chrome) Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_7)
|
AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.57
|
Safari/534.24
|
*/
|
return 0 < webKitVersion && webKitVersion < 534.24;
|
}
|
},
|
|
/**
|
* @property TransparentColor True if the device supports transparent color
|
* @type {Boolean}
|
*/
|
{
|
identity: 'TransparentColor',
|
fn: function(doc, div, view) {
|
view = doc.defaultView;
|
return !(view && view.getComputedStyle(div.lastChild, null).backgroundColor != 'transparent');
|
}
|
},
|
|
/**
|
* @property ComputedStyle True if the browser supports document.defaultView.getComputedStyle()
|
* @type {Boolean}
|
*/
|
{
|
identity: 'ComputedStyle',
|
fn: function(doc, div, view) {
|
view = doc.defaultView;
|
return view && view.getComputedStyle;
|
}
|
},
|
|
/**
|
* @property Svg True if the device supports SVG
|
* @type {Boolean}
|
*/
|
{
|
identity: 'Svg',
|
fn: function(doc) {
|
return !!doc.createElementNS && !!doc.createElementNS( "http:/" + "/www.w3.org/2000/svg", "svg").createSVGRect;
|
}
|
},
|
|
/**
|
* @property Canvas True if the device supports Canvas
|
* @type {Boolean}
|
*/
|
{
|
identity: 'Canvas',
|
fn: function(doc) {
|
return !!doc.createElement('canvas').getContext;
|
}
|
},
|
|
/**
|
* @property Vml True if the device supports VML
|
* @type {Boolean}
|
*/
|
{
|
identity: 'Vml',
|
fn: function(doc) {
|
var d = doc.createElement("div");
|
d.innerHTML = "<!--[if vml]><br/><br/><![endif]-->";
|
return (d.childNodes.length == 2);
|
}
|
},
|
|
/**
|
* @property Float True if the device supports CSS float
|
* @type {Boolean}
|
*/
|
{
|
identity: 'Float',
|
fn: function(doc, div) {
|
return !!div.lastChild.style.cssFloat;
|
}
|
},
|
|
/**
|
* @property AudioTag True if the device supports the HTML5 audio tag
|
* @type {Boolean}
|
*/
|
{
|
identity: 'AudioTag',
|
fn: function(doc) {
|
return !!doc.createElement('audio').canPlayType;
|
}
|
},
|
|
/**
|
* @property History True if the device supports HTML5 history
|
* @type {Boolean}
|
*/
|
{
|
identity: 'History',
|
fn: function() {
|
var history = window.history;
|
return !!(history && history.pushState);
|
}
|
},
|
|
/**
|
* @property CSS3DTransform True if the device supports CSS3DTransform
|
* @type {Boolean}
|
*/
|
{
|
identity: 'CSS3DTransform',
|
fn: function() {
|
return (typeof WebKitCSSMatrix != 'undefined' && new WebKitCSSMatrix().hasOwnProperty('m41'));
|
}
|
},
|
|
/**
|
* @property CSS3LinearGradient True if the device supports CSS3 linear gradients
|
* @type {Boolean}
|
*/
|
{
|
identity: 'CSS3LinearGradient',
|
fn: function(doc, div) {
|
var property = 'background-image:',
|
webkit = '-webkit-gradient(linear, left top, right bottom, from(black), to(white))',
|
w3c = 'linear-gradient(left top, black, white)',
|
moz = '-moz-' + w3c,
|
ms = '-ms-' + w3c,
|
opera = '-o-' + w3c,
|
options = [property + webkit, property + w3c, property + moz, property + ms, property + opera];
|
|
div.style.cssText = options.join(';');
|
|
return (("" + div.style.backgroundImage).indexOf('gradient') !== -1) && !Ext.isIE9;
|
}
|
},
|
|
/**
|
* @property CSS3BorderRadius True if the device supports CSS3 border radius
|
* @type {Boolean}
|
*/
|
{
|
identity: 'CSS3BorderRadius',
|
fn: function(doc, div) {
|
var domPrefixes = ['borderRadius', 'BorderRadius', 'MozBorderRadius', 'WebkitBorderRadius', 'OBorderRadius', 'KhtmlBorderRadius'],
|
pass = false,
|
i;
|
for (i = 0; i < domPrefixes.length; i++) {
|
if (document.body.style[domPrefixes[i]] !== undefined) {
|
return true;
|
}
|
}
|
return pass;
|
}
|
},
|
|
/**
|
* @property GeoLocation True if the device supports GeoLocation
|
* @type {Boolean}
|
*/
|
{
|
identity: 'GeoLocation',
|
fn: function() {
|
// Use the in check for geolocation, see https://github.com/Modernizr/Modernizr/issues/513
|
return (typeof navigator != 'undefined' && 'geolocation' in navigator) || (typeof google != 'undefined' && typeof google.gears != 'undefined');
|
}
|
},
|
/**
|
* @property MouseEnterLeave True if the browser supports mouseenter and mouseleave events
|
* @type {Boolean}
|
*/
|
{
|
identity: 'MouseEnterLeave',
|
fn: function(doc, div){
|
return ('onmouseenter' in div && 'onmouseleave' in div);
|
}
|
},
|
/**
|
* @property MouseWheel True if the browser supports the mousewheel event
|
* @type {Boolean}
|
*/
|
{
|
identity: 'MouseWheel',
|
fn: function(doc, div) {
|
return ('onmousewheel' in div);
|
}
|
},
|
/**
|
* @property Opacity True if the browser supports normal css opacity
|
* @type {Boolean}
|
*/
|
{
|
identity: 'Opacity',
|
fn: function(doc, div){
|
// Not a strict equal comparison in case opacity can be converted to a number.
|
if (Ext.isIE6 || Ext.isIE7 || Ext.isIE8) {
|
return false;
|
}
|
div.firstChild.style.cssText = 'opacity:0.73';
|
return div.firstChild.style.opacity == '0.73';
|
}
|
},
|
/**
|
* @property Placeholder True if the browser supports the HTML5 placeholder attribute on inputs
|
* @type {Boolean}
|
*/
|
{
|
identity: 'Placeholder',
|
fn: function(doc) {
|
return 'placeholder' in doc.createElement('input');
|
}
|
},
|
|
/**
|
* @property Direct2DBug True if when asking for an element's dimension via offsetWidth or offsetHeight,
|
* getBoundingClientRect, etc. the browser returns the subpixel width rounded to the nearest pixel.
|
* @type {Boolean}
|
*/
|
{
|
identity: 'Direct2DBug',
|
fn: function() {
|
return Ext.isString(document.body.style.msTransformOrigin) && Ext.isIE10m;
|
}
|
},
|
/**
|
* @property BoundingClientRect True if the browser supports the getBoundingClientRect method on elements
|
* @type {Boolean}
|
*/
|
{
|
identity: 'BoundingClientRect',
|
fn: function(doc, div) {
|
return Ext.isFunction(div.getBoundingClientRect);
|
}
|
},
|
/**
|
* @property RotatedBoundingClientRect True if the BoundingClientRect is
|
* rotated when the element is rotated using a CSS transform.
|
* @type {Boolean}
|
*/
|
{
|
identity: 'RotatedBoundingClientRect',
|
fn: function() {
|
var body = document.body,
|
supports = false,
|
el = document.createElement('div'),
|
style = el.style;
|
|
if (el.getBoundingClientRect) {
|
style.WebkitTransform = style.MozTransform =
|
style.OTransform = style.transform = 'rotate(90deg)';
|
style.width = '100px';
|
style.height = '30px';
|
body.appendChild(el)
|
|
supports = el.getBoundingClientRect().height !== 100;
|
body.removeChild(el);
|
}
|
|
return supports;
|
}
|
},
|
{
|
identity: 'IncludePaddingInWidthCalculation',
|
fn: function(doc, div){
|
return div.childNodes[1].firstChild.offsetWidth == 210;
|
}
|
},
|
{
|
identity: 'IncludePaddingInHeightCalculation',
|
fn: function(doc, div){
|
return div.childNodes[1].firstChild.offsetHeight == 210;
|
}
|
},
|
|
/**
|
* @property ArraySort True if the Array sort native method isn't bugged.
|
* @type {Boolean}
|
*/
|
{
|
identity: 'ArraySort',
|
fn: function() {
|
var a = [1,2,3,4,5].sort(function(){ return 0; });
|
return a[0] === 1 && a[1] === 2 && a[2] === 3 && a[3] === 4 && a[4] === 5;
|
}
|
},
|
/**
|
* @property Range True if browser support document.createRange native method.
|
* @type {Boolean}
|
*/
|
{
|
identity: 'Range',
|
fn: function() {
|
return !!document.createRange;
|
}
|
},
|
/**
|
* @property CreateContextualFragment True if browser support CreateContextualFragment range native methods.
|
* @type {Boolean}
|
*/
|
{
|
identity: 'CreateContextualFragment',
|
fn: function() {
|
var range = Ext.supports.Range ? document.createRange() : false;
|
|
return range && !!range.createContextualFragment;
|
}
|
},
|
|
/**
|
* @property WindowOnError True if browser supports window.onerror.
|
* @type {Boolean}
|
*/
|
{
|
identity: 'WindowOnError',
|
fn: function () {
|
// sadly, we cannot feature detect this...
|
return Ext.isIE || Ext.isGecko || Ext.webKitVersion >= 534.16; // Chrome 10+
|
}
|
},
|
|
/**
|
* @property TextAreaMaxLength True if the browser supports maxlength on textareas.
|
* @type {Boolean}
|
*/
|
{
|
identity: 'TextAreaMaxLength',
|
fn: function(){
|
var el = document.createElement('textarea');
|
return ('maxlength' in el);
|
}
|
},
|
/**
|
* @property GetPositionPercentage True if the browser will return the left/top/right/bottom
|
* position as a percentage when explicitly set as a percentage value.
|
* @type {Boolean}
|
*/
|
// Related bug: https://bugzilla.mozilla.org/show_bug.cgi?id=707691#c7
|
{
|
identity: 'GetPositionPercentage',
|
fn: function(doc, div){
|
return getStyle(div.childNodes[2], 'left') == '10%';
|
}
|
},
|
/**
|
* @property {Boolean} PercentageHeightOverflowBug
|
* In some browsers (IE quirks, IE6, IE7, IE9, chrome, safari and opera at the time
|
* of this writing) a percentage-height element ignores the horizontal scrollbar
|
* of its parent element. This method returns true if the browser is affected
|
* by this bug.
|
*
|
* @private
|
*/
|
{
|
identity: 'PercentageHeightOverflowBug',
|
fn: function(doc) {
|
var hasBug = false,
|
style, el;
|
|
if (Ext.getScrollbarSize().height) {
|
// must have space-consuming scrollbars for bug to be possible
|
el = doc.createElement('div');
|
style = el.style;
|
style.height = '50px';
|
style.width = '50px';
|
style.overflow = 'auto';
|
style.position = 'absolute';
|
|
el.innerHTML = [
|
'<div style="display:table;height:100%;">',
|
// The element that causes the horizontal overflow must be
|
// a child of the element with the 100% height, otherwise
|
// horizontal overflow is not triggered in webkit quirks mode
|
'<div style="width:51px;"></div>',
|
'</div>'
|
].join('');
|
doc.body.appendChild(el);
|
if (el.firstChild.offsetHeight === 50) {
|
hasBug = true;
|
}
|
doc.body.removeChild(el);
|
}
|
|
return hasBug;
|
}
|
},
|
/**
|
* @property {Boolean} xOriginBug
|
* In Chrome 24.0, an RTL element which has vertical overflow positions its right X origin incorrectly.
|
* It skips a non-existent scrollbar which has been moved to the left edge due to the RTL setting.
|
*
|
* http://code.google.com/p/chromium/issues/detail?id=174656
|
*
|
* This method returns true if the browser is affected by this bug.
|
*
|
* @private
|
*/
|
{
|
identity: 'xOriginBug',
|
fn: function(doc, div) {
|
div.innerHTML = '<div id="b1" style="height:100px;width:100px;direction:rtl;position:relative;overflow:scroll">' +
|
'<div id="b2" style="position:relative;width:100%;height:20px;"></div>' +
|
'<div id="b3" style="position:absolute;width:20px;height:20px;top:0px;right:0px"></div>' +
|
'</div>';
|
|
var outerBox = document.getElementById('b1').getBoundingClientRect(),
|
b2 = document.getElementById('b2').getBoundingClientRect(),
|
b3 = document.getElementById('b3').getBoundingClientRect();
|
|
return (b2.left !== outerBox.left && b3.right !== outerBox.right);
|
}
|
},
|
|
/**
|
* @property {Boolean} ScrollWidthInlinePaddingBug
|
* In some browsers the right padding of an overflowing element is not accounted
|
* for in its scrollWidth. The result can vary depending on whether or not
|
* The element contains block-level children. This method tests the effect
|
* of padding on scrollWidth when there are no block-level children inside the
|
* overflowing element.
|
*
|
* This method returns true if the browser is affected by this bug.
|
*/
|
{
|
identity: 'ScrollWidthInlinePaddingBug',
|
fn: function(doc) {
|
var hasBug = false,
|
style, el;
|
|
el = doc.createElement('div');
|
style = el.style;
|
style.height = '50px';
|
style.width = '50px';
|
style.padding = '10px';
|
style.overflow = 'hidden';
|
style.position = 'absolute';
|
|
el.innerHTML =
|
'<span style="display:inline-block;zoom:1;height:60px;width:60px;"></span>';
|
doc.body.appendChild(el);
|
if (el.scrollWidth === 70) {
|
hasBug = true;
|
}
|
doc.body.removeChild(el);
|
|
return hasBug;
|
}
|
}
|
]
|
};
|
}());
|
|
Ext.supports.init(); // run the "early" detections now
|