diff --git a/tests/unit/draggable/draggable_core.js b/tests/unit/draggable/draggable_core.js index dd526e5ec85..93c6e4080d1 100644 --- a/tests/unit/draggable/draggable_core.js +++ b/tests/unit/draggable/draggable_core.js @@ -174,7 +174,6 @@ test( "#5009: scroll not working with parent's position fixed", function() { } }); - TestHelpers.forceScrollableWindow(); $( "#wrapper" ).css( "position", "fixed" ); @@ -186,42 +185,48 @@ test( "#5009: scroll not working with parent's position fixed", function() { }); }); -test( "#9379: Draggable: position bug in scrollable div", function() { - expect( 2 ); - - $( "#qunit-fixture" ).html( "
a
" ); - $( "#i_9379" ).css({ position: "absolute", width: "500px", height: "500px" }); - $( "#o_9379" ).css({ position: "absolute", width: "300px", height: "300px" }); - $( "#d_9379" ).css({ width: "10px", height: "10px" }); +$( [ "hidden", "auto", "scroll" ] ).each(function() { + var overflow = this; + + // http://bugs.jqueryui.com/ticket/9379 - position bug in scrollable div + // http://bugs.jqueryui.com/ticket/10147 - Wrong position in a parent with "overflow: hidden" + test( "position in scrollable parent with overflow: " + overflow, function() { + expect( 2 ); + + $( "#qunit-fixture" ).html( "
a
" ); + $( "#inner" ).css({ position: "absolute", width: "500px", height: "500px" }); + $( "#outer" ).css({ position: "absolute", width: "300px", height: "300px" }); + $( "#dragged" ).css({ width: "10px", height: "10px" }); + + var moves = 3, + startValue = 0, + dragDelta = 20, + delta = 100, + + // we scroll after each drag event, so subtract 1 from number of moves for expected + expected = delta + ( ( moves - 1 ) * dragDelta ), + element = $( "#dragged" ).draggable({ + drag: function() { + startValue += dragDelta; + $( "#outer" ).scrollTop( startValue ).scrollLeft( startValue ); + }, + stop: function( event, ui ) { + equal( ui.position.left, expected, "left position is correct when grandparent is scrolled" ); + equal( ui.position.top, expected, "top position is correct when grandparent is scrolled" ); + } + }); + + $( "#outer" ).css( "overflow", overflow ); - var moves = 3, - startValue = 0, - dragDelta = 20, - delta = 100, - - // we scroll after each drag event, so subtract 1 from number of moves for expected - expected = delta + ( ( moves - 1 ) * dragDelta ), - element = $( "#d_9379" ).draggable({ - drag: function() { - startValue += dragDelta; - $( "#o_9379" ).scrollTop( startValue ).scrollLeft( startValue ); - }, - stop: function( event, ui ) { - equal( ui.position.left, expected, "left position is correct when grandparent is scrolled" ); - equal( ui.position.top, expected, "top position is correct when grandparent is scrolled" ); - } + element.simulate( "drag", { + dy: delta, + dx: delta, + moves: moves }); - - $( "#o_9379" ).css( "overflow", "auto" ); - - element.simulate( "drag", { - dy: delta, - dx: delta, - moves: moves }); }); -test( "#5727: draggable from iframe" , function() { +test( "#5727: draggable from iframe", function() { expect( 1 ); var iframeBody, draggable1, diff --git a/tests/unit/draggable/draggable_options.js b/tests/unit/draggable/draggable_options.js index 1a9d7892562..99fd608bfc6 100644 --- a/tests/unit/draggable/draggable_options.js +++ b/tests/unit/draggable/draggable_options.js @@ -361,7 +361,7 @@ test( "containment, account for border", function() { el.css({ height: "5px", width: "5px" - }).draggable({ containment: "parent" }); + }).draggable({ containment: "parent", scroll: false }); el.simulate( "drag", { dx: 100, @@ -878,6 +878,20 @@ test( "scroll, scrollSensitivity, and scrollSpeed", function() { TestHelpers.draggable.restoreScroll( document ); }); +test( "scroll ignores containers that are overflow: hidden", function() { + expect( 2 ); + + var element = $( "#draggable1" ).draggable({ scroll: true }).appendTo( "#scrollParent" ); + + element.simulate( "drag", { + dx: 1300, + dy: 1300 + }); + + equal( $( "#scrollParent" ).scrollTop(), 0, "container doesn't scroll vertically" ); + equal( $( "#scrollParent" ).scrollLeft(), 0, "container doesn't scroll horizontally" ); +}); + test( "#6817: auto scroll goes double distance when dragging", function() { expect( 2 ); diff --git a/tests/unit/draggable/draggable_test_helpers.js b/tests/unit/draggable/draggable_test_helpers.js index e27adbffae6..a0fdccfca38 100644 --- a/tests/unit/draggable/draggable_test_helpers.js +++ b/tests/unit/draggable/draggable_test_helpers.js @@ -110,7 +110,7 @@ TestHelpers.draggable = { el.draggable( "option", "helper", "clone" ); // Get what parent is at time of drag - el.bind( "drag", function(e,ui) { + el.bind( "drag", function(e, ui) { el.data( "last_dragged_parent", ui.helper.parent()[ 0 ] ); }); } diff --git a/ui/core.js b/ui/core.js index aa1ee0f3dbb..0bcb46aa7df 100644 --- a/ui/core.js +++ b/ui/core.js @@ -48,15 +48,16 @@ $.extend( $.ui, { // plugins $.fn.extend({ - scrollParent: function() { + scrollParent: function( includeHidden ) { var position = this.css( "position" ), excludeStaticParent = position === "absolute", + overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, scrollParent = this.parents().filter( function() { var parent = $( this ); if ( excludeStaticParent && parent.css( "position" ) === "static" ) { return false; } - return (/(auto|scroll)/).test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) ); + return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) ); }).eq( 0 ); return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent; diff --git a/ui/draggable.js b/ui/draggable.js index 700bb66b3ae..a6de2889cc3 100644 --- a/ui/draggable.js +++ b/ui/draggable.js @@ -161,7 +161,7 @@ $.widget("ui.draggable", $.ui.mouse, { //Store the helper's css position this.cssPosition = this.helper.css( "position" ); - this.scrollParent = this.helper.scrollParent(); + this.scrollParent = this.helper.scrollParent( true ); this.offsetParent = this.helper.offsetParent(); this.offsetParentCssPosition = this.offsetParent.css( "position" ); @@ -827,30 +827,35 @@ $.ui.plugin.add("draggable", "opacity", { $.ui.plugin.add("draggable", "scroll", { start: function( event, ui, i ) { - if ( i.scrollParent[ 0 ] !== i.document[ 0 ] && i.scrollParent[ 0 ].tagName !== "HTML" ) { - i.overflowOffset = i.scrollParent.offset(); + if ( !i.scrollParentNotHidden ) { + i.scrollParentNotHidden = i.helper.scrollParent( false ); + } + + if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) { + i.overflowOffset = i.scrollParentNotHidden.offset(); } }, drag: function( event, ui, i ) { var o = i.options, scrolled = false, + scrollParent = i.scrollParentNotHidden[ 0 ], document = i.document[ 0 ]; - if ( i.scrollParent[ 0 ] !== document && i.scrollParent[ 0 ].tagName !== "HTML" ) { - if (!o.axis || o.axis !== "x") { - if ((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { - i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; - } else if (event.pageY - i.overflowOffset.top < o.scrollSensitivity) { - i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; + if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) { + if ( !o.axis || o.axis !== "x" ) { + if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) { + scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed; + } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) { + scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed; } } - if (!o.axis || o.axis !== "y") { - if ((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { - i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; - } else if (event.pageX - i.overflowOffset.left < o.scrollSensitivity) { - i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; + if ( !o.axis || o.axis !== "y" ) { + if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) { + scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed; + } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) { + scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed; } }