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( "
" );
- $( "#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( "" );
+ $( "#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;
}
}