Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 69 additions & 19 deletions src/drag.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ var DragonDrop = {

html5drag : false,
focusWindow : null,
dragging : false,


/**
* Performs a series of dragStart, dragEnter, dragOver and drop operations to simulate a dragDrop
Expand Down Expand Up @@ -88,46 +90,94 @@ var DragonDrop = {


_dragStart: function(node){
var options = { bubbles:false, cancelable:false };
var options = { bubbles:true, cancelable:true, button: 0, buttons: 1 };
this.createAndDispatchEvent(node, 'dragstart', options);
},

_drag: function(node){
var options = { bubbles:true, cancelable:true };
var options = { bubbles:true, cancelable:true, button: 0, buttons: 1 };
this.createAndDispatchEvent(node, 'drag', options);
},

_dragEnter: function(node){
var options = { bubbles:true, cancelable:true };
var options = { bubbles:true, cancelable:true, button: 0, buttons: 0 };
this.createAndDispatchEvent(node, 'dragenter', options);
},

_dragOver: function(node){
var options = { bubbles:true, cancelable:true };
var options = { bubbles:true, cancelable:true, button: 0, buttons: 0 };
this.createAndDispatchEvent(node, 'dragover', options);
},

_dragLeave: function(node){
var options = { bubbles:true, cancelable:false };
var options = { bubbles:true, cancelable:false, button: 0, buttons: 0 };
this.createAndDispatchEvent(node, 'dragleave', options);
},

_drop: function(node){
var options = { bubbles:true, cancelable:true, buttons:1 };
var options = { bubbles:true, cancelable:true, button: 0, buttons: 0 };
this.createAndDispatchEvent(node, 'drop', options);
},

_dragEnd: function(node){
var options = { bubbles:true, cancelable:false };
var options = { bubbles:true, cancelable:false, button: 0, buttons: 0 };
this.createAndDispatchEvent(node, 'dragend', options);
DragonDrop.dragging = false;
},

_mouseDown: function(node, options){ this.createAndDispatchEvent(node, 'mousedown', options); },
_mouseMove: function(node, options){ this.createAndDispatchEvent(node, 'mousemove', options); },
_mouseEnter: function(node, options){ this.createAndDispatchEvent(node, 'mouseenter', options); },
_mouseOver: function(node, options){ this.createAndDispatchEvent(node, 'mouseover', options); },
_mouseOut: function(node, options){ this.createAndDispatchEvent(node, 'mouseout', options); },
_mouseLeave: function(node, options){ this.createAndDispatchEvent(node, 'mouseleave', options); },
_mouseDown: function(node, options){
if (!options) { options = {}; }
options.bubbles = true;
options.cancelable = true;
options.button = 0;
options.buttons = 1;
this.createAndDispatchEvent(node, 'mousedown', options);
},

_mouseMove: function(node, options){
if (!options) { options = {}; }
options.bubbles = true;
options.cancelable = true;
options.button = 0;
options.buttons = DragonDrop.dragging ? 1: 0;
this.createAndDispatchEvent(node, 'mousemove', options);
},

_mouseEnter: function(node, options){
if (!options) { options = {}; }
options.bubbles = false;
options.cancelable = false;
options.button = 0;
options.buttons = DragonDrop.dragging ? 1: 0;
this.createAndDispatchEvent(node, 'mouseenter', options);
},

_mouseOver: function(node, options){
if (!options) { options = {}; }
options.bubbles = true;
options.cancelable = true;
options.button = 0;
options.buttons = DragonDrop.dragging ? 1: 0;
this.createAndDispatchEvent(node, 'mouseover', options);
},

_mouseOut: function(node, options){
if (!options) { options = {}; }
options.bubbles = true;
options.cancelable = true;
options.button = 0;
options.buttons = DragonDrop.dragging ? 1: 0;
this.createAndDispatchEvent(node, 'mouseout', options);
},

_mouseLeave: function(node, options){
if (!options) { options = {}; }
options.bubbles = false;
options.cancelable = false;
options.button = 0;
options.buttons = DragonDrop.dragging ? 1: 0;
this.createAndDispatchEvent(node, 'mouseleave', options);
},


/**
Expand Down Expand Up @@ -374,9 +424,7 @@ syn.create.dragend = {

if(syn.support.pointerEvents){syn.trigger(el || win, "pointermove", point);}
if(syn.support.touchEvents){syn.trigger(el || win, "touchmove", point);}

//console.log("DRAGGED: " + DragonDrop.html5drag);


/*
The following code needs some explanation. Firefox and Chrome DO NOT issue mousemove events during HTML5-dragdrops
However, they do issue mousemoves during jQuery-dragdrops. I am making the assumption here (which may or may not
Expand All @@ -389,7 +437,6 @@ syn.create.dragend = {
syn.trigger(el || win, "mousemove", point);
}


return el;
},

Expand All @@ -399,9 +446,10 @@ syn.create.dragend = {

//creates an event at a certain point. Note: Redundant to DragonDrop.createAndDispatchEvent
// TODO: Consolidate this with DragonDrop.createAndDispatchEvent !!!
createEventAtPoint = function (event, point, win) {
createEventAtPoint = function (eventName, point, win) {
var el = elementFromPoint(point, win);
syn.trigger(el || win, event, point);
var options = { clientX:point.clientX, clientY:point.clientY };
syn.trigger(el || win, eventName, options);
return el;
},

Expand Down Expand Up @@ -476,6 +524,7 @@ syn.create.dragend = {
if(syn.support.pointerEvents){createEventAtPoint("pointerup", toPoint, win);}
if(syn.support.touchEvents){createEventAtPoint("touchend", toPoint, win);}
createEventAtPoint("mouseup", toPoint, win);
DragonDrop.dragging = false;
if(syn.support.pointerEvents){createEventAtPoint("pointerleave", toPoint, win);}
createEventAtPoint("mouseleave", toPoint, win);
callback();
Expand Down Expand Up @@ -715,6 +764,7 @@ syn.helpers.extend(syn.init.prototype, {
}

DragonDrop.html5drag = from.draggable;
DragonDrop.dragging = true;

if(DragonDrop.html5drag){
DragonDrop.dragAndDrop(win, sourceCoordinates, destinationCoordinates, options.duration || 500, callback);
Expand Down
26 changes: 24 additions & 2 deletions src/mouse.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,21 @@ h.extend(syn.create, {
//browser might not be loaded yet (doing support code)
left = syn.mouse.browser && syn.mouse.browser.left[type],
right = syn.mouse.browser && syn.mouse.browser.right[type];



var leftClick = (type === 'click');
var doubleLeftClick = (type === 'dblclick');
var contextMenuClick = (type === 'contextmenu');

// NOTE: I don't know if this undefined is correct, but if this is set to anything (including 0), jQuery will fail to dragdrop
// The rules about when buttons = 0 vs buttons = undef, seem very squishy. (Kevin.D)
var buttonsCode = undefined;
if(options.buttons){ buttonsCode = options.buttons; }
else if(leftClick){ buttonsCode = 1; }
else if(doubleLeftClick){ buttonsCode = 1; }
else if(contextMenuClick){ buttonsCode = 2; }

return h.extend({
bubbles: true,
cancelable: true,
Expand All @@ -111,7 +126,13 @@ h.extend(syn.create, {
altKey: !! syn.key.altKey,
shiftKey: !! syn.key.shiftKey,
metaKey: !! syn.key.metaKey,
button: left && left.button !== null ? left.button : right && right.button || (type === 'contextmenu' ? 2 : 0),
button: left && left.button !== null ? left.button : right && right.button || (contextMenuClick ? 2 : 0),
// NOTE: 'buttons' doesn't work because we need to identify the button that is currently held-down vs no-button.
// For example: "button" is 0 regardless of whether left button is down or not. For events like click(), this doesn't matter (since
// we can infer that a button was clicked, and that button was 0.) However, for buttonS, left is 1 and nothing is 0.
// Because FuncUnit doesn't keep track of button state, if you want to set buttonS, you need to set it in options when passing
// the event request to syn.trigger . (Kevin.D)
buttons: buttonsCode,
relatedTarget: document.documentElement
}, options);
},
Expand All @@ -137,7 +158,8 @@ h.extend(syn.create, {
defaults.clientX, defaults.clientY,
defaults.ctrlKey, defaults.altKey,
defaults.shiftKey, defaults.metaKey,
defaults.button, defaults.relatedTarget);
defaults.button, defaults.buttons,
defaults.relatedTarget);
} catch (e) {
event = h.createBasicStandardEvent(type, defaults, doc);
}
Expand Down
138 changes: 133 additions & 5 deletions test/mouse_regressions_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ var locate = require('test/locate_test');
var QUnit = require("steal-qunit");

QUnit.module("synthetic/mouse/regressions");
QUnit.module("syn/drag");

var frameHeight = 200;
var frameUrl = 'testpages/regressions_mouse.html';
var regressionsTestpage = 'testpages/regressions_mouse.html';
var buttonCodeTestpage = 'testpages/button_number_tests.html';



Expand Down Expand Up @@ -34,9 +36,8 @@ QUnit.test("Testing Button codes: left click", 2, function () {
});
});

// TODO: Boilerplate. Can we move this to a setup function?
testFrame.height = frameHeight;
testFrame.src = frameUrl;
testFrame.src = regressionsTestpage;
});


Expand Down Expand Up @@ -64,14 +65,141 @@ QUnit.test("Testing Button codes: right click", 1, function () {
});
});

// TODO: Boilerplate. Can we move this to a setup function?
testFrame.height = frameHeight;
testFrame.src = frameUrl;
testFrame.src = regressionsTestpage;
});




QUnit.test("Testing ButtonS codes: left click", 2, function () {
stop();

var testFrame = document.getElementById('pageUnderTest');

testFrame.addEventListener('load', function loadListener(){
testFrame.removeEventListener('load', loadListener);

var pageUnderTest = document.getElementById('pageUnderTest').contentDocument.querySelector('body');
var clickable = pageUnderTest.querySelector('#clickbutton');
var buttonNumber = pageUnderTest.querySelector('#buttonNumber');
var buttonsNumber = pageUnderTest.querySelector('#buttonsNumber');

syn.click(clickable, {}, function () {

var buttonCode = buttonNumber.innerText;
ok( buttonCode == 'Button Number: 0', "Mouse 'button' code expected: '0', received: '" + buttonCode + "'.");
var buttonsCode = buttonsNumber.innerText;
ok( buttonsCode == 'ButtonS Number: 1', "Mouse 'buttons' code expected: '1', received: '" + buttonsCode + "'.");

start();
});
});

testFrame.height = 300;
testFrame.src = buttonCodeTestpage;
});




QUnit.test("Testing ButtonS codes: right click", 2, function () {
stop();

var testFrame = document.getElementById('pageUnderTest');

testFrame.addEventListener('load', function loadListener(){
testFrame.removeEventListener('load', loadListener);

var pageUnderTest = document.getElementById('pageUnderTest').contentDocument.querySelector('body');
var clickable = pageUnderTest.querySelector('#clickbutton');
var buttonNumber = pageUnderTest.querySelector('#buttonNumber');
var buttonsNumber = pageUnderTest.querySelector('#buttonsNumber');

syn.rightClick(clickable, {}, function () {

var buttonCode = buttonNumber.innerText;
ok( buttonCode == 'Button Number: 2', "Mouse 'button' code expected: '2', received: '" + buttonCode + "'.");
var buttonsCode = buttonsNumber.innerText;
ok( buttonsCode == 'ButtonS Number: 2', "Mouse 'buttons' code expected: '2', received: '" + buttonsCode + "'.");

start();
});
});

testFrame.height = 300;
testFrame.src = buttonCodeTestpage;
});




QUnit.test("Testing ButtonS codes: double click", 2, function () {
stop();

var testFrame = document.getElementById('pageUnderTest');

testFrame.addEventListener('load', function loadListener(){
testFrame.removeEventListener('load', loadListener);

var pageUnderTest = document.getElementById('pageUnderTest').contentDocument.querySelector('body');
var clickable = pageUnderTest.querySelector('#clickbutton');
var buttonNumber = pageUnderTest.querySelector('#buttonNumber');
var buttonsNumber = pageUnderTest.querySelector('#buttonsNumber');

syn.dblclick(clickable, {}, function () {

var buttonCode = buttonNumber.innerText;
ok( buttonCode == 'Button Number: 0 0', "Mouse 'button' code expected: '0 0', received: '" + buttonCode + "'.");
var buttonsCode = buttonsNumber.innerText;
ok( buttonsCode == 'ButtonS Number: 1 1', "Mouse 'buttons' code expected: '1 1', received: '" + buttonsCode + "'.");

start();
});
});

testFrame.height = 300;
testFrame.src = buttonCodeTestpage;
});




QUnit.test("Testing ButtonS codes: drag", 2, function () {
stop();

var testFrame = document.getElementById('pageUnderTest');

testFrame.addEventListener('load', function loadListener(){
testFrame.removeEventListener('load', loadListener);

var pageUnderTest = document.getElementById('pageUnderTest').contentDocument.querySelector('body');
var buttonNumber = pageUnderTest.querySelector('#buttonNumber');
var buttonsNumber = pageUnderTest.querySelector('#buttonsNumber');
var draggable = pageUnderTest.querySelector('#drag1');
var target = pageUnderTest.querySelector('#cell_a2');

syn.drag(draggable, {to: target}, function () {


var buttonCode = buttonNumber.innerText;
ok( buttonCode == 'Button Number: 0 0 0 0', "Mouse 'button' code expected: '0 0 0 0', received: '" + buttonCode + "'.");
var buttonsCode = buttonsNumber.innerText;
// EXPLANATION: Mousedown and drag are 1, mouseup and leave are 0
ok( buttonsCode == 'ButtonS Number: 1 1 0 0', "Mouse 'buttons' code expected: '1 1 0 0', received: '" + buttonsCode + "'.");

start();
});
});

testFrame.height = 300;
testFrame.src = buttonCodeTestpage;
});







function getValue(needle, haystack){
Expand Down
Loading