MediaWiki:TouchPunch.js

/*! * jQuery UI Touch Punch 0.2.3 * http://touchpunch.furf.com/ * * Copyright 2011–2014, Dave Furfero * Dual licensed under the MIT or GPL Version 2 licenses. * */ mw.loader.using([   'jquery.ui.widget',    'jquery.ui.mouse' ], function  {

// Detect touch support $.support.touch = 'ontouchend' in document;

// Ignore browsers without touch support if (!$.support.touch) { return; }

var mouseProto = $.ui.mouse.prototype, _mouseInit = mouseProto._mouseInit, _mouseDestroy = mouseProto._mouseDestroy, touchHandled;

/**  * Simulate a mouse event based on a corresponding touch event * @param {Object} event A touch event * @param {String} simulatedType The corresponding mouse event */ function simulateMouseEvent (event, simulatedType) {

// Ignore multi-touch events if (event.originalEvent.touches.length > 1) { return; }

event.preventDefault;

var touch = event.originalEvent.changedTouches[0], simulatedEvent = document.createEvent('MouseEvents'); // Initialize the simulated mouse event using the touch event's coordinates simulatedEvent.initMouseEvent(     simulatedType,    // type      true,             // bubbles                          true,             // cancelable                       window,           // view                             1,                // detail                           touch.screenX,    // screenX                          touch.screenY,    // screenY                          touch.clientX,    // clientX                          touch.clientY,    // clientY                          false,            // ctrlKey                          false,            // altKey                           false,            // shiftKey                         false,            // metaKey                          0,                // button                           null              // relatedTarget                  );

// Dispatch the simulated event to the target element event.target.dispatchEvent(simulatedEvent); }

/**  * Handle the jQuery UI widget's touchstart events * @param {Object} event The widget element's touchstart event */ mouseProto._touchStart = function (event) {

var self = this;

// Ignore the event if another widget is already being handled if (touchHandled || !self._mouseCapture(event.originalEvent.changedTouches[0])) { return; }

// Set the flag to prevent other widgets from inheriting the touch event touchHandled = true;

// Track movement to determine if interaction was a click self._touchMoved = false;

// Simulate the mouseover event simulateMouseEvent(event, 'mouseover');

// Simulate the mousemove event simulateMouseEvent(event, 'mousemove');

// Simulate the mousedown event simulateMouseEvent(event, 'mousedown'); };

/**  * Handle the jQuery UI widget's touchmove events * @param {Object} event The document's touchmove event */ mouseProto._touchMove = function (event) {

// Ignore event if not handled if (!touchHandled) { return; }

// Interaction was not a click this._touchMoved = true;

// Simulate the mousemove event simulateMouseEvent(event, 'mousemove'); };

/**  * Handle the jQuery UI widget's touchend events * @param {Object} event The document's touchend event */ mouseProto._touchEnd = function (event) {

// Ignore event if not handled if (!touchHandled) { return; }

// Simulate the mouseup event simulateMouseEvent(event, 'mouseup');

// Simulate the mouseout event simulateMouseEvent(event, 'mouseout');

// If the touch interaction did not move, it should trigger a click if (!this._touchMoved) {

// Simulate the click event simulateMouseEvent(event, 'click'); }

// Unset the flag to allow other widgets to inherit the touch event touchHandled = false; };

/**  * A duck punch of the $.ui.mouse _mouseInit method to support touch events. * This method extends the widget with bound touch event handlers that * translate touch events to mouse events and pass them to the widget's  * original mouse event handling methods. */ mouseProto._mouseInit = function  { var self = this;

// Delegate the touch handlers to the widget's element self.element.bind({     touchstart: $.proxy(self, '_touchStart'),      touchmove: $.proxy(self, '_touchMove'),      touchend: $.proxy(self, '_touchEnd')    });

// Call the original $.ui.mouse init method _mouseInit.call(self); };

/**  * Remove the touch event handlers */ mouseProto._mouseDestroy = function  { var self = this;

// Delegate the touch handlers to the widget's element self.element.unbind({     touchstart: $.proxy(self, '_touchStart'),      touchmove: $.proxy(self, '_touchMove'),      touchend: $.proxy(self, '_touchEnd')    });

// Call the original $.ui.mouse destroy method _mouseDestroy.call(self); };

});