});
});
-test( "#9315: Draggable: jumps down with offset of scrollbar", function() {
+test( "#9315: jumps down with offset of scrollbar", function() {
expect( 2 );
var element = $( "#draggable2" ).draggable({
});
});
+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,
+
+ // 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" );
+ }
+ });
+
+ $( "#o_9379" ).css( "overflow", "auto" );
+
+ element.simulate( "drag", {
+ dy: delta,
+ dx: delta,
+ moves: moves
+ });
+});
+
test( "#5727: draggable from iframe" , function() {
expect( 1 );
test( "containment, default, switching after initialization", function() {
expect( 6 );
- var element = $( "#draggable1" ).draggable({ containment: false });
+ var element = $( "#draggable1" ).draggable({ containment: false, scroll: false });
TestHelpers.draggable.testDrag( element, element, -100, -100, -100, -100, "containment: default" );
scroll: false
});
- if ( scrollElements.length === 1 && scrollElements[ 1 ] === "#scrollParent" ) {
+ if ( scrollElements.length === 1 && scrollElements[ 0 ] === "#scrollParent" ) {
TestHelpers.draggable.setScrollable( "#main", false );
TestHelpers.draggable.setScrollable( "#scrollParent", true );
}
test( "#6817: auto scroll goes double distance when dragging", function() {
expect( 2 );
+ TestHelpers.draggable.restoreScroll( document );
+
var offsetBefore,
distance = 10,
viewportHeight = $( window ).height(),
snapTolerance = 15,
element = $( "#draggable1" ).draggable({
snap: true,
+ scroll: false,
snapMode: "both",
snapTolerance: snapTolerance
}),
snapTolerance = 15,
element = $( "#draggable1" ).draggable({
snap: true,
+ scroll: false,
snapMode: "both",
snapTolerance: snapTolerance,
start: function() {
})( $.fn.focus ),
scrollParent: function() {
- var scrollParent;
- if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
- scrollParent = this.parents().filter(function() {
- return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
- }).eq(0);
- } else {
- scrollParent = this.parents().filter(function() {
- return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
- }).eq(0);
- }
+ var position = this.css( "position" ),
+ excludeStaticParent = position === "absolute",
+ 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" ) );
+ }).eq( 0 );
- return ( /fixed/ ).test( this.css( "position") ) || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent;
+ return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent;
},
uniqueId: (function() {
}
},
+ _isRootNode: function( element ) {
+ return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
+ },
+
_getParentOffset: function() {
//Get the offsetParent and cache its position
po.top += this.scrollParent.scrollTop();
}
- //This needs to be actually done for all browsers, since pageX/pageY includes this information
- //Ugly IE fix
- if((this.offsetParent[0] === document.body) ||
- (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
+ if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
po = { top: 0, left: 0 };
}
},
_getRelativeOffset: function() {
-
- if(this.cssPosition === "relative") {
- var p = this.element.position();
- return {
- top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
- left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
- };
- } else {
+ if ( this.cssPosition !== "relative" ) {
return { top: 0, left: 0 };
}
+ var p = this.element.position(),
+ scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
+
+ return {
+ top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
+ left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
+ };
+
},
_cacheMargins: function() {
}
var mod = d === "absolute" ? 1 : -1,
- document = this.document[ 0 ],
- useOffsetParent = this.cssPosition === "absolute" && ( this.scrollParent[ 0 ] === document || !$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ),
- scroll = useOffsetParent ? this.offsetParent : this.scrollParent,
- // we need to test if offsetParent was used here because Blink incorrectly reports a 0 scrollTop
- // on document.documentElement when the page is scrolled. Checking for offsetParent normalizes
- // this across browsers. Blink bug: https://code.google.com/p/chromium/issues/detail?id=157855
- scrollIsRootNode = useOffsetParent && ( /(html|body)/i ).test( scroll[ 0 ].nodeName );
-
- //Cache the scroll
- if (!this.offset.scroll) {
- this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
- }
+ scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
return {
top: (
pos.top + // The absolute mouse position
this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border)
- ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)
+ ( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)
),
left: (
pos.left + // The absolute mouse position
this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border)
- ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : this.offset.scroll.left ) * mod)
+ ( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod)
)
};
var containment, co, top, left,
o = this.options,
- document = this.document[ 0 ],
- useOffsetParent = this.cssPosition === "absolute" && ( this.scrollParent[ 0 ] === document || !$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ),
- scroll = useOffsetParent ? this.offsetParent : this.scrollParent,
- // we need to test if offsetParent was used here because Blink incorrectly reports a 0 scrollTop
- // on document.documentElement when the page is scrolled. Checking for offsetParent normalizes
- // this across browsers. Blink bug: https://code.google.com/p/chromium/issues/detail?id=157855
- scrollIsRootNode = useOffsetParent && ( /(html|body)/i ).test( scroll[ 0 ].nodeName ),
+ scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
pageX = event.pageX,
pageY = event.pageY;
- //Cache the scroll
- if (!this.offset.scroll) {
- this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
+ // Cache the scroll
+ if ( !scrollIsRootNode || !this.offset.scroll ) {
+ this.offset.scroll = {
+ top: this.scrollParent.scrollTop(),
+ left: this.scrollParent.scrollLeft()
+ };
}
/*
this.offset.click.top - // Click offset (relative to the element)
this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent
this.offset.parent.top + // The offsetParent's offset without borders (offset + border)
- ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
+ ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
),
left: (
pageX - // The absolute mouse position
this.offset.click.left - // Click offset (relative to the element)
this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent
this.offset.parent.left + // The offsetParent's offset without borders (offset + border)
- ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
+ ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
)
};