From 48ea2aadad11938cc5ddbd9a340c4ca1c997550d Mon Sep 17 00:00:00 2001 From: Mike Sherov Date: Sun, 17 Aug 2014 14:38:05 -0400 Subject: [PATCH] Draggable: Ensure overflow:visible containments are correctly measured Fixes #7016 --- tests/unit/draggable/draggable_options.js | 30 +++++++++++++++++++++++ ui/draggable.js | 18 +++++++++++--- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/tests/unit/draggable/draggable_options.js b/tests/unit/draggable/draggable_options.js index 03a9bf355..1b7dc2b3b 100644 --- a/tests/unit/draggable/draggable_options.js +++ b/tests/unit/draggable/draggable_options.js @@ -374,6 +374,36 @@ test( "containment, account for border", function() { "The draggable should be to the right of its parent's right border" ); }); +// http://bugs.jqueryui.com/ticket/7016 +// draggable can be pulled out of containment in Chrome and IE8 +test( "containment, element cant be pulled out of container", function() { + expect( 1 ); + + var offsetBefore, + parent = $( "
").css({ width: 200, height: 200 }).appendTo( "#qunit-fixture" ), + element = $( "#draggable1" ).appendTo( parent ); + + element + .css({ + height: "5px", + width: "5px" + }) + .draggable({ containment: "parent" }) + .simulate( "drag", { + dx: 200, + dy: 200 + }); + + offsetBefore = element.offset(); + + element.simulate( "drag", { + dx: 200, + dy: 200 + }); + + deepEqual( element.offset(), offsetBefore, "The draggable should not move past bottom right edge" ); +}); + test( "containment, default, switching after initialization", function() { expect( 8 ); diff --git a/ui/draggable.js b/ui/draggable.js index 98f065efb..68222b0d5 100644 --- a/ui/draggable.js +++ b/ui/draggable.js @@ -439,7 +439,7 @@ $.widget("ui.draggable", $.ui.mouse, { _setContainment: function() { - var over, c, ce, + var isUserScrollable, c, ce, o = this.options, document = this.document[ 0 ]; @@ -486,13 +486,23 @@ $.widget("ui.draggable", $.ui.mouse, { return; } - over = c.css( "overflow" ) !== "hidden"; + isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) ); this.containment = [ ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ), - ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - this.helperProportions.width - this.margins.left - this.margins.right, - ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - this.helperProportions.height - this.margins.top - this.margins.bottom + ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - + ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - + ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - + this.helperProportions.width - + this.margins.left - + this.margins.right, + ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - + ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - + ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - + this.helperProportions.height - + this.margins.top - + this.margins.bottom ]; this.relativeContainer = c; }, -- 2.39.5