6
// Draggable Test Helper Functions
8
var el, offsetBefore, offsetAfter, dragged;
10
var drag = function(handle, dx, dy) {
11
var element = el.data("draggable").element;
12
offsetBefore = el.offset();
13
$(handle).simulate("drag", {
17
dragged = { dx: dx, dy: dy };
18
offsetAfter = el.offset();
21
var moved = function (dx, dy, msg) {
22
msg = msg ? msg + "." : "";
23
var actual = { left: offsetAfter.left, top: offsetAfter.top };
24
var expected = { left: offsetBefore.left + dx, top: offsetBefore.top + dy };
25
compare2(actual, expected, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ' + msg);
28
function shouldmove(why) {
33
function shouldnotmove(why) {
38
var border = function(el, side) { return parseInt(el.css('border-' + side + '-width')); }
40
var margin = function(el, side) { return parseInt(el.css('margin-' + side)); }
45
test("init", function() {
48
el = $("#draggable1").draggable();
49
ok(true, '.draggable() called on element');
52
ok(true, '.draggable() called on empty collection');
54
$("<div/>").draggable();
55
ok(true, '.draggable() called on disconnected DOMElement');
57
$("<div/>").draggable().draggable("foo");
58
ok(true, 'arbitrary method called after init');
60
$("<div/>").draggable().data("foo.draggable");
61
ok(true, 'arbitrary option getter after init');
63
$("<div/>").draggable().data("foo.draggable", "bar");
64
ok(true, 'arbitrary option setter after init');
67
test("destroy", function() {
70
$("#draggable1").draggable().draggable("destroy");
71
ok(true, '.draggable("destroy") called on element');
73
$([]).draggable().draggable("destroy");
74
ok(true, '.draggable("destroy") called on empty collection');
76
$("<div/>").draggable().draggable("destroy");
77
ok(true, '.draggable("destroy") called on disconnected DOMElement');
79
$("<div/>").draggable().draggable("destroy").draggable("foo");
80
ok(true, 'arbitrary method called after destroy');
82
$("<div/>").draggable().draggable("destroy").data("foo.draggable");
83
ok(true, 'arbitrary option getter after destroy');
85
$("<div/>").draggable().draggable("destroy").data("foo.draggable", "bar");
86
ok(true, 'arbitrary option setter after destroy');
89
test("enable", function() {
91
el = $("#draggable2").draggable({ disabled: true });
92
shouldnotmove('.draggable({ disabled: true })');
93
el.draggable("enable");
94
shouldmove('.draggable("enable")');
95
equals(el.data("disabled.draggable"), false, "disabled.draggable getter");
97
el.draggable("destroy");
98
el.draggable({ disabled: true });
99
shouldnotmove('.draggable({ disabled: true })');
100
el.data("disabled.draggable", false);
101
equals(el.data("disabled.draggable"), false, "disabled.draggable setter");
102
shouldmove('.data("disabled.draggable", false)');
105
test("disable", function() {
107
el = $("#draggable2").draggable({ disabled: false });
108
shouldmove('.draggable({ disabled: false })');
109
el.draggable("disable");
110
shouldnotmove('.draggable("disable")');
111
equals(el.data("disabled.draggable"), true, "disabled.draggable getter");
113
el.draggable("destroy");
115
el.draggable({ disabled: false });
116
shouldmove('.draggable({ disabled: false })');
117
el.data("disabled.draggable", true);
118
equals(el.data("disabled.draggable"), true, "disabled.draggable setter");
119
shouldnotmove('.data("disabled.draggable", true)');
122
test("element types", function() {
123
var typeNames = ('p,h1,h2,h3,h4,h5,h6,blockquote,ol,ul,dl,div,form'
124
+ ',table,fieldset,address,ins,del,em,strong,q,cite,dfn,abbr'
125
+ ',acronym,code,samp,kbd,var,img,object,hr'
126
+ ',input,button,label,select,iframe').split(',');
128
$.each(typeNames, function(i) {
129
var typeName = typeNames[i];
130
el = $(document.createElement(typeName)).appendTo('body');
131
(typeName == 'table' && el.append("<tr><td>content</td></tr>"));
132
el.draggable({ cancel: '' });
134
moved(50, 50, "<" + typeName + ">");
135
el.draggable("destroy");
140
test("defaults", function() {
141
el = $("#draggable1").draggable();
142
equals(el.data("appendTo.draggable"), "parent", "appendTo");
143
equals(el.data("axis.draggable"), false, "axis");
144
equals(el.data("cancel.draggable"), ":input", "cancel");
145
equals(el.data("delay.draggable"), 0, "delay");
146
equals(el.data("disabled.draggable"), false, "disabled");
147
equals(el.data("distance.draggable"), 1, "distance");
148
equals(el.data("helper.draggable"), "original", "helper");
151
test("No options, relative", function() {
152
el = $("#draggable1").draggable();
157
test("No options, absolute", function() {
158
el = $("#draggable2").draggable();
163
module("draggable: Options");
165
test("{ axis: false }, default", function() {
166
el = $("#draggable2").draggable({ axis: false });
171
test("{ axis: 'x' }", function() {
172
el = $("#draggable2").draggable({ axis: "x" });
177
test("{ axis: 'y' }", function() {
178
el = $("#draggable2").draggable({ axis: "y" });
183
test("{ axis: ? }, unexpected", function() {
189
"undefined": undefined,
190
"function() {}": function() {}
192
$.each(unexpected, function(key, val) {
193
el = $("#draggable2").draggable({ axis: val });
195
moved(50, 50, "axis: " + key);
196
el.draggable("destroy");
200
test("{ cancel: 'span' }", function() {
201
el = $("#draggable2").draggable();
202
drag("#draggable2 span", 50, 50);
205
el.draggable("destroy");
207
el = $("#draggable2").draggable({ cancel: 'span' });
208
drag("#draggable2 span", 50, 50);
212
test("{ cancel: ? }, unexpected", function() {
219
"undefined": undefined,
220
"function() {return '';}": function() {return '';},
221
"function() {return true;}": function() {return true;},
222
"function() {return false;}": function() {return false;}
224
$.each(unexpected, function(key, val) {
225
el = $("#draggable2").draggable({ cancel: val });
227
var expected = [50, 50];
228
moved(expected[0], expected[1], "cancel: " + key);
229
el.draggable("destroy");
233
test("{ containment: 'parent' }, relative", function() {
234
el = $("#draggable1").draggable({ containment: 'parent' });
235
var p = el.parent(), po = p.offset();
236
drag(el, -100, -100);
238
left: po.left + border(p, 'left') + margin(el, 'left'),
239
top: po.top + border(p, 'top') + margin(el, 'top')
241
compare2(offsetAfter, expected, 'compare offset to parent');
244
test("{ containment: 'parent' }, absolute", function() {
245
el = $("#draggable2").draggable({ containment: 'parent' });
246
var p = el.parent(), po = p.offset();
247
drag(el, -100, -100);
249
left: po.left + border(p, 'left') + margin(el, 'left'),
250
top: po.top + border(p, 'top') + margin(el, 'top')
252
compare2(offsetAfter, expected, 'compare offset to parent');
255
test("{ cursor: 'move' }", function() {
257
function getCursor() { return $("body").css("cursor"); }
261
var expected = "move", actual, before, after;
263
el = $("#draggable2").draggable({
265
start: function(e, ui) {
266
actual = getCursor();
270
before = getCursor();
271
drag("#draggable2", -1, -1);
274
equals(actual, expected, "start callback: cursor '" + expected + "'");
275
equals(after, before, "after drag: cursor restored");
279
test("{ cursorAt: { left: -5, top: -5 } }", function() {
283
var dx = -3, dy = -3;
285
var cax = -5, cay = -5;
288
$("#draggable2").draggable({
289
cursorAt: { left: cax, top: cay },
290
drag: function(e, ui) {
291
actual = ui.absolutePosition;
294
var el = $("#draggable2").data("draggable").element;
296
var before = el.offset();
297
var pos = { clientX: before.left + ox, clientY: before.top + oy };
298
$("#draggable2").simulate("mousedown", pos);
299
pos = { clientX: pos.clientX + dx, clientY: pos.clientY + dy };
300
$(document).simulate("mousemove", pos);
301
$(document).simulate("mousemove", pos);
302
$("#draggable2").simulate("mouseup", pos);
304
left: before.left + ox - cax + dx,
305
top: before.top + oy - cay + dy
308
equals(actual.left, expected.left, "Absolute: -1px left");
309
equals(actual.top, expected.top, "Absolute: -1px top");
312
$("#draggable1").draggable({
313
cursorAt: { left: cax, top: cay },
314
drag: function(e, ui) {
315
actual = ui.absolutePosition;
318
var el = $("#draggable2").data("draggable").element;
320
var before = el.offset();
321
var pos = { clientX: before.left + ox, clientY: before.top + oy };
322
$("#draggable2").simulate("mousedown", pos);
323
pos = { clientX: pos.clientX + dx, clientY: pos.clientY + dy };
324
$(document).simulate("mousemove", pos);
325
$(document).simulate("mousemove", pos);
326
$("#draggable2").simulate("mouseup", pos);
328
left: before.left + ox - cax + dx,
329
top: before.top + oy - cay + dy
332
equals(actual.left, expected.left, "Relative: -1px left");
333
equals(actual.top, expected.top, "Relative: -1px top");
337
test("{ distance: 10 }", function() {
339
el = $("#draggable2").draggable({ distance: 10 });
341
moved(0, 0, 'distance not met');
344
moved(-10, -10, 'distance met');
347
moved(0, 0, 'distance not met');
351
test("{ grid: [50, 50] }, relative", function() {
352
el = $("#draggable1").draggable({ grid: [50, 50] });
359
test("{ grid: [50, 50] }, absolute", function() {
360
el = $("#draggable2").draggable({ grid: [50, 50] });
367
test("{ handle: 'span' }", function() {
368
el = $("#draggable2").draggable({ handle: 'span' });
370
drag("#draggable2 span", 50, 50);
371
moved(50, 50, "drag span");
373
drag("#draggable2", 50, 50);
374
moved(0, 0, "drag element");
377
test("{ helper: 'clone' }, relative", function() {
378
el = $("#draggable1").draggable({ helper: "clone" });
383
test("{ helper: 'clone' }, absolute", function() {
384
el = $("#draggable2").draggable({ helper: "clone" });
389
test("{ opacity: 0.5 }", function() {
394
el = $("#draggable2").draggable({
396
start: function(e, ui) {
397
opacity = $(this).css("opacity");
401
drag("#draggable2", -1, -1);
403
equals(opacity, 0.5, "start callback: opacity is");
407
test("{ zIndex: 10 }", function() {
411
var expected = 10, actual;
414
el = $("#draggable2").draggable({
416
start: function(e, ui) {
417
actual = $(this).css("zIndex");
421
drag("#draggable2", -1, -1);
423
equals(actual, expected, "start callback: zIndex is");
427
module("draggable: Callbacks");
429
test("callbacks occurance count", function() {
433
var start = 0, stop = 0, dragc = 0;
434
el = $("#draggable2").draggable({
435
start: function() { start++; },
436
drag: function() { dragc++; },
437
stop: function() { stop++; }
442
equals(start, 1, "start callback should happen exactly once");
443
equals(dragc, 3 + 1, "drag callback should happen exactly once per mousemove + 1");
444
equals(stop, 1, "stop callback should happen exactly once");
448
module("draggable: Scroll offsets");
450
test("{ helper: 'original' }, relative, with scroll offset on parent", function() {
451
el = $("#draggable1").draggable({ helper: "original" });
452
$("#main")[0].scrollTop = 100;
455
$("#main")[0].scrollTop = 0;
458
test("{ helper: 'original' }, relative, with scroll offset on root", function() {
459
el = $("#draggable1").draggable({ helper: "original" });
460
$(document).scrollTop(100);
463
$(document).scrollTop(0);
466
test("{ helper: 'original' }, relative, with scroll offset on root and parent", function() {
467
el = $("#draggable1").draggable({ helper: "original" });
468
$(document).scrollTop(100);
469
$("#main")[0].scrollTop = 100;
472
$(document).scrollTop(0);
473
$("#main")[0].scrollTop = 0;
476
test("{ helper: 'original' }, absolute, with scroll offset on parent", function() {
477
el = $("#draggable1").css({ position: 'absolute', top: 0, left: 0 }).draggable({ helper: "original" });
478
$("#main")[0].scrollTop = 100;
481
$("#main")[0].scrollTop = 0;
484
test("{ helper: 'original' }, absolute, with scroll offset on root", function() {
485
el = $("#draggable1").css({ position: 'absolute', top: 0, left: 0 }).draggable({ helper: "original" });
486
$(document).scrollTop(100);
489
$(document).scrollTop(0);
492
test("{ helper: 'original' }, absolute, with scroll offset on root and parent", function() {
493
el = $("#draggable1").css({ position: 'absolute', top: 0, left: 0 }).draggable({ helper: "original" });
494
$(document).scrollTop(100);
495
$("#main")[0].scrollTop = 100;
498
$(document).scrollTop(0);
499
$("#main")[0].scrollTop = 0;
502
//Fixed not for IE < 7
503
if(!($.browser.msie && $.browser.version < 7)) {
505
test("{ helper: 'original' }, fixed, with scroll offset on parent", function() {
506
el = $("#draggable1").css({ position: 'fixed', top: 0, left: 0 }).draggable({ helper: "original" });
507
$("#main")[0].scrollTop = 100;
510
$("#main")[0].scrollTop = 0;
513
test("{ helper: 'original' }, fixed, with scroll offset on root", function() {
514
el = $("#draggable1").css({ position: 'fixed', top: 0, left: 0 }).draggable({ helper: "original" });
515
$(document).scrollTop(100);
518
$(document).scrollTop(0);
521
test("{ helper: 'original' }, fixed, with scroll offset on root and parent", function() {
522
el = $("#draggable1").css({ position: 'fixed', top: 0, left: 0 }).draggable({ helper: "original" });
523
$(document).scrollTop(100);
524
$("#main")[0].scrollTop = 100;
527
$(document).scrollTop(0);
528
$("#main")[0].scrollTop = 0;
535
test("{ helper: 'clone' }, absolute", function() {
537
var helperOffset = null;
538
var origOffset = $("#draggable1").offset();
540
el = $("#draggable1").draggable({ helper: "clone", drag: function(e, ui) {
541
helperOffset = ui.helper.offset();
546
compare2({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');
550
test("{ helper: 'clone' }, absolute with scroll offset on parent", function() {
552
$("#main")[0].scrollTop = 100;
553
var helperOffset = null;
554
var origOffset = $("#draggable1").offset();
556
el = $("#draggable1").draggable({ helper: "clone", drag: function(e, ui) {
557
helperOffset = ui.helper.offset();
562
compare2({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');
563
$("#main")[0].scrollTop = 0;
567
test("{ helper: 'clone' }, absolute with scroll offset on root", function() {
569
$(document).scrollTop(100);
570
var helperOffset = null;
571
var origOffset = $("#draggable1").offset();
573
el = $("#draggable1").draggable({ helper: "clone", drag: function(e, ui) {
574
helperOffset = ui.helper.offset();
579
compare2({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');
580
$(document).scrollTop(0);
584
test("{ helper: 'clone' }, absolute with scroll offset on root and parent", function() {
586
$(document).scrollTop(100);
587
$("#main")[0].scrollTop = 100;
588
var helperOffset = null;
589
var origOffset = $("#draggable1").offset();
591
el = $("#draggable1").draggable({ helper: "clone", drag: function(e, ui) {
592
helperOffset = ui.helper.offset();
597
compare2({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');
598
$(document).scrollTop(0);
599
$("#main")[0].scrollTop = 0;
604
module("draggable: Tickets");
606
/* This needs to be rewritten
608
test("#2965 cursorAt with margin", function() {
614
var actual, expected;
615
$("#draggable2").draggable({
616
cursorAt: { left: ox, top: oy },
617
drag: function(e, ui) {
618
actual = ui.absolutePosition;
621
var el = $("#draggable2").data("draggable").element;
623
$("#draggable2").css('margin', '0px !important');
625
var before = el.offset();
626
var pos = { clientX: before.left + ox, clientY: before.top + oy };
627
$("#draggable2").simulate("mousedown", pos);
628
$(document).simulate("mousemove", { clientX: pos.clientX + 1, clientY: pos.clientY + 1});
629
$(document).simulate("mousemove", pos);
630
$("#draggable2").simulate("mouseup", pos);
631
var expected = actual;
636
$("#draggable2").css('margin', marg + 'px !important');
637
var before = el.offset();
638
var pos = { clientX: before.left + ox - marg, clientY: before.top + oy - marg };
639
$("#draggable2").simulate("mousedown", pos);
640
$(document).simulate("mousemove", { clientX: pos.clientX + 1, clientY: pos.clientY + 1});
641
$(document).simulate("mousemove", pos);
642
$("#draggable2").simulate("mouseup", pos);
644
equals(actual.left, expected.left, "10px margin. left");
645
equals(actual.top, expected.top, "10px margin. top");