static/js/mobile/appframework.desktopBrowsers.js
/**
* desktopBrowsers contributed by Carlos Ouro @ Badoo
* translates desktop browsers events to touch events and prevents defaults
* It can be used independently in other apps but it is required for using the touchLayer in the desktop
*
* @param {Function} $ The appframework selector function
*/
(function ($) {
"use strict";
var cancelClickMove = false;
//See if we can create a touch event
var tmp;
if($.os.supportsTouch) return;
try {
tmp = document.createEvent("TouchEvent");
return;
} catch (ex) {
}
$.os.supportsTouch=true;
var preventAll = function (e) {
e.preventDefault();
e.stopPropagation();
};
var ieThreshold=navigator.userAgent.match(/Phone/i)?2:7;
/**
* Stop propagation, and remove default behavior for everything but INPUT, TEXTAREA & SELECT fields
*
* @param {Event} event
* @param {HTMLElement} target
*/
var preventAllButInputs = function(event, target) {
var tag = target.tagName.toUpperCase();
if (tag.indexOf("SELECT") > -1 || tag.indexOf("OPTION") > -1 || tag.indexOf("TEXTAREA") > -1 || tag.indexOf("INPUT") > -1) {
return;
}
preventAll(event);
};
var redirectMouseToTouch = function (type, originalEvent, newTarget,skipPrevent) {
var theTarget = newTarget ? newTarget : originalEvent.target;
if(!skipPrevent)
preventAllButInputs(originalEvent, theTarget);
var touchevt = document.createEvent("MouseEvent");
touchevt.initEvent(type, true, true);
touchevt.initMouseEvent(type, true, true, window, originalEvent.detail, originalEvent.screenX, originalEvent.screenY, originalEvent.clientX, originalEvent.clientY, originalEvent.ctrlKey, originalEvent.shiftKey, originalEvent.altKey, originalEvent.metaKey, originalEvent.button, originalEvent.relatedTarget);
touchevt.touches= new $.feat.TouchList();
touchevt.changedTouches = new $.feat.TouchList();
touchevt.targetTouches = new $.feat.TouchList();
var thetouch=new $.feat.Touch();
thetouch.pageX=originalEvent.pageX;
thetouch.pageY=originalEvent.pageY;
thetouch.target=originalEvent.target;
touchevt.changedTouches._add(thetouch);
if (type !== "touchend") {
touchevt.touches = touchevt.changedTouches;
touchevt.targetTouches = touchevt.changedTouches;
}
//target
touchevt.mouseToTouch = true;
if ($.os.ie) {
// handle inline event handlers for target and parents (for bubbling)
var elem = originalEvent.target;
while (elem !== null) {
if (elem.hasAttribute("on" + type)) {
eval(elem.getAttribute("on" + type));
}
elem = elem.parentElement;
}
}
theTarget.dispatchEvent(touchevt);
};
var mouseDown = false,
lastTarget = null,
prevX=0,
prevY=0;
if (!window.navigator.msPointerEnabled) {
document.addEventListener("mousedown", function (e) {
mouseDown = true;
lastTarget = e.target;
if (e.target.nodeName.toLowerCase() === "a" && e.target.href.toLowerCase() === "javascript:;")
e.target.href = "#";
redirectMouseToTouch("touchstart", e);
cancelClickMove = false;
prevX=e.clientX;
prevY=e.clientY;
}, true);
document.addEventListener("mouseup", function (e) {
if (!mouseDown) return;
redirectMouseToTouch("touchend", e, lastTarget); //bind it to initial mousedown target
lastTarget = null;
mouseDown = false;
}, true);
document.addEventListener("mousemove", function (e) {
if(e.clientX===prevX&&e.clientY===prevY) return;
if (!mouseDown) return;
redirectMouseToTouch("touchmove", e, lastTarget);
cancelClickMove = true;
}, true);
} else { //Win8
var skipMove=false;
document.addEventListener("MSPointerDown", function (e) {
mouseDown = true;
skipMove=true;
lastTarget = e.target;
if (e.target.nodeName.toLowerCase() === "a" && e.target.href.toLowerCase() === "javascript:;")
e.target.href = "";
redirectMouseToTouch("touchstart", e,null,true);
cancelClickMove = false;
prevX=e.clientX;
prevY=e.clientY;
return true;
}, true);
document.addEventListener("MSPointerUp", function (e) {
if (!mouseDown) return;
redirectMouseToTouch("touchend", e, lastTarget,true); // bind it to initial mousedown target
lastTarget = null;
mouseDown = false;
return true;
}, true);
document.addEventListener("MSPointerMove", function (e) {
//IE is very flakey...we need 7 pixel movement before we trigger it
if(Math.abs(e.clientX-prevX)<=ieThreshold||Math.abs(e.clientY-prevY)<=ieThreshold) return;
if (!mouseDown) return;
redirectMouseToTouch("touchmove", e, lastTarget,true);
cancelClickMove = true;
return true;
}, true);
}
// prevent all mouse events which don't exist on touch devices
document.addEventListener("drag", preventAll, true);
document.addEventListener("dragstart", preventAll, true);
document.addEventListener("dragenter", preventAll, true);
document.addEventListener("dragover", preventAll, true);
document.addEventListener("dragleave", preventAll, true);
document.addEventListener("dragend", preventAll, true);
document.addEventListener("drop", preventAll, true);
// Allow selection of input elements
document.addEventListener("selectstart", function(e){
preventAllButInputs(e, e.target);
}, true);
document.addEventListener("click", function (e) {
if (!e.mouseToTouch && e.target === lastTarget) {
preventAll(e);
}
if (cancelClickMove) {
preventAll(e);
cancelClickMove = false;
}
}, true);
})(jQuery,window);