Skip to content

Commit

Permalink
Fixed major error in new mouse timeout implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
mennovanslooten committed Jan 19, 2015
1 parent 83bcd27 commit 319505e
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 72 deletions.
2 changes: 1 addition & 1 deletion lib/handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ exports.create = function(_page, path) {
var center = local.getCoordinates(destination);
if (!center) return 'No coordinates for element';

if (_mouse.moveTo(center.left, center.top)) {
if (_mouse.sendEvent('mousemove', center.left, center.top)) {
return '';
}
return 'Mouse not over element';
Expand Down
152 changes: 87 additions & 65 deletions lib/mouse.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,52 +7,14 @@ exports.create = function(_page) {
var _mouse_x = 0;
var _mouse_y = 0;
var _mouse = {};
var _interval;

/**
* Update the scroll coordinates and move the mouse to the top left corner
*/
_mouse.reset = function() {
var scroll = _page.evaluate(function() {
return {
top: window.scrollY,
left: window.scrollX
};
});

_page.scrollPosition = {
top: scroll.top,
left: scroll.left
};

_mouse_x = scroll.left;
_mouse_y = scroll.top;
};
var _timeout = null;


/**
* Trigger event "type" at (x, y) if the mouse is there or
* move the mouse in that direction
*/
_mouse.sendEvent = function(type, x, y) {
if (this.moveTo(x, y)) {
// _mouse_x and _mouse_y are relative to the top left of the document
// sendEvent() is relative to the top left corner of the viewport
var real_x = _mouse_x - _page.scrollPosition.left;
var real_y = _mouse_y - _page.scrollPosition.top;
_page.sendEvent(type, real_x, real_y);
return true;
}
//this.moveTo(x, y);
return false;
};


/**
* Move the mouse in the direction of (x, y)
* Scroll the page so (x, y) is in view if it isn't already
* x and y are relative to the document
*/
function moveTo(x, y) {
function scrollIntoView(x, y) {
var top = _page.scrollPosition.top;
var left = _page.scrollPosition.left;
var height = _page.viewportSize.height;
Expand All @@ -67,33 +29,64 @@ exports.create = function(_page) {
var is_y_in_viewport = y >= top && y <= top + height;
var is_x_in_viewport = x >= left && x <= left + width;

var scroll_top;
var scroll_left;
if (!is_y_in_viewport) {
top = Math.max(0, y - Math.round(height / 2));
top = Math.min(top, doc.height - height);
scroll_top = Math.max(0, y - Math.round(height / 2));
scroll_top = Math.min(scroll_top, doc.height - height);
}

if (!is_x_in_viewport) {
left = Math.max(0, x - Math.round(width / 2));
left = Math.min(left, doc.width - width);
scroll_left = Math.max(0, x - Math.round(width / 2));
scroll_left = Math.min(scroll_left, doc.width - width);
}

// Scroll (x, y) into view
if (!is_y_in_viewport || !is_x_in_viewport) {
_page.scrollPosition = {
top: top,
left: left
top: scroll_top,
left: scroll_left
};

_mouse_y += (scroll_top - top);
_mouse_x += (scroll_left - left);
}
}


/**
* Trigger a series of timeout-separated mousemove events towards (x, y)
* x and y are relative to the document
*/
function moveTo(x, y) {
moveTowards(x, y);

var top = _page.scrollPosition.top;
var left = _page.scrollPosition.left;

// _mouse_x and _mouse_y are relative to the top left of the document
// sendEvent() is relative to the top left corner of the viewport
_page.sendEvent('mousemove', _mouse_x - left, _mouse_y - top);

if (isHovering(x, y)) {
clearInterval(_interval);
_interval = null;
_timeout = null;
return true;
}

_timeout = setTimeout(moveTo, 15, x, y);
return false;
}



/**
* Move the mouse a step in the direction of (x, y)
* x and y are relative to the document
*/
function moveTowards(x, y) {
// Move the mouse a step into the direction of (x, y)
//var mouse_step = (12500 / _cli.timeout) * _cli.step;
var mouse_step = 50;
var mouse_step = 100;
var delta_x = x - _mouse_x;
var delta_y = y - _mouse_y;

Expand All @@ -112,30 +105,59 @@ exports.create = function(_page) {
} else {
_mouse_y = y;
}
}

// _mouse_x and _mouse_y are relative to the top left of the document
// sendEvent() is relative to the top left corner of the viewport
_page.sendEvent('mousemove', _mouse_x - left, _mouse_y - top);
return false;

/**
* Is the current mouse position (x, y)?
*/
function isHovering(x, y) {
var result = (x === _mouse_x && y === _mouse_y);
//console.log(' - isHovering', x, ',', y, ' -- ', _mouse_x, ', ', _mouse_y, result);
return result;
}


_mouse.moveTo = function(x, y) {
if (isHovering(x, y)) {
return true;
} else if (!_interval) {
_interval = setInterval(moveTo, 1, x, y);
}
return false;
/**
* Update the scroll coordinates and move the mouse to the top left corner
*/
_mouse.reset = function() {
var scroll = _page.evaluate(function() {
return {
top: window.scrollY,
left: window.scrollX
};
});

_page.scrollPosition = {
top: scroll.top,
left: scroll.left
};

_mouse_x = scroll.left;
_mouse_y = scroll.top;
};


/**
* Is the current mouse position (x, y)?
* Trigger event "type" at (x, y) if the mouse is there or
* move the mouse in that direction
*/
function isHovering(x, y) {
return (x === _mouse_x && y === _mouse_y);
}
_mouse.sendEvent = function(type, x, y) {
if (isHovering(x, y)) {
// _mouse_x and _mouse_y are relative to the top left of the document
// sendEvent() is relative to the top left corner of the viewport
var real_x = _mouse_x - _page.scrollPosition.left;
var real_y = _mouse_y - _page.scrollPosition.top;
_page.sendEvent(type, real_x, real_y);
return true;
} else if (_timeout === null) {
scrollIntoView(x, y);
moveTo(x, y);
}

return false;
};

return _mouse;
};
9 changes: 3 additions & 6 deletions test/mouse.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,10 @@ describe('mouse', function() {
width: 600
};

page_stub.evaluate.returns(base);


var moveTo = sinon.spy(mouse, 'moveTo');
it('should call mouse.moveTo', function() {
it('should call page.sendEvent', function() {
page_stub.evaluate.returns(base);
mouse.sendEvent('click', 1000, 2000);
assert.equal(moveTo.calledWith(1000, 2000), true);
assert.equal(page_stub.sendEvent.calledWith('mousemove'), true);
});

it('should return false when not hovering', function() {
Expand Down

0 comments on commit 319505e

Please sign in to comment.