Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1d -> 2d -> 1d zoombox regression fix + drag test maintenance #3950

Merged
merged 8 commits into from
Jun 11, 2019
166 changes: 133 additions & 33 deletions test/jasmine/assets/drag.js
Original file line number Diff line number Diff line change
@@ -1,42 +1,146 @@
var isNumeric = require('fast-isnumeric');

var mouseEvent = require('./mouse_event');
var touchEvent = require('./touch_event');
var getNodeCoords = require('./get_node_coords');
var delay = require('./delay');

function makeFns(node, dx, dy, opts) {
/**
* Inside `opts`:
*
* @param {array of 2 numbers} pos0 :
* px position of start of drag motion, default computed using `node` and `edge`
* @param {DOM element} node :
* element to drag on, default found using `pos0`
* @param {string} edge :
* combinations of 'n', 's', 'e', 'w' used to find `pos0` of `node`
*
* Set one of:
* @param {array of arrays of numbers} path :
* px position drag path
* @param {array of 2 numbers} dpos :
* px position delta
* @param {array of 2 numbers} posN :
* px position of end of drag motion
*
* If using `dpos` or `posN`
* @param {number} nsteps :
* set number of steps to take between `pos0` and `pos0` + `dpos` or `posN`, default is 1
*
* @param {boolean} touch :
* pass `true` to simulate touch events
* @param {boolean} shiftKey, altKey, ctrlKey ....
* pass `true to simulate <shift>, alt, ctrl drag (see ./mouse_event.js for more info)
*
* @param {function} clearThrottle :
* pass Lib.clearThrottle to clear throttle for all mouse/touch event
* @param {boolean} noCover :
* do not wait for "drag cover" element to start "move" events
*
* @return {object}
* - {function} start
* - {function} end
*/
function makeFns(opts) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can now use the same drag helpers by passing a path, start/end position, start position + delta, etc..

opts = opts || {};

var nsteps = opts.nsteps || 1;
var edge = opts.edge || '';
var noCover = Boolean(opts.noCover);
var path;

if(Array.isArray(opts.path) && opts.path.length >= 2 &&
Array.isArray(opts.path[0]) && Array.isArray(opts.path[1])) {
path = opts.path;
} else {
var nsteps = opts.nsteps || 1;
var p0, dp;
var msg = [];

if(opts.pos0 && isNumeric(opts.pos0[0]) && isNumeric(opts.pos0[1])) {
p0 = opts.pos0;
} else if(opts.node) {
var coords = getNodeCoords(opts.node, opts.edge || '');
p0 = [coords.x, coords.y];
} else {
msg.push('Cannot determine drag path start position from the given options');
}

if(opts.dpos && isNumeric(opts.dpos[0]) && isNumeric(opts.dpos[1])) {
dp = opts.dpos;
} else if(opts.posN && isNumeric(opts.posN[0]) && isNumeric(opts.posN[1])) {
dp = [opts.posN[0] - opts.pos0[0], opts.posN[1] - opts.pos0[1]];
} else {
msg.push('Cannot determine drag path step from the given options');
}

if(msg.length) {
throw new Error(msg.join('\n'));
}

path = [p0];

for(var i = 1; i <= nsteps; i++) {
path[i] = [
p0[0] + i * dp[0] / nsteps,
p0[1] + i * dp[1] / nsteps
];
}
}

var coords = getNodeCoords(node, edge);
var fromX = isNumeric(opts.x0) ? opts.x0 : coords.x;
var fromY = isNumeric(opts.y0) ? opts.y0 : coords.y;
function extendOpts(patch) {
var out = {};
var k;
for(k in opts) out[k] = opts[k];
for(k in patch) out[k] = patch[k];
return out;
}

var dragCoverNode;
var toX;
var toY;

function start() {
mouseEvent('mousemove', fromX, fromY, {element: node});
mouseEvent('mousedown', fromX, fromY, {element: node});
if(opts.clearThrottle) opts.clearThrottle();

var x0 = path[0][0];
var y0 = path[0][1];

var _opts = extendOpts({element: opts.node});

if(opts.touch) {
touchEvent('touchstart', x0, y0, _opts);
} else {
mouseEvent('mousemove', x0, y0, _opts);
mouseEvent('mousedown', x0, y0, _opts);
}

return (noCover ? Promise.resolve(node) : waitForDragCover())
return (opts.noCover ? Promise.resolve(opts.node) : waitForDragCover())
.then(function(_dragCoverNode) {
dragCoverNode = _dragCoverNode;

for(var i = 1; i <= nsteps; i++) {
toX = fromX + i * dx / nsteps;
toY = fromY + i * dy / nsteps;
mouseEvent('mousemove', toX, toY, {element: dragCoverNode});
}
var _opts = extendOpts({element: dragCoverNode});

path.slice(1).forEach(function(p) {
if(opts.clearThrottle) opts.clearThrottle();
if(opts.touch) {
touchEvent('touchmove', p[0], p[1], _opts);
} else {
mouseEvent('mousemove', p[0], p[1], _opts);
}
});
});
}

function end() {
mouseEvent('mouseup', toX, toY, {element: dragCoverNode});
return noCover || waitForDragCoverRemoval();
var iN = path.length - 1;
var xN = path[iN][0];
var yN = path[iN][1];

var _opts = extendOpts({element: dragCoverNode});

if(opts.touch) {
touchEvent('touchend', xN, yN, _opts);
} else {
mouseEvent('mouseup', xN, yN, _opts);
}

return opts.noCover || waitForDragCoverRemoval();
}

return {
Expand All @@ -45,21 +149,17 @@ function makeFns(node, dx, dy, opts) {
};
}

/*
* drag: grab a node and drag it (dx, dy) pixels
* optionally specify an edge ('n', 'se', 'w' etc)
* to grab it by an edge or corner (otherwise the middle is used)
/**
* Inside `opts`:
*
* Same as in makeDragFns plus:
*
* @param {number} timeDelay :
* time delay between drag start promise resolve and drag end call
*/
function drag(node, dx, dy, edge, x0, y0, nsteps, noCover, timeDelay) {
if(!timeDelay) timeDelay = 0;
var fns = makeFns(node, dx, dy, {
edge: edge,
x0: x0,
y0: y0,
nsteps: nsteps,
noCover: noCover
});

function drag(opts) {
var fns = makeFns(opts);
var timeDelay = opts.timeDelay || 0;
return fns.start().then(delay(timeDelay)).then(fns.end);
}

Expand Down