forked from adopted-ember-addons/ember-sortable
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdrag.js
More file actions
115 lines (97 loc) · 2.57 KB
/
drag.js
File metadata and controls
115 lines (97 loc) · 2.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import { registerAsyncHelper } from '@ember/test';
import { triggerEvent } from '@ember/test-helpers';
/**
Drags elements by an offset specified in pixels.
Examples
drag(
'mouse',
'.some-list li[data-item=uno]',
function() {
return { dy: 50, dx: 20 };
}
);
@method drag
@param {'mouse'|'touch'} [mode]
event mode
@param {String} [itemSelector]
selector for the element to drag
@param {Function} [offsetFn]
function returning the offset by which to drag
@param {Object} [callbacks]
callbacks that are fired at the different stages of the interaction
@return {Promise}
*/
export function drag(app, mode, itemSelector, offsetFn, callbacks = {}) {
let start, move, end, which;
const {
andThen,
findWithAssert,
wait
} = app.testHelpers;
if (mode === 'mouse') {
start = 'mousedown';
move = 'mousemove';
end = 'mouseup';
which = 1;
} else if (mode === 'touch') {
start = 'touchstart';
move = 'touchmove';
end = 'touchend';
} else {
throw new Error(`Unsupported mode: '${mode}'`);
}
andThen(() => {
let item = findWithAssert(itemSelector);
let itemOffset = item.offset();
let offset = offsetFn();
let itemElement = item.get(0);
let rect = itemElement.getBoundingClientRect();
let scale = itemElement.clientHeight / (rect.bottom - rect.top);
let halfwayX = itemOffset.left + (offset.dx * scale) / 2;
let halfwayY = itemOffset.top + (offset.dy * scale) / 2;
let targetX = itemOffset.left + offset.dx * scale;
let targetY = itemOffset.top + offset.dy * scale;
andThen(() => {
triggerEvent(itemElement, start, {
clientX: itemOffset.left,
clientY: itemOffset.top,
which
});
});
if (callbacks.dragstart) {
andThen(callbacks.dragstart);
}
andThen(() => {
triggerEvent(itemElement, move, {
clientX: itemOffset.left,
clientY: itemOffset.top
});
});
if (callbacks.dragmove) {
andThen(callbacks.dragmove);
}
andThen(() => {
triggerEvent(itemElement, move, {
clientX: halfwayX,
clientY: halfwayY
});
});
andThen(() => {
triggerEvent(itemElement, move, {
clientX: targetX,
clientY: targetY
});
});
andThen(() => {
triggerEvent(itemElement, end, {
clientX: targetX,
clientY: targetY
});
});
if (callbacks.dragend) {
andThen(callbacks.dragend);
}
});
return wait();
}
export default registerAsyncHelper('drag', drag);