define( [ "qunit", "jquery", "lib/helper", "./helper", "ui/widgets/draggable", "ui/widgets/droppable", "ui/widgets/sortable" ], function( QUnit, $, helper, testHelper ) { "use strict"; QUnit.module( "draggable: options", { afterEach: helper.moduleAfterEach } ); // TODO: This doesn't actually test whether append happened, possibly remove QUnit.test( "{ appendTo: 'parent' }, default, no clone", function( assert ) { assert.expect( 4 ); var element = $( "#draggable2" ).draggable( { appendTo: "parent" } ); testHelper.shouldMove( assert, element, "absolute appendTo: parent" ); element = $( "#draggable1" ).draggable( { appendTo: "parent" } ); testHelper.shouldMove( assert, element, "relative appendTo: parent" ); } ); // TODO: This doesn't actually test whether append happened, possibly remove QUnit.test( "{ appendTo: Element }, no clone", function( assert ) { assert.expect( 4 ); var element = $( "#draggable2" ).draggable( { appendTo: $( "#draggable2" ).parent()[ 0 ] } ); testHelper.shouldMove( assert, element, "absolute appendTo: Element" ); element = $( "#draggable1" ).draggable( { appendTo: $( "#draggable2" ).parent()[ 0 ] } ); testHelper.shouldMove( assert, element, "relative appendTo: Element" ); } ); // TODO: This doesn't actually test whether append happened, possibly remove QUnit.test( "{ appendTo: Selector }, no clone", function( assert ) { assert.expect( 4 ); var element = $( "#draggable2" ).draggable( { appendTo: "#main" } ); testHelper.shouldMove( assert, element, "absolute appendTo: Selector" ); element = $( "#draggable1" ).draggable( { appendTo: "#main" } ); testHelper.shouldMove( assert, element, "relative appendTo: Selector" ); } ); QUnit.test( "{ appendTo: 'parent' }, default", function( assert ) { assert.expect( 2 ); var element = $( "#draggable1" ).draggable(); testHelper.trackAppendedParent( element ); assert.equal( element.draggable( "option", "appendTo" ), "parent" ); testHelper.move( element, 1, 1 ); assert.equal( element.data( "last_dragged_parent" ), $( "#main" )[ 0 ] ); } ); QUnit.test( "{ appendTo: Element }", function( assert ) { assert.expect( 1 ); var appendTo = $( "#draggable2" ).parent()[ 0 ], element = $( "#draggable1" ).draggable( { appendTo: appendTo } ); testHelper.trackAppendedParent( element ); testHelper.move( element, 1, 1 ); assert.equal( element.data( "last_dragged_parent" ), appendTo ); } ); QUnit.test( "{ appendTo: jQuery }", function( assert ) { assert.expect( 1 ); var appendTo = $( "#draggable2" ).parent(), element = $( "#draggable1" ).draggable( { appendTo: appendTo } ); testHelper.trackAppendedParent( element ); testHelper.move( element, 1, 1 ); assert.equal( element.data( "last_dragged_parent" ), appendTo[ 0 ] ); } ); QUnit.test( "{ appendTo: Selector }", function( assert ) { assert.expect( 1 ); var appendTo = "#main", element = $( "#draggable1" ).draggable( { appendTo: appendTo } ); testHelper.trackAppendedParent( element ); testHelper.move( element, 1, 1 ); assert.equal( element.data( "last_dragged_parent" ), $( appendTo )[ 0 ] ); } ); QUnit.test( "appendTo, default, switching after initialization", function( assert ) { assert.expect( 2 ); var element = $( "#draggable1" ).draggable( { helper: "clone" } ); testHelper.trackAppendedParent( element ); // Move and make sure element was appended to fixture testHelper.move( element, 1, 1 ); assert.equal( element.data( "last_dragged_parent" ), $( "#main" )[ 0 ] ); // Move and make sure element was appended to main element.draggable( "option", "appendTo", $( "#qunit-fixture" ) ); testHelper.move( element, 2, 2 ); assert.equal( element.data( "last_dragged_parent" ), $( "#qunit-fixture" )[ 0 ] ); } ); QUnit.test( "{ axis: false }, default", function( assert ) { assert.expect( 2 ); var element = $( "#draggable2" ).draggable( { axis: false } ); testHelper.shouldMove( assert, element, "axis: false" ); } ); QUnit.test( "{ axis: 'x' }", function( assert ) { assert.expect( 2 ); var element = $( "#draggable2" ).draggable( { axis: "x" } ); testHelper.testDrag( assert, element, element, 50, 50, 50, 0, "axis: x" ); } ); QUnit.test( "{ axis: 'y' }", function( assert ) { assert.expect( 2 ); var element = $( "#draggable2" ).draggable( { axis: "y" } ); testHelper.testDrag( assert, element, element, 50, 50, 0, 50, "axis: y" ); } ); QUnit.test( "{ axis: ? }, unexpected", function( assert ) { var element, unexpected = { "true": true, "{}": {}, "[]": [], "null": null, "undefined": undefined, "function() {}": function() {} }; assert.expect( 12 ); $.each( unexpected, function( key, val ) { element = $( "#draggable2" ).draggable( { axis: val } ); testHelper.shouldMove( assert, element, "axis: " + key ); element.draggable( "destroy" ); } ); } ); QUnit.test( "axis, default, switching after initialization", function( assert ) { assert.expect( 6 ); var element = $( "#draggable1" ).draggable( { axis: false } ); // Any Direction testHelper.shouldMove( assert, element, "axis: default" ); // Only horizontal element.draggable( "option", "axis", "x" ); testHelper.testDrag( assert, element, element, 50, 50, 50, 0, "axis: x as option" ); // Vertical only element.draggable( "option", "axis", "y" ); testHelper.testDrag( assert, element, element, 50, 50, 0, 50, "axis: y as option" ); } ); QUnit.test( "{ cancel: 'input,textarea,button,select,option' }, default", function( assert ) { assert.expect( 4 ); $( "
" ).appendTo( "#qunit-fixture" ); var element = $( "#draggable-option-cancel-default" ).draggable( { cancel: "input,textarea,button,select,option" } ); testHelper.shouldMove( assert, element, "cancel: default, element dragged" ); element.draggable( "destroy" ); element = $( "#draggable-option-cancel-default" ).draggable( { cancel: "input,textarea,button,select,option" } ); testHelper.shouldNotDrag( assert, element, "cancel: default, input dragged", "#draggable-option-cancel-default input" ); element.draggable( "destroy" ); } ); QUnit.test( "{ cancel: 'span' }", function( assert ) { assert.expect( 4 ); var element = $( "#draggable2" ).draggable(); testHelper.shouldMove( assert, element, "cancel: default, span dragged", "#draggable2 span" ); element.draggable( "destroy" ); element = $( "#draggable2" ).draggable( { cancel: "span" } ); testHelper.shouldNotDrag( assert, element, "cancel: span, span dragged", "#draggable2 span" ); } ); QUnit.test( "{ cancel: ? }, unexpected", function( assert ) { assert.expect( 12 ); var element, unexpected = { "true": true, "false": false, "{}": {}, "[]": [], "null": null, "undefined": undefined }; $.each( unexpected, function( key, val ) { element = $( "#draggable2" ).draggable( { cancel: val } ); testHelper.shouldMove( assert, 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 ); testHelper.shouldMove( assert, element, "drag span child", "#draggable2 span" ); testHelper.shouldNotDrag( assert, $( "#draggable2 span a" ), "drag span a" ); testHelper.shouldNotDrag( assert, $( "#wrapping a" ), "drag wrapping a" ); $( "#draggable2" ).draggable( "option", "cancel", "span > a" ); $( "#draggable2" ).find( "a" ).append( "" ); testHelper.shouldMove( assert, element, "drag span child", $( "#draggable2 span a" ).last() ); testHelper.shouldNotDrag( assert, $( "#draggable2 span a" ).first(), "drag span a first child" ); }); */ QUnit.test( "cancelement, default, switching after initialization", function( assert ) { assert.expect( 6 ); $( "" ).appendTo( "#qunit-fixture" ); var input = $( "#draggable-option-cancel-default input" ), element = $( "#draggable-option-cancel-default" ).draggable(); testHelper.shouldNotDrag( assert, element, "cancel: default, input dragged", input ); element.draggable( "option", "cancel", "textarea" ); testHelper.shouldMove( assert, element, "cancel: textarea, input dragged", input ); element.draggable( "option", "cancel", "input" ); testHelper.shouldNotDrag( assert, element, "cancel: input, input dragged", input ); } ); QUnit.test( "connectToSortable, dragging out of a sortable", function( assert ) { assert.expect( 5 ); var sortItem, dragHelper, result, 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 result = ui.helper.offset(); // Support: Chrome <=45 - 73+ // In recent Chrome these values differ a little. assert.ok( Math.abs( result.top - offsetExpected.top ) < 0.25, "draggable offset is within 0.25 of expected" ); assert.ok( Math.abs( result.left - offsetExpected.left ) < 0.25, "draggable offset is within 0.25 of expected" ); // Http://bugs.jqueryui.com/ticket/7734 // HTML IDs are removed when dragging to a Sortable assert.equal( sortItem[ 0 ], dragHelper[ 0 ], "both have the same helper" ); assert.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 assert.equal( sortable.sortable( "option", "revert" ), 100, "sortable revert behavior is preserved" ); } ); element.simulate( "drag", { dx: dx, dy: dy } ); // Cleanup element.stop( true ); } ); QUnit.test( "connectToSortable, dragging clone into sortable", function( assert ) { var ready = assert.async(); assert.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 assert.deepEqual( ui.helper.offset(), offsetSortable, "sortable offset is correct" ); assert.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 assert.deepEqual( ui.item.offset(), offsetPlaceholder, "offset eventually equals placeholder" ); ready(); } ); element.simulate( "drag", { x: offsetSortable.left + 1, y: offsetSortable.top + 1, moves: 1 } ); } ); QUnit.test( "connectToSortable, dragging multiple elements in and out of sortable", function( assert ) { assert.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 ) { assert.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 } ); } ); QUnit.test( "connectToSortable, dragging through one sortable to a second", function( assert ) { assert.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() { assert.ok( true, "second sortable is updated" ); } ); $( sortable2 ).one( "sortover", function() { overCount++; } ); $( sortable2 ).one( "sortstop", function() { assert.equal( overCount, 2, "went over both sortables" ); } ); element.simulate( "drag", dragParams ); } ); QUnit.test( "connectToSortable, dragging through a sortable", function( assert ) { assert.expect( 1 ); var draggable = $( "#draggableSortable" ).draggable( { scroll: false, connectToSortable: "#sortable2" } ), sortable = $( "#sortable2" ).sortable(), sortableOffset = sortable.offset(); // Http://bugs.jqueryui.com/ticket/10669 // Draggable: Position issue with connectToSortable draggable.one( "dragstop", function() { assert.equal( draggable.parent().attr( "id" ), "sortable", "restored draggable to original parent" ); } ); draggable.simulate( "drag", { x: sortableOffset.left + 25, y: sortableOffset.top + sortable.outerHeight() + 400, moves: 20 } ); } ); QUnit.test( "{ containment: Element }", function( assert ) { assert.expect( 1 ); var offsetAfter, element = $( "#draggable1" ).draggable( { containment: $( "#draggable1" ).parent()[ 0 ] } ), p = element.parent(), po = p.offset(), expected = { left: po.left + testHelper.border( p, "left" ) + testHelper.margin( element, "left" ), top: po.top + testHelper.border( p, "top" ) + testHelper.margin( element, "top" ) }; element.simulate( "drag", { dx: -100, dy: -100 } ); offsetAfter = element.offset(); assert.deepEqual( offsetAfter, expected, "compare offset to parent" ); } ); QUnit.test( "{ containment: Selector }", function( assert ) { assert.expect( 1 ); var offsetAfter, element = $( "#draggable1" ).draggable( { containment: $( "#qunit-fixture" ) } ), p = element.parent(), po = p.offset(), expected = { left: po.left + testHelper.border( p, "left" ) + testHelper.margin( element, "left" ), top: po.top + testHelper.border( p, "top" ) + testHelper.margin( element, "top" ) }; element.simulate( "drag", { dx: -100, dy: -100 } ); offsetAfter = element.offset(); assert.deepEqual( offsetAfter, expected, "compare offset to parent" ); } ); QUnit.test( "{ containment: [x1, y1, x2, y2] }", function( assert ) { assert.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 ] ); testHelper.testDrag( assert, element, element, -100, -100, 0, 0, "containment: [x1, y1, x2, y2]" ); } ); QUnit.test( "{ containment: 'parent' }, relative", function( assert ) { assert.expect( 1 ); var offsetAfter, element = $( "#draggable1" ).draggable( { containment: "parent" } ), p = element.parent(), po = p.offset(), expected = { left: po.left + testHelper.border( p, "left" ) + testHelper.margin( element, "left" ), top: po.top + testHelper.border( p, "top" ) + testHelper.margin( element, "top" ) }; element.simulate( "drag", { dx: -100, dy: -100 } ); offsetAfter = element.offset(); assert.deepEqual( offsetAfter, expected, "compare offset to parent" ); } ); QUnit.test( "{ containment: 'parent' }, absolute", function( assert ) { assert.expect( 1 ); var offsetAfter, element = $( "#draggable2" ).draggable( { containment: "parent" } ), p = element.parent(), po = p.offset(), expected = { left: po.left + testHelper.border( p, "left" ) + testHelper.margin( element, "left" ), top: po.top + testHelper.border( p, "top" ) + testHelper.margin( element, "top" ) }; element.simulate( "drag", { dx: -100, dy: -100 } ); offsetAfter = element.offset(); assert.deepEqual( offsetAfter, expected, "compare offset to parent" ); } ); QUnit.test( "containment, account for border", function( assert ) { assert.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 = testHelper.border( parent, "bottom" ), parentBorderRight = testHelper.border( parent, "right" ); el.css( { height: "5px", width: "5px" } ).draggable( { containment: "parent", scroll: false } ); el.simulate( "drag", { dx: 100, dy: 100 } ); assert.close( el.offset().top, parentBottom - parentBorderBottom - el.height(), 1, "The draggable should be on top of its parent's bottom border" ); assert.close( 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 QUnit.test( "containment, element cant be pulled out of container", function( assert ) { assert.expect( 1 ); var offsetBefore, parent = $( "