Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resizable: Fix content shrink on resize #2281

Merged
merged 9 commits into from
Sep 9, 2024
138 changes: 138 additions & 0 deletions tests/unit/resizable/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -244,4 +244,142 @@ QUnit.test( "nested resizable", function( assert ) {
outer.remove();
} );

QUnit.test( "Resizable with scrollbars and box-sizing: border-box", function( assert ) {
Daniel-Garmig marked this conversation as resolved.
Show resolved Hide resolved
assert.expect( 4 );

var style = $( "<style> * { box-sizing: border-box; } </style>" ).appendTo( "head" );
Daniel-Garmig marked this conversation as resolved.
Show resolved Hide resolved

//Both scrollbars
Daniel-Garmig marked this conversation as resolved.
Show resolved Hide resolved
var elementContent = $( "<div>" )
.css( {
width: "200px",
height: "200px",
padding: "10px",
border: "5px",
borderStyle: "solid",
margin: "20px"
} )
.appendTo( "#resizable1" ),
element = $( "#resizable1" ).css( "overflow", "auto" ).resizable(),
handle = ".ui-resizable-se";

testHelper.drag( handle, 10, 10 );
assert.equal( element.width(), 110, "element width (both scrollbars)" );
assert.equal( element.height(), 110, "element height (both scrollbars)" );

//Single (vertical) scrollbar.
elementContent.css( "width", "50px" );
testHelper.drag( handle, 10, 10 );
assert.equal( element.width(), 120, "element width (only vertical scrollbar)" );
assert.equal( element.height(), 120, "element height (only vertical scrollbar)" );

style.remove();
} );

QUnit.test( "Resizable with scrollbars and box-sizing: content-box", function( assert ) {
assert.expect( 4 );

var style = $( "<style> * { box-sizing: content-box; } </style>" ).appendTo( "head" );

//Both scrollbars
var elementContent = $( "<div>" )
.css( {
width: "200px",
height: "200px",
padding: "10px",
border: "5px",
borderStyle: "solid",
margin: "20px"
} )
.appendTo( "#resizable1" ),
element = $( "#resizable1" ).css( "overflow", "auto" ).resizable(),
handle = ".ui-resizable-se";

// In some browsers scrollbar may change element size (when "box-sizing: content-box")
var widthBefore = element.innerWidth();
var heightBefore = element.innerHeight();

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)" );

style.remove();
} );

QUnit.test( "Resizable with scrollbars, a transform and box-sizing: border-box", function( assert ) {
assert.expect( 4 );

var style = $( "<style> * { box-sizing: border-box; } </style>" ).appendTo( "head" );

//Both scrollbars
var elementContent = $( "<div>" )
.css( {
width: "200px",
height: "200px",
padding: "10px",
border: "5px",
borderStyle: "solid",
margin: "20px"
} )
.appendTo( "#resizable1" ),
element = $( "#resizable1" ).css( { overflow: "auto", transform: "scale(1.5)" } ).resizable(),
handle = ".ui-resizable-se";

testHelper.drag( handle, 10, 10 );
assert.equal( element.width(), 110, "element width (both scrollbars)" );
assert.equal( element.height(), 110, "element height (both scrollbars)" );

//Single (vertical) scrollbar.
elementContent.css( "width", "50px" );
testHelper.drag( handle, 10, 10 );
assert.equal( element.width(), 120, "element width (only vertical scrollbar)" );
assert.equal( element.height(), 120, "element height (only vertical scrollbar)" );

style.remove();
} );

QUnit.test( "Resizable with scrollbars, a transform and box-sizing: content-box", function( assert ) {
assert.expect( 4 );

var style = $( "<style> * { box-sizing: content-box; } </style>" ).appendTo( "head" );

//Both scrollbars
var elementContent = $( "<div>" )
.css( {
width: "200px",
height: "200px",
padding: "10px",
border: "5px",
borderStyle: "solid",
margin: "20px"
} )
.appendTo( "#resizable1" ),
element = $( "#resizable1" ).css( { overflow: "auto", transform: "scale(1.5)" } ).resizable(),
handle = ".ui-resizable-se";

// In some browsers scrollbar may change element size (when "box-sizing: content-box")
var widthBefore = element.innerWidth();
var heightBefore = element.innerHeight();

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)" );

style.remove();
} );

} );
67 changes: 67 additions & 0 deletions tests/unit/resizable/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -565,4 +565,71 @@ QUnit.test( "alsoResize with box-sizing: border-box", function( assert ) {
assert.equal( parseFloat( other.css( "height" ) ), 130, "alsoResize height" );
} );

QUnit.test( "alsoResize with scrollbars and box-sizing: border-box", function( assert ) {
assert.expect( 4 );

var style = $( "<style> * { box-sizing: border-box; } </style>" ).appendTo( "head" );

var other = $( "<div>" )
.css( {
width: "150px",
height: "150px",
padding: "10px",
border: "5px",
borderStyle: "solid",
margin: "25px",
overflow: "scroll"
} )
.appendTo( "#qunit-fixture" ),
element = $( "#resizable1" ).resizable( {
alsoResize: other
} ),
handle = ".ui-resizable-se";

testHelper.drag( handle, 80, 80 );

assert.equal( element.width(), 180, "resizable width" );
assert.equal( parseFloat( other.css( "width" ) ), 230, "alsoResize width" );
assert.equal( element.height(), 180, "resizable height" );
assert.equal( parseFloat( other.css( "height" ) ), 230, "alsoResize height" );

style.remove();
} );

QUnit.test( "alsoResize with scrollbars and box-sizing: content-box", function( assert ) {
assert.expect( 4 );

var style = $( "<style> * { box-sizing: content-box; } </style>" ).appendTo( "head" );

var 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";

// In some browsers scrollbar may change element computed size.
var widthBefore = other.innerWidth();
var 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" );

style.remove();
} );


} );
63 changes: 57 additions & 6 deletions ui/widgets/resizable.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,13 @@ $.widget( "ui.resizable", $.ui.mouse, {

_hasScroll: function( el, a ) {

if ( $( el ).css( "overflow" ) === "hidden" ) {
var overflow = $( el ).css( "overflow" );
if ( overflow === "hidden" ) {
return false;
}
if ( overflow === "scroll" ) {
return true;
}

var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
has = false;
Expand Down Expand Up @@ -381,20 +385,25 @@ $.widget( "ui.resizable", $.ui.mouse, {
this.offset = this.helper.offset();
this.position = { left: curleft, top: curtop };

var calculatedSize = undefined;
Daniel-Garmig marked this conversation as resolved.
Show resolved Hide resolved
if ( !this._helper ) {
calculatedSize = this._calculateAdjustedElementDimensions( el );
}

this.size = this._helper ? {
width: this.helper.width(),
height: this.helper.height()
} : {
width: el.width(),
height: el.height()
width: calculatedSize.width,
height: calculatedSize.height
};

this.originalSize = this._helper ? {
width: el.outerWidth(),
height: el.outerHeight()
} : {
width: el.width(),
height: el.height()
width: calculatedSize.width,
height: calculatedSize.height
};

this.sizeDiff = {
Expand Down Expand Up @@ -690,6 +699,45 @@ $.widget( "ui.resizable", $.ui.mouse, {
};
},

_calculateAdjustedElementDimensions: function( element ) {
var 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)
var elWidth = ce.style.width === "" ? "" : parseFloat( ce.style.width );
var elHeight = ce.style.height === "" ? "" : parseFloat( ce.style.height );

if ( elWidth === "" ) {
elWidth = this._getElementSizeWithoutOverflow( element, "width" );
}
if ( elHeight === "" ) {
elHeight = this._getElementSizeWithoutOverflow( element, "height" );
}

return {
height: elHeight,
width: elWidth
};
},

_getElementSizeWithoutOverflow: function( element, sizeProperty ) {
var overflowProperty = sizeProperty === "width" ? "overflow-y" : "overflow-x";

var origOverflow = element.css( overflowProperty );
element.css( overflowProperty, "hidden" );
var elSize = parseFloat( element.css( sizeProperty ) );
Daniel-Garmig marked this conversation as resolved.
Show resolved Hide resolved
element.css( overflowProperty, origOverflow );

return elSize;
},

_proportionallyResize: function() {

if ( !this._proportionallyResizeElements.length ) {
Expand Down Expand Up @@ -1045,8 +1093,11 @@ $.ui.plugin.add( "resizable", "alsoResize", {

$( o.alsoResize ).each( function() {
var el = $( this );

var elSize = that._calculateAdjustedElementDimensions( el );

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" ) )
} );
} );
Expand Down