mirror of
https://github.com/jquery/jquery-ui.git
synced 2024-11-21 11:04:24 +00:00
Resizable: Fix content shrink on resize
Make resizable elements not shrink on resize when they have scrollbars and "box-sizing: content-box". Fixes: gh-2277 Closes gh-2281
This commit is contained in:
parent
d564731f20
commit
c934995efa
@ -244,4 +244,72 @@ QUnit.test( "nested resizable", function( assert ) {
|
|||||||
outer.remove();
|
outer.remove();
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
QUnit.test( "Resizable with scrollbars and box-sizing: border-box", function( assert ) {
|
||||||
|
assert.expect( 4 );
|
||||||
|
testResizableWithBoxSizing( assert, {
|
||||||
|
isBorderBox: true,
|
||||||
|
applyScaleTransform: false
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
QUnit.test( "Resizable with scrollbars and box-sizing: content-box", function( assert ) {
|
||||||
|
assert.expect( 4 );
|
||||||
|
testResizableWithBoxSizing( assert, {
|
||||||
|
isBorderBox: false,
|
||||||
|
applyScaleTransform: false
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
QUnit.test( "Resizable with scrollbars, a transform and box-sizing: border-box", function( assert ) {
|
||||||
|
assert.expect( 4 );
|
||||||
|
testResizableWithBoxSizing( assert, {
|
||||||
|
isBorderBox: true,
|
||||||
|
applyScaleTransform: true
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
QUnit.test( "Resizable with scrollbars, a transform and box-sizing: content-box", function( assert ) {
|
||||||
|
assert.expect( 4 );
|
||||||
|
testResizableWithBoxSizing( assert, {
|
||||||
|
isBorderBox: false,
|
||||||
|
applyScaleTransform: true
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
function testResizableWithBoxSizing( assert, options ) {
|
||||||
|
var widthBefore, heightBefore,
|
||||||
|
cssBoxSizing = options.isBorderBox ? "border-box" : "content-box",
|
||||||
|
cssTransform = options.applyScaleTransform ? "scale(1.5)" : "",
|
||||||
|
elementContent = $( "<div>" )
|
||||||
|
.css( {
|
||||||
|
width: "200px",
|
||||||
|
height: "200px",
|
||||||
|
padding: "10px",
|
||||||
|
border: "5px",
|
||||||
|
borderStyle: "solid",
|
||||||
|
margin: "20px"
|
||||||
|
} )
|
||||||
|
.appendTo( "#resizable1" ),
|
||||||
|
element = $( "#resizable1" ).css( { overflow: "auto", transform: cssTransform } ).resizable(),
|
||||||
|
handle = ".ui-resizable-se";
|
||||||
|
|
||||||
|
$( "<style> * { box-sizing: " + cssBoxSizing + "; } </style>" ).appendTo( "#qunit-fixture" );
|
||||||
|
|
||||||
|
// In some browsers scrollbar may change element size (when "box-sizing: content-box")
|
||||||
|
widthBefore = element.innerWidth();
|
||||||
|
heightBefore = element.innerHeight();
|
||||||
|
|
||||||
|
// Both scrollbars
|
||||||
|
testHelper.drag( handle, 10, 10 );
|
||||||
|
assert.equal( parseFloat( element.innerWidth() ), widthBefore + 10, "element width (both scrollbars)" );
|
||||||
|
assert.equal( parseFloat( element.innerHeight() ), heightBefore + 10, "element height (both scrollbars)" );
|
||||||
|
|
||||||
|
// Single (vertical) scrollbar.
|
||||||
|
elementContent.css( "width", "50px" );
|
||||||
|
|
||||||
|
testHelper.drag( handle, 10, 10 );
|
||||||
|
assert.equal( parseFloat( element.innerWidth() ), widthBefore + 20, "element width (only vertical scrollbar)" );
|
||||||
|
assert.equal( parseFloat( element.innerHeight() ), heightBefore + 20, "element height (only vertical scrollbar)" );
|
||||||
|
}
|
||||||
|
|
||||||
} );
|
} );
|
||||||
|
@ -542,21 +542,22 @@ QUnit.test( "alsoResize + multiple selection", function( assert ) {
|
|||||||
QUnit.test( "alsoResize with box-sizing: border-box", function( assert ) {
|
QUnit.test( "alsoResize with box-sizing: border-box", function( assert ) {
|
||||||
assert.expect( 4 );
|
assert.expect( 4 );
|
||||||
|
|
||||||
|
$( "<style> * { box-sizing: border-box; } </style>" ).appendTo( "#qunit-fixture" );
|
||||||
|
|
||||||
var other = $( "<div>" )
|
var other = $( "<div>" )
|
||||||
.css( {
|
.css( {
|
||||||
width: 50,
|
width: "50px",
|
||||||
height: 50,
|
height: "50px",
|
||||||
padding: 10,
|
padding: "10px",
|
||||||
border: 5
|
border: "5px",
|
||||||
|
borderStyle: "solid"
|
||||||
} )
|
} )
|
||||||
.appendTo( "body" ),
|
.appendTo( "#qunit-fixture" ),
|
||||||
element = $( "#resizable1" ).resizable( {
|
element = $( "#resizable1" ).resizable( {
|
||||||
alsoResize: other
|
alsoResize: other
|
||||||
} ),
|
} ),
|
||||||
handle = ".ui-resizable-se";
|
handle = ".ui-resizable-se";
|
||||||
|
|
||||||
$( "*" ).css( "box-sizing", "border-box" );
|
|
||||||
|
|
||||||
testHelper.drag( handle, 80, 80 );
|
testHelper.drag( handle, 80, 80 );
|
||||||
|
|
||||||
assert.equal( element.width(), 180, "resizable width" );
|
assert.equal( element.width(), 180, "resizable width" );
|
||||||
@ -565,4 +566,51 @@ QUnit.test( "alsoResize with box-sizing: border-box", function( assert ) {
|
|||||||
assert.equal( parseFloat( other.css( "height" ) ), 130, "alsoResize height" );
|
assert.equal( parseFloat( other.css( "height" ) ), 130, "alsoResize height" );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
QUnit.test( "alsoResize with scrollbars and box-sizing: border-box", function( assert ) {
|
||||||
|
assert.expect( 4 );
|
||||||
|
testAlsoResizeWithBoxSizing( assert, {
|
||||||
|
isBorderBox: true
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
QUnit.test( "alsoResize with scrollbars and box-sizing: content-box", function( assert ) {
|
||||||
|
assert.expect( 4 );
|
||||||
|
testAlsoResizeWithBoxSizing( assert, {
|
||||||
|
isBorderBox: false
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
function testAlsoResizeWithBoxSizing( assert, options ) {
|
||||||
|
var widthBefore, heightBefore,
|
||||||
|
cssBoxSizing = options.isBorderBox ? "border-box" : "content-box",
|
||||||
|
other = $( "<div>" )
|
||||||
|
.css( {
|
||||||
|
width: "150px",
|
||||||
|
height: "150px",
|
||||||
|
padding: "10px",
|
||||||
|
border: "5px",
|
||||||
|
borderStyle: "solid",
|
||||||
|
margin: "20px",
|
||||||
|
overflow: "scroll"
|
||||||
|
} )
|
||||||
|
.appendTo( "#qunit-fixture" ),
|
||||||
|
element = $( "#resizable1" ).resizable( {
|
||||||
|
alsoResize: other
|
||||||
|
} ),
|
||||||
|
handle = ".ui-resizable-se";
|
||||||
|
|
||||||
|
$( "<style> * { box-sizing: " + cssBoxSizing + "; } </style>" ).appendTo( "#qunit-fixture" );
|
||||||
|
|
||||||
|
// In some browsers scrollbar may change element computed size.
|
||||||
|
widthBefore = other.innerWidth();
|
||||||
|
heightBefore = other.innerHeight();
|
||||||
|
|
||||||
|
testHelper.drag( handle, 80, 80 );
|
||||||
|
|
||||||
|
assert.equal( element.width(), 180, "resizable width" );
|
||||||
|
assert.equal( parseFloat( other.innerWidth() ), widthBefore + 80, "alsoResize width" );
|
||||||
|
assert.equal( element.height(), 180, "resizable height" );
|
||||||
|
assert.equal( parseFloat( other.innerHeight() ), heightBefore + 80, "alsoResize height" );
|
||||||
|
}
|
||||||
|
|
||||||
} );
|
} );
|
||||||
|
@ -80,12 +80,18 @@ $.widget( "ui.resizable", $.ui.mouse, {
|
|||||||
|
|
||||||
_hasScroll: function( el, a ) {
|
_hasScroll: function( el, a ) {
|
||||||
|
|
||||||
if ( $( el ).css( "overflow" ) === "hidden" ) {
|
var scroll,
|
||||||
|
has = false,
|
||||||
|
overflow = $( el ).css( "overflow" );
|
||||||
|
|
||||||
|
if ( overflow === "hidden" ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if ( overflow === "scroll" ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
|
scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop";
|
||||||
has = false;
|
|
||||||
|
|
||||||
if ( el[ scroll ] > 0 ) {
|
if ( el[ scroll ] > 0 ) {
|
||||||
return true;
|
return true;
|
||||||
@ -362,7 +368,7 @@ $.widget( "ui.resizable", $.ui.mouse, {
|
|||||||
|
|
||||||
_mouseStart: function( event ) {
|
_mouseStart: function( event ) {
|
||||||
|
|
||||||
var curleft, curtop, cursor,
|
var curleft, curtop, cursor, calculatedSize,
|
||||||
o = this.options,
|
o = this.options,
|
||||||
el = this.element;
|
el = this.element;
|
||||||
|
|
||||||
@ -381,20 +387,24 @@ $.widget( "ui.resizable", $.ui.mouse, {
|
|||||||
this.offset = this.helper.offset();
|
this.offset = this.helper.offset();
|
||||||
this.position = { left: curleft, top: curtop };
|
this.position = { left: curleft, top: curtop };
|
||||||
|
|
||||||
|
if ( !this._helper ) {
|
||||||
|
calculatedSize = this._calculateAdjustedElementDimensions( el );
|
||||||
|
}
|
||||||
|
|
||||||
this.size = this._helper ? {
|
this.size = this._helper ? {
|
||||||
width: this.helper.width(),
|
width: this.helper.width(),
|
||||||
height: this.helper.height()
|
height: this.helper.height()
|
||||||
} : {
|
} : {
|
||||||
width: el.width(),
|
width: calculatedSize.width,
|
||||||
height: el.height()
|
height: calculatedSize.height
|
||||||
};
|
};
|
||||||
|
|
||||||
this.originalSize = this._helper ? {
|
this.originalSize = this._helper ? {
|
||||||
width: el.outerWidth(),
|
width: el.outerWidth(),
|
||||||
height: el.outerHeight()
|
height: el.outerHeight()
|
||||||
} : {
|
} : {
|
||||||
width: el.width(),
|
width: calculatedSize.width,
|
||||||
height: el.height()
|
height: calculatedSize.height
|
||||||
};
|
};
|
||||||
|
|
||||||
this.sizeDiff = {
|
this.sizeDiff = {
|
||||||
@ -690,6 +700,52 @@ $.widget( "ui.resizable", $.ui.mouse, {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_calculateAdjustedElementDimensions: function( element ) {
|
||||||
|
var elWidth, elHeight, paddingBorder,
|
||||||
|
ce = element.get( 0 );
|
||||||
|
|
||||||
|
if ( element.css( "box-sizing" ) !== "content-box" ||
|
||||||
|
( !this._hasScroll( ce ) && !this._hasScroll( ce, "left" ) ) ) {
|
||||||
|
return {
|
||||||
|
height: parseFloat( element.css( "height" ) ),
|
||||||
|
width: parseFloat( element.css( "width" ) )
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if CSS inline styles are set and use those (usually from previous resizes)
|
||||||
|
elWidth = parseFloat( ce.style.width );
|
||||||
|
elHeight = parseFloat( ce.style.height );
|
||||||
|
|
||||||
|
paddingBorder = this._getPaddingPlusBorderDimensions( element );
|
||||||
|
elWidth = isNaN( elWidth ) ?
|
||||||
|
this._getElementTheoreticalSize( element, paddingBorder, "width" ) :
|
||||||
|
elWidth;
|
||||||
|
elHeight = isNaN( elHeight ) ?
|
||||||
|
this._getElementTheoreticalSize( element, paddingBorder, "height" ) :
|
||||||
|
elHeight;
|
||||||
|
|
||||||
|
return {
|
||||||
|
height: elHeight,
|
||||||
|
width: elWidth
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
_getElementTheoreticalSize: function( element, extraSize, dimension ) {
|
||||||
|
|
||||||
|
// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
|
||||||
|
var size = Math.max( 0, Math.ceil(
|
||||||
|
element.get( 0 )[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
|
||||||
|
extraSize[ dimension ] -
|
||||||
|
0.5
|
||||||
|
|
||||||
|
// If offsetWidth/offsetHeight is unknown, then we can't determine theoretical size.
|
||||||
|
// Use an explicit zero to avoid NaN.
|
||||||
|
// See https://github.com/jquery/jquery/issues/3964
|
||||||
|
) ) || 0;
|
||||||
|
|
||||||
|
return size;
|
||||||
|
},
|
||||||
|
|
||||||
_proportionallyResize: function() {
|
_proportionallyResize: function() {
|
||||||
|
|
||||||
if ( !this._proportionallyResizeElements.length ) {
|
if ( !this._proportionallyResizeElements.length ) {
|
||||||
@ -1044,9 +1100,11 @@ $.ui.plugin.add( "resizable", "alsoResize", {
|
|||||||
o = that.options;
|
o = that.options;
|
||||||
|
|
||||||
$( o.alsoResize ).each( function() {
|
$( o.alsoResize ).each( function() {
|
||||||
var el = $( this );
|
var el = $( this ),
|
||||||
|
elSize = that._calculateAdjustedElementDimensions( el );
|
||||||
|
|
||||||
el.data( "ui-resizable-alsoresize", {
|
el.data( "ui-resizable-alsoresize", {
|
||||||
width: parseFloat( el.css( "width" ) ), height: parseFloat( el.css( "height" ) ),
|
width: elSize.width, height: elSize.height,
|
||||||
left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
|
left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
Loading…
Reference in New Issue
Block a user