(function( $ ) { module( "draggable: options" ); // TODO: This doesn't actually test whether append happened, possibly remove test( "{ appendTo: 'parent' }, default, no clone", function() { expect( 4 ); var element = $( "#draggable2" ).draggable({ appendTo: "parent" }); TestHelpers.draggable.shouldMove( element, "absolute appendTo: parent" ); element = $( "#draggable1" ).draggable({ appendTo: "parent" }); TestHelpers.draggable.shouldMove( element, "relative appendTo: parent" ); }); // TODO: This doesn't actually test whether append happened, possibly remove test( "{ appendTo: Element }, no clone", function() { expect( 4 ); var element = $( "#draggable2" ).draggable({ appendTo: $( "#draggable2" ).parent()[ 0 ] }); TestHelpers.draggable.shouldMove( element, "absolute appendTo: Element" ); element = $( "#draggable1" ).draggable({ appendTo: $( "#draggable2" ).parent()[ 0 ] }); TestHelpers.draggable.shouldMove( element, "relative appendTo: Element" ); }); // TODO: This doesn't actually test whether append happened, possibly remove test( "{ appendTo: Selector }, no clone", function() { expect( 4 ); var element = $( "#draggable2" ).draggable({ appendTo: "#main" }); TestHelpers.draggable.shouldMove( element, "absolute appendTo: Selector" ); element = $( "#draggable1" ).draggable({ appendTo: "#main" }); TestHelpers.draggable.shouldMove( element, "relative appendTo: Selector" ); }); test( "{ appendTo: 'parent' }, default", function() { expect( 2 ); var element = $( "#draggable1" ).draggable(); TestHelpers.draggable.trackAppendedParent( element ); equal( element.draggable( "option", "appendTo" ), "parent" ); TestHelpers.draggable.move( element, 1, 1 ); equal( element.data( "last_dragged_parent" ), $( "#main" )[ 0 ] ); }); test( "{ appendTo: Element }", function() { expect( 1 ); var appendTo = $( "#draggable2" ).parent()[ 0 ], element = $( "#draggable1" ).draggable({ appendTo: appendTo }); TestHelpers.draggable.trackAppendedParent( element ); TestHelpers.draggable.move( element, 1, 1 ); equal( element.data( "last_dragged_parent" ), appendTo ); }); test( "{ appendTo: jQuery }", function() { expect( 1 ); var appendTo = $( "#draggable2" ).parent(), element = $( "#draggable1" ).draggable({ appendTo: appendTo }); TestHelpers.draggable.trackAppendedParent( element ); TestHelpers.draggable.move( element, 1, 1 ); equal( element.data( "last_dragged_parent" ), appendTo[ 0 ] ); }); test( "{ appendTo: Selector }", function() { expect( 1 ); var appendTo = "#main", element = $( "#draggable1" ).draggable({ appendTo: appendTo }); TestHelpers.draggable.trackAppendedParent( element ); TestHelpers.draggable.move( element, 1, 1 ); equal( element.data( "last_dragged_parent" ), $(appendTo)[ 0 ] ); }); test( "appendTo, default, switching after initialization", function() { expect( 2 ); var element = $( "#draggable1" ).draggable({ helper: "clone" }); TestHelpers.draggable.trackAppendedParent( element ); // Move and make sure element was appended to fixture TestHelpers.draggable.move( element, 1, 1 ); equal( element.data( "last_dragged_parent" ), $( "#main" )[ 0 ] ); // Move and make sure element was appended to main element.draggable( "option", "appendTo", $( "#qunit-fixture" ) ); TestHelpers.draggable.move( element, 2, 2 ); equal( element.data( "last_dragged_parent" ), $( "#qunit-fixture" )[ 0 ] ); }); test( "{ axis: false }, default", function() { expect( 2 ); var element = $( "#draggable2" ).draggable({ axis: false }); TestHelpers.draggable.shouldMove( element, "axis: false" ); }); test( "{ axis: 'x' }", function() { expect( 2 ); var element = $( "#draggable2" ).draggable({ axis: "x" }); TestHelpers.draggable.testDrag( element, element, 50, 50, 50, 0, "axis: x" ); }); test( "{ axis: 'y' }", function() { expect( 2 ); var element = $( "#draggable2" ).draggable({ axis: "y" }); TestHelpers.draggable.testDrag( element, element, 50, 50, 0, 50, "axis: y" ); }); test( "{ axis: ? }, unexpected", function() { var element, unexpected = { "true": true, "{}": {}, "[]": [], "null": null, "undefined": undefined, "function() {}": function() {} }; expect( 12 ); $.each(unexpected, function(key, val) { element = $( "#draggable2" ).draggable({ axis: val }); TestHelpers.draggable.shouldMove( element, "axis: " + key ); element.draggable( "destroy" ); }); }); test( "axis, default, switching after initialization", function() { expect( 6 ); var element = $( "#draggable1" ).draggable({ axis: false }); // Any Direction TestHelpers.draggable.shouldMove( element, "axis: default" ); // Only horizontal element.draggable( "option", "axis", "x" ); TestHelpers.draggable.testDrag( element, element, 50, 50, 50, 0, "axis: x as option" ); // Vertical only element.draggable( "option", "axis", "y" ); TestHelpers.draggable.testDrag( element, element, 50, 50, 0, 50, "axis: y as option" ); }); test( "{ cancel: 'input,textarea,button,select,option' }, default", function() { expect( 4 ); $( "
" ).appendTo( "#qunit-fixture" ); var element = $( "#draggable-option-cancel-default" ).draggable({ cancel: "input,textarea,button,select,option" }); TestHelpers.draggable.shouldMove( element, "cancel: default, element dragged" ); element.draggable( "destroy" ); element = $( "#draggable-option-cancel-default" ).draggable({ cancel: "input,textarea,button,select,option" }); TestHelpers.draggable.shouldNotDrag( element, "cancel: default, input dragged", "#draggable-option-cancel-default input" ); element.draggable( "destroy" ); }); test( "{ cancel: 'span' }", function() { expect( 4 ); var element = $( "#draggable2" ).draggable(); TestHelpers.draggable.shouldMove( element, "cancel: default, span dragged", "#draggable2 span" ); element.draggable( "destroy" ); element = $( "#draggable2" ).draggable({ cancel: "span" }); TestHelpers.draggable.shouldNotDrag( element, "cancel: span, span dragged", "#draggable2 span" ); }); test( "{ cancel: ? }, unexpected", function() { expect( 12 ); var element, unexpected = { "true": true, "false": false, "{}": {}, "[]": [], "null": null, "undefined": undefined }; $.each( unexpected, function( key, val ) { element = $( "#draggable2" ).draggable({ cancel: val }); TestHelpers.draggable.shouldMove( element, "cancel: " + key ); element.draggable( "destroy" ); }); }); /* test( "{ cancel: Selectors }, matching parent selector", function() { expect( 4 ); var element = $( "#draggable2" ).draggable({ cancel: "span a" }); $( "#qunit-fixture" ).append( "" ); element.find( "span" ).append( "" ); $( "#wrapping a" ).append( element ); TestHelpers.draggable.shouldMove( element, "drag span child", "#draggable2 span" ); TestHelpers.draggable.shouldNotDrag( $( "#draggable2 span a" ), "drag span a" ); TestHelpers.draggable.shouldNotDrag( $( "#wrapping a" ), "drag wrapping a" ); $( "#draggable2" ).draggable( "option", "cancel", "span > a" ); $( "#draggable2" ).find( "a" ).append( "" ); TestHelpers.draggable.shouldMove( element, "drag span child", $( "#draggable2 span a" ).last() ); TestHelpers.draggable.shouldNotDrag( $( "#draggable2 span a" ).first(), "drag span a first child" ); }); */ test( "cancelement, default, switching after initialization", function() { expect( 6 ); $( "" ).appendTo( "#qunit-fixture" ); var input = $( "#draggable-option-cancel-default input" ), element = $( "#draggable-option-cancel-default" ).draggable(); TestHelpers.draggable.shouldNotDrag( element, "cancel: default, input dragged", input ); element.draggable( "option", "cancel", "textarea" ); TestHelpers.draggable.shouldMove( element, "cancel: textarea, input dragged", input ); element.draggable( "option", "cancel", "input" ); TestHelpers.draggable.shouldNotDrag( element, "cancel: input, input dragged", input ); }); test( "connectToSortable, dragging out of a sortable", function() { expect( 4 ); var sortItem, dragHelper, element = $( "#draggableSortable" ).draggable({ scroll: false, connectToSortable: "#sortable" }), sortable = $( "#sortable" ).sortable({ revert: 100 }), dx = 50, dy = 50, offsetBefore = element.offset(), offsetExpected = { left: offsetBefore.left + dx, top: offsetBefore.top + dy }; $( sortable ).one( "sortstart", function( event, ui ) { sortItem = ui.item; }); $( element ).one( "drag", function( event, ui ) { dragHelper = ui.helper; }); $( element ).one( "dragstop", function( event, ui ) { // http://bugs.jqueryui.com/ticket/8809 // Position issue when connected to sortable deepEqual( ui.helper.offset(), offsetExpected, "draggable offset is correct" ); // http://bugs.jqueryui.com/ticket/7734 // HTML IDs are removed when dragging to a Sortable equal( sortItem[ 0 ], dragHelper[ 0 ], "both have the same helper" ); equal( sortItem.attr( "id" ), dragHelper.attr( "id" ), "both have the same id" ); // http://bugs.jqueryui.com/ticket/9481 // connectToSortable causes sortable revert to fail on second attempt equal( sortable.sortable( "option", "revert" ), 100, "sortable revert behavior is preserved" ); }); element.simulate( "drag", { dx: dx, dy: dy }); }); asyncTest( "connectToSortable, dragging clone into sortable", function() { expect( 3 ); var offsetPlaceholder, element = $( "#draggableSortableClone" ).draggable({ scroll: false, connectToSortable: "#sortable", helper: "clone" }), sortable = $( "#sortable" ).sortable({ revert: 100 }), offsetSortable = sortable.offset(); $( sortable ).one( "sort", function( event, ui ) { offsetPlaceholder = ui.placeholder.offset(); // http://bugs.jqueryui.com/ticket/8809 // Position issue when connected to sortable deepEqual( ui.helper.offset(), offsetSortable, "sortable offset is correct" ); notDeepEqual( ui.helper.offset(), offsetPlaceholder, "offset not equal to placeholder" ); }); $( sortable ).one( "sortstop", function( event, ui ) { // http://bugs.jqueryui.com/ticket/9675 // Animation issue with revert and connectToSortable deepEqual( ui.item.offset(), offsetPlaceholder, "offset eventually equals placeholder" ); start(); }); element.simulate( "drag", { x: offsetSortable.left + 1, y: offsetSortable.top + 1, moves: 1 }); }); test( "connectToSortable, dragging multiple elements in and out of sortable", function() { expect( 1 ); var element = $( "#draggableSortableClone" ).draggable({ scroll: false, connectToSortable: "#sortable", helper: "clone" }), element2 = $( "#draggableSortable" ).draggable({ scroll: false, connectToSortable: "#sortable" }), sortable = $( "#sortable" ).sortable({ revert: false }), sortableOffset = sortable.offset(); // Move element into sortable element.simulate( "drag", { x: sortableOffset.left + 1, y: sortableOffset.top + 1, moves: 10 }); // Move element in sortable out element2.simulate( "drag", { dx: 200, dy: 200, moves: 10 }); // http://bugs.jqueryui.com/ticket/9675 // Animation issue with revert and connectToSortable sortable.one( "sortstop", function( event, ui ) { ok( !$.contains( document, ui.placeholder[ 0 ] ), "placeholder was removed" ); }); // Move the clone of the first element back out $( "#sortable .sortable2Item" ).simulate( "drag", { dx: 200, dy: 200, moves: 10 }); }); test( "connectToSortable, dragging through one sortable to a second", function() { expect( 2 ); var overCount = 0, element = $( "#draggableSortable" ).draggable({ scroll: false, connectToSortable: ".sortable" }), delta = 200, sortable = $( "#sortable" ).sortable({ revert: false }), sortable2 = $( "#sortable2" ).sortable({ revert: false }), sortable2Offset = sortable2.offset(), dragParams = { x: sortable2Offset.left + 25, y: sortable2Offset.top + sortable.outerHeight() + delta, moves: 10 }; $( sortable ).one( "sortover", function() { overCount++; sortable2.css( "top", "+=" + delta ); }); $( sortable2 ).on( "sortupdate", function() { ok( true, "second sortable is updated" ); }); $( sortable2 ).one( "sortover", function() { overCount++; }); $( sortable2 ).one( "sortstop", function() { equal( overCount, 2, "went over both sortables" ); }); element.simulate( "drag", dragParams ); }); test( "{ containment: Element }", function() { expect( 1 ); var offsetAfter, element = $( "#draggable1" ).draggable({ containment: $( "#draggable1" ).parent()[ 0 ] }), p = element.parent(), po = p.offset(), expected = { left: po.left + TestHelpers.draggable.border( p, "left" ) + TestHelpers.draggable.margin( element, "left" ), top: po.top + TestHelpers.draggable.border( p, "top" ) + TestHelpers.draggable.margin( element, "top" ) }; element.simulate( "drag", { dx: -100, dy: -100 }); offsetAfter = element.offset(); deepEqual( offsetAfter, expected, "compare offset to parent" ); }); test( "{ containment: Selector }", function() { expect( 1 ); var offsetAfter, element = $( "#draggable1" ).draggable({ containment: $( "#qunit-fixture" ) }), p = element.parent(), po = p.offset(), expected = { left: po.left + TestHelpers.draggable.border( p, "left" ) + TestHelpers.draggable.margin( element, "left" ), top: po.top + TestHelpers.draggable.border( p, "top" ) + TestHelpers.draggable.margin( element, "top" ) }; element.simulate( "drag", { dx: -100, dy: -100 }); offsetAfter = element.offset(); deepEqual( offsetAfter, expected, "compare offset to parent" ); }); test( "{ containment: [x1, y1, x2, y2] }", function() { expect( 2 ); var element = $( "#draggable1" ).draggable(), eo = element.offset(); element.draggable( "option", "containment", [ eo.left, eo.top, eo.left + element.width() + 5, eo.top + element.height() + 5 ] ); TestHelpers.draggable.testDrag( element, element, -100, -100, 0, 0, "containment: [x1, y1, x2, y2]" ); }); test( "{ containment: 'parent' }, relative", function() { expect( 1 ); var offsetAfter, element = $( "#draggable1" ).draggable({ containment: "parent" }), p = element.parent(), po = p.offset(), expected = { left: po.left + TestHelpers.draggable.border( p, "left" ) + TestHelpers.draggable.margin( element, "left" ), top: po.top + TestHelpers.draggable.border( p, "top" ) + TestHelpers.draggable.margin( element, "top" ) }; element.simulate( "drag", { dx: -100, dy: -100 }); offsetAfter = element.offset(); deepEqual( offsetAfter, expected, "compare offset to parent" ); }); test( "{ containment: 'parent' }, absolute", function() { expect( 1 ); var offsetAfter, element = $( "#draggable2" ).draggable({ containment: "parent" }), p = element.parent(), po = p.offset(), expected = { left: po.left + TestHelpers.draggable.border( p, "left" ) + TestHelpers.draggable.margin( element, "left" ), top: po.top + TestHelpers.draggable.border( p, "top" ) + TestHelpers.draggable.margin( element, "top" ) }; element.simulate( "drag", { dx: -100, dy: -100 }); offsetAfter = element.offset(); deepEqual( offsetAfter, expected, "compare offset to parent" ); }); test( "containment, account for border", function() { expect( 2 ); var el = $( "#draggable1" ).appendTo( "#scrollParent" ), parent = el.parent().css({ height: "100px", width: "100px", borderStyle: "solid", borderWidth: "5px 10px 15px 20px" }), parentBottom = parent.offset().top + parent.outerHeight(), parentRight = parent.offset().left + parent.outerWidth(), parentBorderBottom = TestHelpers.draggable.border( parent, "bottom" ), parentBorderRight = TestHelpers.draggable.border( parent, "right" ); el.css({ height: "5px", width: "5px" }).draggable({ containment: "parent", scroll: false }); el.simulate( "drag", { dx: 100, dy: 100 }); closeEnough( el.offset().top, parentBottom - parentBorderBottom - el.height(), 1, "The draggable should be on top of its parent's bottom border" ); closeEnough( el.offset().left, parentRight - parentBorderRight - el.width(), 1, "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 = $( "