diff --git a/src/css/curCSS.js b/src/css/curCSS.js index 260184b47..f5c85ecc0 100644 --- a/src/css/curCSS.js +++ b/src/css/curCSS.js @@ -3,11 +3,13 @@ define([ "./var/rnumnonpx", "./var/rmargin", "./var/getStyles", + "./support", "../selector" // contains -], function( jQuery, rnumnonpx, rmargin, getStyles ) { +], function( jQuery, rnumnonpx, rmargin, getStyles, support ) { function curCSS( elem, name, computed ) { - var ret; + var width, minWidth, maxWidth, ret, + style = elem.style; computed = computed || getStyles( elem ); @@ -22,6 +24,29 @@ function curCSS( elem, name, computed ) { if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { ret = jQuery.style( elem, name ); } + + // Support: Android 4.0-4.3 + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // http://dev.w3.org/csswg/cssom/#resolved-values + if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } } return ret !== undefined ? diff --git a/src/css/support.js b/src/css/support.js index ffe3ed9bb..3165af87d 100644 --- a/src/css/support.js +++ b/src/css/support.js @@ -6,7 +6,7 @@ define([ ], function( jQuery, document, documentElement, support ) { (function() { - var pixelPositionVal, boxSizingReliableVal, + var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, container = document.createElement( "div" ), div = document.createElement( "div" ); @@ -20,7 +20,7 @@ define([ div.cloneNode( true ).style.backgroundClip = ""; support.clearCloneStyle = div.style.backgroundClip === "content-box"; - container.style.cssText = "border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;" + + container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;margin-top:1px;" + "position:absolute"; container.appendChild( div ); @@ -61,6 +61,16 @@ define([ } return boxSizingReliableVal; }, + pixelMarginRight: function() { + if ( pixelMarginRightVal == null ) { + div.style.cssText = "display:block;width:50%;margin-right:50%"; + documentElement.appendChild( container ); + pixelMarginRightVal = + window.getComputedStyle( div, null ).marginRight === "4px"; + documentElement.removeChild( container ); + } + return pixelMarginRightVal; + }, reliableMarginRight: function() { // Support: Android 2.3 diff --git a/test/unit/support.js b/test/unit/support.js index cfb37e585..81ae0d053 100644 --- a/test/unit/support.js +++ b/test/unit/support.js @@ -66,6 +66,7 @@ testIframeWithCallback( "Check CSP (https://developer.mozilla.org/en-US/docs/Sec "noCloneChecked": true, "optDisabled": true, "optSelected": true, + "pixelMarginRight": true, "pixelPosition": true, "radioValue": true, "reliableMarginRight": true @@ -83,6 +84,7 @@ testIframeWithCallback( "Check CSP (https://developer.mozilla.org/en-US/docs/Sec "noCloneChecked": false, "optDisabled": true, "optSelected": false, + "pixelMarginRight": true, "pixelPosition": true, "radioValue": false, "reliableMarginRight": true @@ -100,6 +102,7 @@ testIframeWithCallback( "Check CSP (https://developer.mozilla.org/en-US/docs/Sec "noCloneChecked": false, "optDisabled": true, "optSelected": false, + "pixelMarginRight": true, "pixelPosition": true, "radioValue": false, "reliableMarginRight": true @@ -117,6 +120,7 @@ testIframeWithCallback( "Check CSP (https://developer.mozilla.org/en-US/docs/Sec "noCloneChecked": true, "optDisabled": true, "optSelected": true, + "pixelMarginRight": true, "pixelPosition": false, "radioValue": true, "reliableMarginRight": true @@ -134,6 +138,7 @@ testIframeWithCallback( "Check CSP (https://developer.mozilla.org/en-US/docs/Sec "noCloneChecked": true, "optDisabled": true, "optSelected": true, + "pixelMarginRight": true, "pixelPosition": false, "radioValue": true, "reliableMarginRight": true @@ -151,6 +156,7 @@ testIframeWithCallback( "Check CSP (https://developer.mozilla.org/en-US/docs/Sec "noCloneChecked": true, "optDisabled": true, "optSelected": true, + "pixelMarginRight": true, "pixelPosition": true, "radioValue": true, "reliableMarginRight": true @@ -168,6 +174,7 @@ testIframeWithCallback( "Check CSP (https://developer.mozilla.org/en-US/docs/Sec "noCloneChecked": true, "optDisabled": true, "optSelected": true, + "pixelMarginRight": true, "pixelPosition": false, "radioValue": true, "reliableMarginRight": true @@ -185,6 +192,7 @@ testIframeWithCallback( "Check CSP (https://developer.mozilla.org/en-US/docs/Sec "noCloneChecked": true, "optDisabled": true, "optSelected": true, + "pixelMarginRight": true, "pixelPosition": false, "radioValue": true, "reliableMarginRight": true @@ -202,6 +210,7 @@ testIframeWithCallback( "Check CSP (https://developer.mozilla.org/en-US/docs/Sec "noCloneChecked": true, "optDisabled": true, "optSelected": true, + "pixelMarginRight": false, "pixelPosition": false, "radioValue": true, "reliableMarginRight": true @@ -219,6 +228,7 @@ testIframeWithCallback( "Check CSP (https://developer.mozilla.org/en-US/docs/Sec "noCloneChecked": true, "optDisabled": false, "optSelected": true, + "pixelMarginRight": true, "pixelPosition": false, "radioValue": true, "reliableMarginRight": false