Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Resizable: Refactored resize handler. Fixed #5545, #5817, #7605. #694

Closed
wants to merge 4 commits into from

3 participants

@eromba

This pull request includes a refactoring of Resizable's resize handler that fixes 3 reported issues. The fixes build upon one another, so I am including them together in one request. I've included appropriate test cases for each issue, as well.

Resizable now modifies only the CSS properties that are actually necessary to perform the resize (instead of always setting top, left, width, and height regardless; see #7605). This makes the plugin behave more predictably in dynamic layouts.

Furthermore, the plugin's resize event is now altogether more useful:

  • The event is triggered only when the element's size is modified (as opposed to every mousemove; see #5545)
  • The ui callback parameter now correctly reports the element's current size (see #5817)
ui/jquery.ui.resizable.js
((26 lines not shown))
if (!this._helper && this._proportionallyResizeElements.length)
this._proportionallyResize();
- this._updateCache(data);
-
- // calling the user callback at the end
- this._trigger('resize', event, this.ui());
+ // Call the user callback if the element was resized
+ if ( ! $.isEmptyObject(props) ) {
@scottgonzalez Owner

Can you please change this to use a flag inside each fo the conditionals above? $.isEmptyObject() wasn't added until jQuery 1.4, and if we land this change it'll need to go into 1-8-stable as well. Otherwise this will need to wait until 1.10 when we introduce breaking changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@eromba

This should now be ready to go for both master and 1.8-stable.

@mikesherov
Collaborator

Hi @eromba, thanks again for contributing this patch. We recently rewrote the test suite for resizable. Can you rebase this please?

@eromba

I'm closing this pull request since I'll be moving the rebased commits to a new, dedicated branch.

@eromba eromba closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 10, 2012
  1. @eromba

    Resizable: Update CSS dimensions selectively. Fixed #7605 - Setting w…

    eromba authored
    …idth
    
    and height when only one is changing
  2. @eromba

    Resizable: Trigger resize event only when element is resized. Fixed #…

    eromba authored
    …5545
    
    - Callbacks ignore the grid.
  3. @eromba

    Resizable: Added event tests. Confirms fix for #5817 - resize event r…

    eromba authored
    …eports unconstrained ui.size
Commits on Jul 16, 2012
  1. @eromba
This page is out of date. Refresh to see the latest.
View
16 tests/unit/resizable/resizable.html
@@ -38,6 +38,18 @@
}
</script>
<script src="../swarminject.js"></script>
+
+ <style>
+ #resizable1 {
+ background: green;
+ height: 100px;
+ width: 100px;
+ }
+ #resizable2 {
+ height: 100px;
+ width: 100px;
+ }
+ </style>
</head>
<body>
@@ -48,8 +60,8 @@ <h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<div id="qunit-fixture">
-<div id="resizable1" style="background: green; width: 100px; height: 100px;">I'm a resizable.</div>
-<img src="images/test.jpg" id="resizable2" style="width: 100px; height: 100px;" alt="solid gray">
+<div id="resizable1">I'm a resizable.</div>
+<img src="images/test.jpg" id="resizable2" alt="solid gray">
</div>
</body>
View
37 tests/unit/resizable/resizable_core.js
@@ -42,7 +42,7 @@ test("element types", function() {
*/
test("n", function() {
- expect(2);
+ expect(4);
var handle = '.ui-resizable-n', target = $('#resizable1').resizable({ handles: 'all' });
@@ -51,10 +51,13 @@ test("n", function() {
drag(handle, 0, 50);
equal( target.height(), 100, "compare height" );
+
+ equal( target[0].style.left, "", "left should not be modified" );
+ equal( target[0].style.width, "", "width should not be modified" );
});
test("s", function() {
- expect(2);
+ expect(5);
var handle = '.ui-resizable-s', target = $('#resizable1').resizable({ handles: 'all' });
@@ -63,22 +66,30 @@ test("s", function() {
drag(handle, 0, -50);
equal( target.height(), 100, "compare height" );
+
+ equal( target[0].style.top, "", "top should not be modified" );
+ equal( target[0].style.left, "", "left should not be modified" );
+ equal( target[0].style.width, "", "width should not be modified" );
});
test("e", function() {
- expect(2);
+ expect(5);
var handle = '.ui-resizable-e', target = $('#resizable1').resizable({ handles: 'all' });
drag(handle, 50);
- equal( target.width(), 150, "compare width");
+ equal( target.width(), 150, "compare width" );
drag(handle, -50);
equal( target.width(), 100, "compare width" );
+
+ equal( target[0].style.height, "", "height should not be modified" );
+ equal( target[0].style.top, "", "top should not be modified" );
+ equal( target[0].style.left, "", "left should not be modified" );
});
test("w", function() {
- expect(2);
+ expect(4);
var handle = '.ui-resizable-w', target = $('#resizable1').resizable({ handles: 'all' });
@@ -87,10 +98,13 @@ test("w", function() {
drag(handle, 50);
equal( target.width(), 100, "compare width" );
+
+ equal( target[0].style.height, "", "height should not be modified" );
+ equal( target[0].style.top, "", "top should not be modified" );
});
test("ne", function() {
- expect(4);
+ expect(5);
var handle = '.ui-resizable-ne', target = $('#resizable1').css({ overflow: 'hidden' }).resizable({ handles: 'all' });
@@ -101,10 +115,12 @@ test("ne", function() {
drag(handle, 50, 50);
equal( target.width(), 100, "compare width" );
equal( target.height(), 100, "compare height" );
+
+ equal( target[0].style.left, "", "left should not be modified" );
});
test("se", function() {
- expect(4);
+ expect(6);
var handle = '.ui-resizable-se', target = $('#resizable1').resizable({ handles: 'all' });
@@ -115,10 +131,13 @@ test("se", function() {
drag(handle, -50, -50);
equal( target.width(), 100, "compare width" );
equal( target.height(), 100, "compare height" );
+
+ equal( target[0].style.top, "", "top should not be modified" );
+ equal( target[0].style.left, "", "left should not be modified" );
});
test("sw", function() {
- expect(4);
+ expect(5);
var handle = '.ui-resizable-sw', target = $('#resizable1').resizable({ handles: 'all' });
@@ -129,6 +148,8 @@ test("sw", function() {
drag(handle, 50, 50);
equal( target.width(), 100, "compare width" );
equal( target.height(), 100, "compare height" );
+
+ equal( target[0].style.top, "", "top should not be modified" );
});
test("nw", function() {
View
157 tests/unit/resizable/resizable_events.js
@@ -5,4 +5,161 @@
module("resizable: events");
+test("start", function() {
+
+ expect(5);
+
+ var count = 0,
+ handle = '.ui-resizable-se';
+ el = $("#resizable1").resizable({
+ handles: 'all',
+ start: function(event, ui) {
+ equal( ui.size.width, 100, "compare width" );
+ equal( ui.size.height, 100, "compare height" );
+ equal( ui.originalSize.width, 100, "compare original width" );
+ equal( ui.originalSize.height, 100, "compare original height" );
+ count++;
+ }
+ });
+
+ drag(handle, 50, 50);
+
+ equal(count, 1, "start callback should happen exactly once");
+
+});
+
+test("resize", function() {
+
+ expect(9);
+
+ var count = 0,
+ handle = '.ui-resizable-se';
+ el = $("#resizable1").resizable({
+ handles: 'all',
+ resize: function(event, ui) {
+ if (count === 0) {
+ equal( ui.size.width, 101, "compare width" );
+ equal( ui.size.height, 101, "compare height" );
+ equal( ui.originalSize.width, 100, "compare original width" );
+ equal( ui.originalSize.height, 100, "compare original height" );
+ }
+ else {
+ equal( ui.size.width, 150, "compare width" );
+ equal( ui.size.height, 150, "compare height" );
+ equal( ui.originalSize.width, 100, "compare original width" );
+ equal( ui.originalSize.height, 100, "compare original height" );
+ }
+ count++;
+ }
+ });
+
+ drag(handle, 50, 50);
+
+ equal(count, 2, "resize callback should happen exactly once per size adjustment");
+
+});
+
+test("resize (min/max dimensions)", function() {
+
+ expect(5);
+
+ var count = 0,
+ handle = '.ui-resizable-se';
+ el = $("#resizable1").resizable({
+ handles: 'all',
+ minWidth: 60,
+ minHeight: 60,
+ maxWidth: 100,
+ maxHeight: 100,
+ resize: function(event, ui) {
+ equal( ui.size.width, 60, "compare width" );
+ equal( ui.size.height, 60, "compare height" );
+ equal( ui.originalSize.width, 100, "compare original width" );
+ equal( ui.originalSize.height, 100, "compare original height" );
+ count++;
+ }
+ });
+
+ drag(handle, -50, -50);
+
+ equal(count, 1, "resize callback should happen exactly once per size adjustment");
+
+});
+
+test("resize (containment)", function() {
+
+ expect(5);
+
+ var count = 0,
+ handle = '.ui-resizable-se',
+ container = $('#resizable1').wrap('<div>').parent().css({
+ height: '100px',
+ width: '100px'
+ });
+
+ el = $("#resizable1").resizable({
+ handles: 'all',
+ containment: container,
+ resize: function(event, ui) {
+ equal( ui.size.width, 50, "compare width" );
+ equal( ui.size.height, 50, "compare height" );
+ equal( ui.originalSize.width, 100, "compare original width" );
+ equal( ui.originalSize.height, 100, "compare original height" );
+ count++;
+ }
+ });
+
+ drag(handle, -50, -50);
+
+ equal(count, 1, "resize callback should happen exactly once per size adjustment");
+
+});
+
+test("resize (grid)", function() {
+
+ expect(5);
+
+ var count = 0,
+ handle = '.ui-resizable-se';
+ el = $("#resizable1").resizable({
+ handles: 'all',
+ grid: 50,
+ resize: function(event, ui) {
+ equal( ui.size.width, 150, "compare width" );
+ equal( ui.size.height, 150, "compare height" );
+ equal( ui.originalSize.width, 100, "compare original width" );
+ equal( ui.originalSize.height, 100, "compare original height" );
+ count++;
+ },
+ });
+
+ drag(handle, 50, 50);
+
+ equal(count, 1, "resize callback should happen exactly once per grid-unit size adjustment");
+
+});
+
+test("stop", function() {
+
+ expect(5);
+
+ var count = 0,
+ handle = '.ui-resizable-se';
+ el = $("#resizable1").resizable({
+ handles: 'all',
+ stop: function(event, ui) {
+ equal( ui.size.width, 150, "compare width" );
+ equal( ui.size.height, 150, "compare height" );
+ equal( ui.originalSize.width, 100, "compare original width" );
+ equal( ui.originalSize.height, 100, "compare original height" );
+ count++;
+ }
+ });
+
+ drag(handle, 50, 50);
+
+ equal(count, 1, "stop callback should happen exactly once");
+
+});
+
})(jQuery);
View
36 ui/jquery.ui.resizable.js
@@ -277,7 +277,10 @@ $.widget("ui.resizable", $.ui.mouse, {
//Increase performance, avoid regex
var el = this.helper, o = this.options, props = {},
- that = this, smp = this.originalMousePosition, a = this.axis;
+ that = this, smp = this.originalMousePosition, a = this.axis,
+ prevTop = this.position.top, prevLeft = this.position.left,
+ prevWidth = this.size.width, prevHeight = this.size.height,
+ elemResized = false;
var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
var trigger = this._change[a];
@@ -293,21 +296,36 @@ $.widget("ui.resizable", $.ui.mouse, {
data = this._respectSize(data, event);
+ this._updateCache(data);
+
// plugins callbacks need to be called first
this._propagate("resize", event);
- el.css({
- top: this.position.top + "px", left: this.position.left + "px",
- width: this.size.width + "px", height: this.size.height + "px"
- });
+ if (this.position.top !== prevTop) {
+ props.top = this.position.top + "px";
+ elemResized = true;
+ }
+ if (this.position.left !== prevLeft) {
+ props.left = this.position.left + "px";
+ elemResized = true;
+ }
+ if (this.size.width !== prevWidth) {
+ props.width = this.size.width + "px";
+ elemResized = true;
+ }
+ if (this.size.height !== prevHeight) {
+ props.height = this.size.height + "px";
+ elemResized = true;
+ }
+ el.css(props);
if (!this._helper && this._proportionallyResizeElements.length)
this._proportionallyResize();
- this._updateCache(data);
-
- // calling the user callback at the end
- this._trigger('resize', event, this.ui());
+ // Call the user callback if the element was resized
+ if (elemResized) {
+ this._trigger('resize', event, this.ui());
+ }
return false;
},
Something went wrong with that request. Please try again.