Skip to content
Permalink
Browse files

Draggable: consider offsets from overflow:hidden parents

Developers can programmatically set scrollTop/Left on
draggable containers that are overflow:hidden. They must
be considered for positioning.

Fixes #10147
  • Loading branch information...
mikesherov committed Aug 10, 2014
1 parent 67e4b44 commit e9efbc222149ca7c7a5fef2c0fe28b7b1d9be698
Showing with 38 additions and 32 deletions.
  1. +36 −30 tests/unit/draggable/draggable_core.js
  2. +1 −1 tests/unit/draggable/draggable_options.js
  3. +1 −1 ui/draggable.js
@@ -185,38 +185,44 @@ 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( "<div id='o_9379'><div id='i_9379'></div><div id='d_9379'>a</div></div>" );
$( "#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" });

var moves = 3,
startValue = 0,
dragDelta = 20,
delta = 100,
$( [ "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( "<div id='outer'><div id='inner'></div><div id='dragged'>a</div></div>" );
$( "#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 );

// 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
});
});

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

0 comments on commit e9efbc2

Please sign in to comment.
You can’t perform that action at this time.