From 02e5ffa132cd6f4c76c02a5e8ba6a8d0cc49d709 Mon Sep 17 00:00:00 2001 From: venkatesh-ramalingam Date: Fri, 22 Aug 2014 21:12:40 +0530 Subject: [PATCH] Translating mouse events into touch events Add the required objects[touches, changedTouches, targetTouches] inside the event object generated by the mouse events and relay them as touch. This causes the gestures to be handled in desktop browsers just the same way like they are handled in the touch devices. --- .../ember-touch/lib/system/gesture_manager.js | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/packages/ember-touch/lib/system/gesture_manager.js b/packages/ember-touch/lib/system/gesture_manager.js index 94fb582..a142f06 100644 --- a/packages/ember-touch/lib/system/gesture_manager.js +++ b/packages/ember-touch/lib/system/gesture_manager.js @@ -99,6 +99,121 @@ Em.GestureManager = Em.Object.extend({ return this._invokeEvent('touchCancel',evt); }, + /* Taking mouseDown, mouseMove, mouseLeave and mouseUp events and mapping them to + * touchStart, touchMove, touchEnd events. + * Add the necessary properties to the event object for click and make it look + * like touch event object. Then give it to Em.Gesture. + * Refer http://goo.gl/GmQg4K to know more about touch event object. + * */ + /** + Relays mouseDown as touchStart events to all the gesture recognizers to the + specified view + + @return Boolen + */ + mouseDown: function(evt, view) { + /* Set _currentEventProperties to the view to track down the mouse events. + * 1. mouseDown followed by mouseMove can only be considered as touchMove + * 2. targetTouches can only be filled if mouseDown and mouseUp have occurred on the same target + * */ + var currentEventProp = { + "savedTarget": evt.target, + "isTouchStarted": true + }; + view.set("_currentEventProperties", currentEventProp); + + evt = this._convertToTouchObj(evt, view); + return this._invokeEvent('touchStart',evt); + }, + + /** + Relays mouseMove as touchMove events to all the gesture recognizers to the + specified view + + @return Boolen + */ + mouseMove: function(evt, view) { + var currentEventProp = view.get("_currentEventProperties"); + // Check if mouseDown event has already been fired in the view and invoke touchMove + if(typeof currentEventProp !== "undefined" && currentEventProp.isTouchStarted) { + evt = this._convertToTouchObj(evt, view); + return this._invokeEvent('touchMove', evt); + } else { + // Do nothing when mouse just hovers on an element + return; + } + }, + + /** + Relays mouseLeave as touchEnd event to all the gesture recognizers to the + specified view + NOTE: mouseLeave should actually be mapped to touchCancel. + Doing so since we have not handled touchCancel anywhere in our views + + @return Boolen + */ + mouseLeave: function(evt, view) { + evt = this._convertToTouchObj(evt, view); + // Clear _currentEventProperties of the view + var currentEventProp = { + "savedTarget": '', + "isTouchStarted": false + }; + view.set("_currentEventProperties", currentEventProp); + + return this._invokeEvent('touchEnd', evt); + }, + + /** + Relays mouseUp as touchEnd events to all the gesture recognizers to the + specified view + + @return Boolen + */ + mouseUp: function(evt, view) { + evt = this._convertToTouchObj(evt, view); + // Clear _currentEventProperties of the view + var currentEventProp = { + "savedTarget": '', + "isTouchStarted": false + }; + view.set("_currentEventProperties", currentEventProp); + + return this._invokeEvent('touchEnd',evt); + }, + + /** Converts click event object into touch event object by adding + * the most needed properties like touches, changedTouches and targetTouches + * Each of these would have clientX, clientY, identifier, pageX, pageY, screenX, screenY, target + * targetTouches will have the event object only if the mouse is in the same target element + * from mouseDown through mouseUp + * @param Object evt Event object of click + * @param Object view Target view. Used to check mouseDown target + * @return Object (touch event object) modified event object + */ + _convertToTouchObj: function(evt, view) { + var touches = [], targetTouches = []; + touches[0] = { + clientX: evt.clientX, + clientY: evt.clientY, + identifier: 0, + pageX: evt.pageX, + pageY: evt.pageY, + screenX: evt.screenX, + screenY: evt.screenY, + target: evt.target + }; + + if(evt.target === view.getPath("_currentEventProperties.savedTarget")) { + // Check if the target element is the same element as in mouseDown + targetTouches = touches; + } + evt.originalEvent.touches = evt.originalEvent.changedTouches = touches; + evt.originalEvent.targetTouches = targetTouches; + + return evt; + }, + /** Relays an event to the gesture recognizers. Used internally by the touch event listeners. Propagates the event to the parentViews.