Skip to content

Commit

Permalink
Dimensions: properly manipulate non-px values
Browse files Browse the repository at this point in the history
  • Loading branch information
timmywil committed Nov 9, 2015
1 parent 67fa2ea commit 7afbbce
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 39 deletions.
28 changes: 19 additions & 9 deletions src/css.js
Expand Up @@ -27,8 +27,6 @@ var
// except "table", "table-cell", or "table-caption"
// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
rdisplayswap = /^(none|table(?!-c[ea]).+)/,
rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),

cssShow = { position: "absolute", visibility: "hidden", display: "block" },
cssNormalTransform = {
letterSpacing: "0",
Expand Down Expand Up @@ -59,11 +57,14 @@ function vendorPropName( name ) {
}

function setPositiveNumber( elem, value, subtract ) {
var matches = rnumsplit.exec( value );

// Any relative (+/-) values have already been
// normalized at this point
var matches = rcssNum.exec( value );
return matches ?

// Guard against undefined "subtract", e.g., when used as in cssHooks
Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
value;
}

Expand Down Expand Up @@ -336,16 +337,25 @@ jQuery.each( [ "height", "width" ], function( i, name ) {
},

set: function( elem, value, extra ) {
var styles = extra && getStyles( elem );
return setPositiveNumber( elem, value, extra ?
augmentWidthOrHeight(
var matches,
styles = extra && getStyles( elem ),
subtract = extra && augmentWidthOrHeight(
elem,
name,
extra,
jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
styles
) : 0
);
);

// Convert to pixels if value adjustment is needed
if ( subtract && ( matches = rcssNum.exec( value ) ) &&
( matches[ 3 ] || "px" ) !== "px" ) {

elem.style[ name ] = value;
value = jQuery.css( elem, name );
}

return setPositiveNumber( elem, value, subtract );
}
};
} );
Expand Down
68 changes: 38 additions & 30 deletions test/unit/dimensions.js
Expand Up @@ -418,36 +418,44 @@ QUnit.test( "getters on non elements should return null", function( assert ) {
} );

QUnit.test( "setters with and without box-sizing:border-box", function( assert ) {
assert.expect( 20 );

// Support: Android 2.3 (-webkit-box-sizing).
var el_bb = jQuery( "<div style='width:114px;height:114px;margin:5px;padding:3px;border:4px solid white;-webkit-box-sizing:border-box;box-sizing:border-box;'>test</div>" ).appendTo( "#qunit-fixture" ),
el = jQuery( "<div style='width:100px;height:100px;margin:5px;padding:3px;border:4px solid white;'>test</div>" ).appendTo( "#qunit-fixture" ),
expected = 100;

assert.equal( el_bb.width( 101 ).width(), expected + 1, "test border-box width(int) by roundtripping" );
assert.equal( el_bb.innerWidth( 108 ).width(), expected + 2, "test border-box innerWidth(int) by roundtripping" );
assert.equal( el_bb.outerWidth( 117 ).width(), expected + 3, "test border-box outerWidth(int) by roundtripping" );
assert.equal( el_bb.outerWidth( 118, false ).width(), expected + 4, "test border-box outerWidth(int, false) by roundtripping" );
assert.equal( el_bb.outerWidth( 129, true ).width(), expected + 5, "test border-box innerWidth(int, true) by roundtripping" );

assert.equal( el_bb.height( 101 ).height(), expected + 1, "test border-box height(int) by roundtripping" );
assert.equal( el_bb.innerHeight( 108 ).height(), expected + 2, "test border-box innerHeight(int) by roundtripping" );
assert.equal( el_bb.outerHeight( 117 ).height(), expected + 3, "test border-box outerHeight(int) by roundtripping" );
assert.equal( el_bb.outerHeight( 118, false ).height(), expected + 4, "test border-box outerHeight(int, false) by roundtripping" );
assert.equal( el_bb.outerHeight( 129, true ).height(), expected + 5, "test border-box innerHeight(int, true) by roundtripping" );

assert.equal( el.width( 101 ).width(), expected + 1, "test border-box width(int) by roundtripping" );
assert.equal( el.innerWidth( 108 ).width(), expected + 2, "test border-box innerWidth(int) by roundtripping" );
assert.equal( el.outerWidth( 117 ).width(), expected + 3, "test border-box outerWidth(int) by roundtripping" );
assert.equal( el.outerWidth( 118, false ).width(), expected + 4, "test border-box outerWidth(int, false) by roundtripping" );
assert.equal( el.outerWidth( 129, true ).width(), expected + 5, "test border-box innerWidth(int, true) by roundtripping" );

assert.equal( el.height( 101 ).height(), expected + 1, "test border-box height(int) by roundtripping" );
assert.equal( el.innerHeight( 108 ).height(), expected + 2, "test border-box innerHeight(int) by roundtripping" );
assert.equal( el.outerHeight( 117 ).height(), expected + 3, "test border-box outerHeight(int) by roundtripping" );
assert.equal( el.outerHeight( 118, false ).height(), expected + 4, "test border-box outerHeight(int, false) by roundtripping" );
assert.equal( el.outerHeight( 129, true ).height(), expected + 5, "test border-box innerHeight(int, true) by roundtripping" );
assert.expect( 60 );

var parent = jQuery( "#foo" ).css({ width: "200px", height: "200px", "font-size": "16px" }),
el_bb = jQuery( "<div style='margin:5px;padding:1px;border:2px solid black;box-sizing:border-box;'></div>" ).appendTo( parent ),
el = jQuery( "<div style='margin:5px;padding:1px;border:2px solid black;'></div>" ).appendTo( parent );

jQuery.each( {
"number": { set: 100, expected: 100 },
"em": { set: "10em", expected: 160 },
"percentage": { set: "50%", expected: 100 }
}, function( units, values ) {
assert.equal( el_bb.width( values.set ).width(), values.expected, "test border-box width(" + units + ") by roundtripping" );
assert.equal( el_bb.innerWidth( values.set ).width(), values.expected - 2, "test border-box innerWidth(" + units + ") by roundtripping" );
assert.equal( el_bb.outerWidth( values.set ).width(), values.expected - 6, "test border-box outerWidth(" + units + ") by roundtripping" );
assert.equal( el_bb.outerWidth( values.set, false ).width(), values.expected - 6, "test border-box outerWidth(" + units + ", false) by roundtripping" );
assert.equal( el_bb.outerWidth( values.set, true ).width(), values.expected - 16, "test border-box innerWidth(" + units + ", true) by roundtripping" );

assert.equal( el_bb.height( values.set ).height(), values.expected, "test border-box height(" + units + ") by roundtripping" );
assert.equal( el_bb.innerHeight( values.set ).height(), values.expected - 2, "test border-box innerHeight(" + units + ") by roundtripping" );
assert.equal( el_bb.outerHeight( values.set ).height(), values.expected - 6, "test border-box outerHeight(" + units + ") by roundtripping" );
assert.equal( el_bb.outerHeight( values.set, false ).height(), values.expected - 6, "test border-box outerHeight(" + units + ", false) by roundtripping" );
assert.equal( el_bb.outerHeight( values.set, true ).height(), values.expected - 16, "test border-box innerHeight(" + units + ", true) by roundtripping" );

assert.equal( el.width( values.set ).width(), values.expected, "test non-border-box width(" + units + ") by roundtripping" );
assert.equal( el.innerWidth( values.set ).width(), values.expected - 2, "test non-border-box innerWidth(" + units + ") by roundtripping" );
assert.equal( el.outerWidth( values.set ).width(), values.expected - 6, "test non-border-box outerWidth(" + units + ") by roundtripping" );
assert.equal( el.outerWidth( values.set, false ).width(), values.expected - 6, "test non-border-box outerWidth(" + units + ", false) by roundtripping" );
assert.equal( el.outerWidth( values.set, true ).width(), values.expected - 16, "test non-border-box innerWidth(" + units + ", true) by roundtripping" );

assert.equal( el.height( values.set ).height(), values.expected, "test non-border-box height(" + units + ") by roundtripping" );
assert.equal( el.innerHeight( values.set ).height(), values.expected - 2, "test non-border-box innerHeight(" + units + ") by roundtripping" );
assert.equal( el.outerHeight( values.set ).height(), values.expected - 6, "test non-border-box outerHeight(" + units + ") by roundtripping" );
assert.equal( el.outerHeight( values.set, false ).height(), values.expected - 6, "test non-border-box outerHeight(" + units + ", false) by roundtripping" );
assert.equal( el.outerHeight( values.set, true ).height(), values.expected - 16, "test non-border-box innerHeight(" + units + ", true) by roundtripping" );
} );

// Reset styles
parent.css({ width: "", height: "", "font-size": "" });
} );

testIframe(
Expand Down

0 comments on commit 7afbbce

Please sign in to comment.