Skip to content
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
timmywil committed Dec 12, 2011
1 parent 605e4bb commit 9bea216
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 89 deletions.
@@ -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,
@@ -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

@mikesherov
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@timmywil
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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!

@mikesherov
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.