Skip to content

Commit 8806fb7

Browse files
committed
generalize assets/drag.js
- to accept `path` (on top of dpos/pos0) - to accept `touch` option to emulate touch drag
1 parent 121227b commit 8806fb7

File tree

1 file changed

+133
-33
lines changed

1 file changed

+133
-33
lines changed

test/jasmine/assets/drag.js

Lines changed: 133 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,146 @@
11
var isNumeric = require('fast-isnumeric');
2+
23
var mouseEvent = require('./mouse_event');
4+
var touchEvent = require('./touch_event');
35
var getNodeCoords = require('./get_node_coords');
46
var delay = require('./delay');
57

6-
function makeFns(node, dx, dy, opts) {
8+
/**
9+
* Inside `opts`:
10+
*
11+
* @param {array of 2 numbers} pos0 :
12+
* px position of start of drag motion, default computed using `node` and `edge`
13+
* @param {DOM element} node :
14+
* element to drag on, default found using `pos0`
15+
* @param {string} edge :
16+
* combinations of 'n', 's', 'e', 'w' used to find `pos0` of `node`
17+
*
18+
* Set one of:
19+
* @param {array of arrays of numbers} path :
20+
* px position drag path
21+
* @param {array of 2 numbers} dpos :
22+
* px position delta
23+
* @param {array of 2 numbers} posN :
24+
* px position of end of drag motion
25+
*
26+
* If using `dpos` or `posN`
27+
* @param {number} nsteps :
28+
* set number of steps to take between `pos0` and `pos0` + `dpos` or `posN`, default is 1
29+
*
30+
* @param {boolean} touch :
31+
* pass `true` to simulate touch events
32+
* @param {boolean} shiftKey, altKey, ctrlKey ....
33+
* pass `true to simulate <shift>, alt, ctrl drag (see ./mouse_event.js for more info)
34+
*
35+
* @param {function} clearThrottle :
36+
* pass Lib.clearThrottle to clear throttle for all mouse/touch event
37+
* @param {boolean} noCover :
38+
* do not wait for "drag cover" element to start "move" events
39+
*
40+
* @return {object}
41+
* - {function} start
42+
* - {function} end
43+
*/
44+
function makeFns(opts) {
745
opts = opts || {};
846

9-
var nsteps = opts.nsteps || 1;
10-
var edge = opts.edge || '';
11-
var noCover = Boolean(opts.noCover);
47+
var path;
48+
49+
if(Array.isArray(opts.path) && opts.path.length >= 2 &&
50+
Array.isArray(opts.path[0]) && Array.isArray(opts.path[1])) {
51+
path = opts.path;
52+
} else {
53+
var nsteps = opts.nsteps || 1;
54+
var p0, dp;
55+
var msg = [];
56+
57+
if(opts.pos0 && isNumeric(opts.pos0[0]) && isNumeric(opts.pos0[1])) {
58+
p0 = opts.pos0;
59+
} else if(opts.node) {
60+
var coords = getNodeCoords(opts.node, opts.edge || '');
61+
p0 = [coords.x, coords.y];
62+
} else {
63+
msg.push('Cannot determine drag path start position from the given options');
64+
}
65+
66+
if(opts.dpos && isNumeric(opts.dpos[0]) && isNumeric(opts.dpos[1])) {
67+
dp = opts.dpos;
68+
} else if(opts.posN && isNumeric(opts.posN[0]) && isNumeric(opts.posN[1])) {
69+
dp = [opts.posN[0] - opts.pos0[0], opts.posN[1] - opts.pos0[1]];
70+
} else {
71+
msg.push('Cannot determine drag path step from the given options');
72+
}
73+
74+
if(msg.length) {
75+
throw new Error(msg.join('\n'));
76+
}
77+
78+
path = [p0];
79+
80+
for(var i = 1; i <= nsteps; i++) {
81+
path[i] = [
82+
p0[0] + i * dp[0] / nsteps,
83+
p0[1] + i * dp[1] / nsteps
84+
];
85+
}
86+
}
1287

13-
var coords = getNodeCoords(node, edge);
14-
var fromX = isNumeric(opts.x0) ? opts.x0 : coords.x;
15-
var fromY = isNumeric(opts.y0) ? opts.y0 : coords.y;
88+
function extendOpts(patch) {
89+
var out = {};
90+
var k;
91+
for(k in opts) out[k] = opts[k];
92+
for(k in patch) out[k] = patch[k];
93+
return out;
94+
}
1695

1796
var dragCoverNode;
18-
var toX;
19-
var toY;
2097

2198
function start() {
22-
mouseEvent('mousemove', fromX, fromY, {element: node});
23-
mouseEvent('mousedown', fromX, fromY, {element: node});
99+
if(opts.clearThrottle) opts.clearThrottle();
100+
101+
var x0 = path[0][0];
102+
var y0 = path[0][1];
103+
104+
var _opts = extendOpts({element: opts.node});
105+
106+
if(opts.touch) {
107+
touchEvent('touchstart', x0, y0, _opts);
108+
} else {
109+
mouseEvent('mousemove', x0, y0, _opts);
110+
mouseEvent('mousedown', x0, y0, _opts);
111+
}
24112

25-
return (noCover ? Promise.resolve(node) : waitForDragCover())
113+
return (opts.noCover ? Promise.resolve(opts.node) : waitForDragCover())
26114
.then(function(_dragCoverNode) {
27115
dragCoverNode = _dragCoverNode;
28116

29-
for(var i = 1; i <= nsteps; i++) {
30-
toX = fromX + i * dx / nsteps;
31-
toY = fromY + i * dy / nsteps;
32-
mouseEvent('mousemove', toX, toY, {element: dragCoverNode});
33-
}
117+
var _opts = extendOpts({element: dragCoverNode});
118+
119+
path.slice(1).forEach(function(p) {
120+
if(opts.clearThrottle) opts.clearThrottle();
121+
if(opts.touch) {
122+
touchEvent('touchmove', p[0], p[1], _opts);
123+
} else {
124+
mouseEvent('mousemove', p[0], p[1], _opts);
125+
}
126+
});
34127
});
35128
}
36129

37130
function end() {
38-
mouseEvent('mouseup', toX, toY, {element: dragCoverNode});
39-
return noCover || waitForDragCoverRemoval();
131+
var iN = path.length - 1;
132+
var xN = path[iN][0];
133+
var yN = path[iN][1];
134+
135+
var _opts = extendOpts({element: dragCoverNode});
136+
137+
if(opts.touch) {
138+
touchEvent('touchend', xN, yN, _opts);
139+
} else {
140+
mouseEvent('mouseup', xN, yN, _opts);
141+
}
142+
143+
return opts.noCover || waitForDragCoverRemoval();
40144
}
41145

42146
return {
@@ -45,21 +149,17 @@ function makeFns(node, dx, dy, opts) {
45149
};
46150
}
47151

48-
/*
49-
* drag: grab a node and drag it (dx, dy) pixels
50-
* optionally specify an edge ('n', 'se', 'w' etc)
51-
* to grab it by an edge or corner (otherwise the middle is used)
152+
/**
153+
* Inside `opts`:
154+
*
155+
* Same as in makeDragFns plus:
156+
*
157+
* @param {number} timeDelay :
158+
* time delay between drag start promise resolve and drag end call
52159
*/
53-
function drag(node, dx, dy, edge, x0, y0, nsteps, noCover, timeDelay) {
54-
if(!timeDelay) timeDelay = 0;
55-
var fns = makeFns(node, dx, dy, {
56-
edge: edge,
57-
x0: x0,
58-
y0: y0,
59-
nsteps: nsteps,
60-
noCover: noCover
61-
});
62-
160+
function drag(opts) {
161+
var fns = makeFns(opts);
162+
var timeDelay = opts.timeDelay || 0;
63163
return fns.start().then(delay(timeDelay)).then(fns.end);
64164
}
65165

0 commit comments

Comments
 (0)