Permalink
Browse files

When the width/height computed unit is not pixels, return that instea…

…d. Fixes #10782.

- Reordered some of css.js in preparation for jshint undef.
  • Loading branch information...
1 parent 605e4bb commit 9bea2167c434d5b97643f53da16b04927dc02a7d @timmywil timmywil committed Dec 12, 2011
Showing with 101 additions and 89 deletions.
  1. +92 −84 src/css.js
  2. +9 −5 test/unit/css.js
View
@@ -166,97 +166,16 @@ jQuery.extend({
// DEPRECATED, Use jQuery.css() instead
jQuery.curCSS = jQuery.css;
-jQuery.each(["height", "width"], function( i, name ) {
- jQuery.cssHooks[ name ] = {
- get: function( elem, computed, extra ) {
- if ( computed ) {
- if ( elem.offsetWidth !== 0 ) {
- return getWidthOrHeight( elem, name, extra );
- } else {
- return jQuery.swap( elem, cssShow, function() {
- return getWidthOrHeight( elem, name, extra );
- });
- }
- }
- },
-
- set: function( elem, value ) {
- return rnum.test( value ) ?
- value + "px" :
- value;
- }
- };
-});
-
-if ( !jQuery.support.opacity ) {
- jQuery.cssHooks.opacity = {
- get: function( elem, computed ) {
- // IE uses filters for opacity
- return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
- ( parseFloat( RegExp.$1 ) / 100 ) + "" :
- computed ? "1" : "";
- },
-
- set: function( elem, value ) {
- var style = elem.style,
- currentStyle = elem.currentStyle,
- opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
- filter = currentStyle && currentStyle.filter || style.filter || "";
-
- // IE has trouble with opacity if it does not have layout
- // Force it by setting the zoom level
- style.zoom = 1;
-
- // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
- if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" ) {
-
- // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
- // if "filter:" is present at all, clearType is disabled, we want to avoid this
- // style.removeAttribute is IE Only, but so apparently is this code path...
- style.removeAttribute( "filter" );
-
- // if there there is no filter style applied in a css rule, we are done
- if ( currentStyle && !currentStyle.filter ) {
- return;
- }
- }
-
- // otherwise, set new filter values
- style.filter = ralpha.test( filter ) ?
- filter.replace( ralpha, opacity ) :
- filter + " " + opacity;
- }
- };
-}
-
-jQuery(function() {
- // This hook cannot be added until DOM ready because the support test
- // for it is not run until after DOM ready
- if ( !jQuery.support.reliableMarginRight ) {
- jQuery.cssHooks.marginRight = {
- get: function( elem, computed ) {
- // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
- // Work around by temporarily setting element display to inline-block
- return jQuery.swap( elem, { "display": "inline-block" }, function() {
- if ( computed ) {
- return curCSS( elem, "margin-right", "marginRight" );
- } else {
- return elem.style.marginRight;
- }
- });
- }
- };
- }
-});
-
if ( document.defaultView && document.defaultView.getComputedStyle ) {
getComputedStyle = function( elem, name ) {
- var ret, defaultView, computedStyle, width, style = elem.style;
+ var ret, defaultView, computedStyle, width,
+ style = elem.style;
name = name.replace( rupper, "-$1" ).toLowerCase();
if ( (defaultView = elem.ownerDocument.defaultView) &&
(computedStyle = defaultView.getComputedStyle( elem, null )) ) {
+
ret = computedStyle.getPropertyValue( name );
if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
ret = jQuery.style( elem, name );
@@ -349,6 +268,12 @@ function getWidthOrHeight( elem, name, extra ) {
if ( val < 0 || val == null ) {
val = elem.style[ name ];
}
+
+ // Computed unit is not pixels. Stop here and return.
+ if ( rnumnonpx.test(val) ) {
+ return val;
+ }
+
// Normalize "", auto, and prepare for extra
val = parseFloat( val ) || 0;
@@ -368,6 +293,89 @@ function getWidthOrHeight( elem, name, extra ) {
return val + "px";
}
+jQuery.each([ "height", "width" ], function( i, name ) {
+ jQuery.cssHooks[ name ] = {
+ get: function( elem, computed, extra ) {
+ if ( computed ) {
+ if ( elem.offsetWidth !== 0 ) {
+ return getWidthOrHeight( elem, name, extra );
+ } else {
+ return jQuery.swap( elem, cssShow, function() {
+ return getWidthOrHeight( elem, name, extra );
+ });
+ }
+ }
+ },
+
+ set: function( elem, value ) {
+ return rnum.test( value ) ?
+ value + "px" :
+ value;
+ }
+ };
+});
+
+if ( !jQuery.support.opacity ) {
+ jQuery.cssHooks.opacity = {
+ get: function( elem, computed ) {
+ // IE uses filters for opacity
+ return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
+ ( parseFloat( RegExp.$1 ) / 100 ) + "" :
+ computed ? "1" : "";
+ },
+
+ set: function( elem, value ) {
+ var style = elem.style,
+ currentStyle = elem.currentStyle,
+ opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
+ filter = currentStyle && currentStyle.filter || style.filter || "";
+
+ // IE has trouble with opacity if it does not have layout
+ // Force it by setting the zoom level
+ style.zoom = 1;
+
+ // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
+ if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" ) {
+
+ // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
+ // if "filter:" is present at all, clearType is disabled, we want to avoid this
+ // style.removeAttribute is IE Only, but so apparently is this code path...
+ style.removeAttribute( "filter" );
+
+ // if there there is no filter style applied in a css rule, we are done
+ if ( currentStyle && !currentStyle.filter ) {
+ return;
+ }
+ }
+
+ // otherwise, set new filter values
+ style.filter = ralpha.test( filter ) ?
+ filter.replace( ralpha, opacity ) :
+ filter + " " + opacity;
+ }
+ };
+}
+
+jQuery(function() {
+ // This hook cannot be added until DOM ready because the support test
+ // for it is not run until after DOM ready
+ if ( !jQuery.support.reliableMarginRight ) {
+ jQuery.cssHooks.marginRight = {
+ get: function( elem, computed ) {
+ // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+ // Work around by temporarily setting element display to inline-block
+ return jQuery.swap( elem, { "display": "inline-block" }, function() {
+ if ( computed ) {
+ return curCSS( elem, "margin-right", "marginRight" );
+ } else {
+ return elem.style.marginRight;
+ }
+ });
+ }
+ };
+ }
+});
+
if ( jQuery.expr && jQuery.expr.filters ) {
jQuery.expr.filters.hidden = function( elem ) {
var width = elem.offsetWidth,
View
@@ -1,13 +1,17 @@
module("css", { teardown: moduleTeardown });
test("css(String|Hash)", function() {
- expect( 44 );
+ expect( 46 );
- equal( jQuery("#qunit-fixture").css("display"), "block", "Check for css property \"display\"");
+ equal( jQuery("#qunit-fixture").css("display"), "block", "Check for css property \"display\"" );
+
+ ok( jQuery("#nothiddendiv").is(":visible"), "Modifying CSS display: Assert element is visible" );
+ jQuery("#nothiddendiv").css({ display: "none" });
+ ok( !jQuery("#nothiddendiv").is(":visible"), "Modified CSS display: Assert element is hidden" );
+ var $child = jQuery("#nothiddendivchild").css({ width: "20%", height: "20%" });
+ notEqual( $child.css("width"), "20px", "Retrieving a width percentage on the child of a hidden div returns percentage" );
+ notEqual( $child.css("height"), "20px", "Retrieving a height percentage on the child of a hidden div returns percentage" );
- ok( jQuery("#nothiddendiv").is(":visible"), "Modifying CSS display: Assert element is visible");
- jQuery("#nothiddendiv").css({display: "none"});
- ok( !jQuery("#nothiddendiv").is(":visible"), "Modified CSS display: Assert element is hidden");
jQuery("#nothiddendiv").css({display: "block"});
ok( jQuery("#nothiddendiv").is(":visible"), "Modified CSS display: Assert element is visible");
ok( jQuery(window).is(":visible"), "Calling is(':visible') on window does not throw an error in IE.");

3 comments on commit 9bea216

Member

mikesherov replied Dec 12, 2011

there is still a problem in dimensions for inner/outerwidth where a hidden div is partially pixels, partially percents. I think we should address that.

Owner

timmywil replied Dec 12, 2011

Yea we talked about that. We don't want to put in too much code for these edge cases, but this is an improvement for .css('width/height'). Feel free to continue tackling tho!

Member

mikesherov replied Dec 12, 2011

That's fine. We should then at least document that known issue.... of course, I'll continue to try to find an efficient, smaller solution :-)

Please sign in to comment.