Last active
August 29, 2015 14:06
-
-
Save melanke/0160110c5dc1e7fda48d to your computer and use it in GitHub Desktop.
trying to test touch events
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
describe("mouse", function(){ | |
function computedStyle(el, prop) { | |
return ( | |
window.getComputedStyle ? window.getComputedStyle(el) : el.currentStyle | |
)[prop.replace(/-(\w)/gi, function (word, letter) { | |
return letter.toUpperCase(); | |
})]; | |
} | |
function getChildrenSize(container) { | |
if (!container) { | |
return; | |
} | |
var children = [].slice.call(container.children, 0).filter(function (el) { | |
var pos = computedStyle(el, 'position'); | |
el.rect = el.getBoundingClientRect(); // store rect for later | |
return !( | |
(pos === 'absolute' || pos === 'fixed') || | |
(el.rect.width === 0 && el.rect.height === 0) | |
); | |
}); | |
if (children.length === 0) { | |
return { | |
width: 0, | |
height: 0 | |
}; | |
} | |
var totRect = children.reduce(function (tot, el) { | |
return (!tot ? | |
el.rect : { | |
top: Math.min(tot.top, el.rect.top), | |
left: Math.min(tot.left, el.rect.left), | |
right: Math.max(tot.right, el.rect.right), | |
bottom: Math.max(tot.bottom, el.rect.bottom) | |
}); | |
}, null); | |
return { | |
width: totRect.right - totRect.left, | |
height: totRect.bottom - totRect.top | |
}; | |
} | |
/* | |
list can be either [[x, y], [x, y]] or [x, y] | |
*/ | |
function createTouchList(target, list) { | |
if (Array.isArray(list) && list[0] && !Array.isArray(list[0])) { | |
list = [list]; | |
} | |
list = list.map(function (entry, index) { | |
return createTouch(entry[0], entry[1], target, index + 1); | |
}); | |
return document.createTouchList.apply(document, list); | |
} | |
function createTouch(x, y, target, id) { | |
return document.createTouch(window, target, | |
//identifier | |
id || 1, | |
//pageX / clientX | |
x, | |
//pageY / clientY | |
y, | |
//screenX | |
x, | |
//screenY | |
y | |
); | |
} | |
//http://stackoverflow.com/questions/7056026/variation-of-e-touches-e-targettouches-and-e-changedtouches | |
function initTouchEvent(touchEvent, type, touches) { | |
var touch1 = touches[0]; | |
return touchEvent.initTouchEvent( | |
//touches | |
touches, | |
//targetTouches | |
touches, | |
//changedTouches | |
touches, | |
//type | |
type, | |
//view | |
window, | |
//screenX | |
touch1.screenX, | |
//screenY | |
touch1.screenY, | |
//clientX | |
touch1.clientX, | |
//clientY | |
touch1.clientY, | |
//ctrlKey | |
false, | |
//altKey | |
false, | |
//shiftKey | |
false, | |
//metaKey | |
false | |
); | |
} | |
function createTouchEvent(elem, type, touches) { | |
var touchEvent = document.createEvent('TouchEvent'); | |
if (Array.isArray(touches)) { | |
touches = createTouchList(elem, touches); | |
} | |
function dispatch(getEvent) { | |
initTouchEvent(touchEvent, type, touches); | |
if (typeof getEvent === 'function'){ | |
getEvent.call(elem, touchEvent, elem); | |
} | |
elem.dispatchEvent(touchEvent); | |
} | |
dispatch.event = touchEvent; | |
return dispatch; | |
} | |
function apply(fn, arg, args) { | |
return fn.apply(null, [arg].concat(Array.prototype.slice.call(args))); | |
} | |
function swipeLeft() { | |
return apply(swipe, 'left', arguments); | |
} | |
function swipeRight() { | |
return apply(swipe, 'right', arguments); | |
} | |
function swipeTop(){ | |
return apply(swipe, 'top', arguments); | |
} | |
function swipeBottom(){ | |
return apply(swipe, 'bottom', arguments); | |
} | |
function round(num){ | |
return Math.round(num); | |
} | |
var HORIZONTAL_OFFSET = 45; | |
var VERTICAL_OFFSET = 10; | |
function swipe(direction, elem, ms, frames, getEvent) { | |
var elemSize = getChildrenSize(elem.parentNode); | |
var x; | |
var y; | |
var from; | |
var to; | |
var isVertical = direction === 'top' || direction === 'bottom'; | |
if (isVertical){ | |
y = elemSize.height; | |
x = elemSize.width / 2; | |
from = [x*0.95, VERTICAL_OFFSET].map(round); | |
to = [x*1.01, y-VERTICAL_OFFSET].map(round); | |
} else { | |
// horizontal | |
x = elemSize.width; | |
y = elemSize.height / 2; | |
from = [HORIZONTAL_OFFSET, y*0.98].map(round); | |
to = [x - HORIZONTAL_OFFSET, y*1.01].map(round); | |
} | |
if (direction === 'right' || direction === 'top') { | |
touchActionSequence(elem, from, to, ms, frames, getEvent); | |
} else { | |
touchActionSequence(elem, to, from, ms, frames, getEvent); | |
} | |
} | |
function getDiff(fromList, toList){ | |
return [ | |
toList[0] - fromList[0], | |
toList[1] - fromList[1] | |
]; | |
} | |
function getXandYFrame(startPoint, diffToWalk, currentProgress){ | |
return [ | |
Math.round( | |
Math.abs( | |
startPoint[0] + (diffToWalk[0] * currentProgress))), | |
Math.round( | |
Math.abs( | |
startPoint[1] + (diffToWalk[1] * currentProgress))) | |
]; | |
} | |
function touchActionSequence(elem, fromXandY, toXandY, ms, frames, getEvent) { | |
frames = frames || 10; | |
ms = Math.round((ms||1000) / frames); | |
// lets find difference from start to end and divide on frames | |
var diff = getDiff(fromXandY, toXandY); | |
var counter = frames; | |
var pos = getXandYFrame(fromXandY, diff, counter/frames); | |
var targetElement; | |
targetElement = document.elementFromPoint(pos[0], pos[1]); | |
setTimeout(function handler() { | |
counter--; | |
if (counter) { | |
pos = getXandYFrame(fromXandY, diff, counter/frames); | |
targetElement = document.elementFromPoint(pos[0], pos[1]); | |
createTouchEvent(targetElement||elem, 'touchmove', pos)(getEvent); | |
setTimeout(handler, ms); | |
} else { | |
createTouchEvent(targetElement||elem, 'touchend', [[0, 0]])(getEvent); | |
} | |
}, ms); | |
createTouchEvent(targetElement||elem, 'touchstart', pos)(getEvent); | |
} | |
function factory(){ | |
return { | |
_apply: apply, | |
_getXandYFrame: getXandYFrame, | |
_getDiff: getDiff, | |
swipeLeft: swipeLeft, | |
swipeRight: swipeRight, | |
swipeTop: swipeTop, | |
swipeBottom: swipeBottom, | |
touchActionSequence: touchActionSequence, | |
createTouchEvent: createTouchEvent | |
}; | |
} | |
if (typeof module !== 'undefined' && module.exports){ | |
module.exports = factory(); | |
} else { | |
window.mockPhantomTouchEvents = factory(); | |
} | |
it("Mocks TouchStart", function(){ | |
var canvas = document.createElement("canvas"); | |
document.body.appendChild(canvas); | |
var triggered = false; | |
canvas.addEventListener("touchstart", function(event) { | |
triggered = true; | |
}, false); | |
expect(triggered).toBe(false); | |
createTouchEvent(canvas, "touchstart", [0, 0]); | |
expect(triggered).toBe(true); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment