Spaces:
Paused
Paused
| /*! | |
| * jQuery UI Touch Punch 1.0.9 as modified by RWAP Software | |
| * based on original touchpunch v0.2.3 which has not been updated since 2014 | |
| * | |
| * Updates by RWAP Software to take account of various suggested changes on the original code issues | |
| * | |
| * Original: https://github.com/furf/jquery-ui-touch-punch | |
| * Copyright 2011–2014, Dave Furfero | |
| * Dual licensed under the MIT or GPL Version 2 licenses. | |
| * | |
| * Fork: https://github.com/RWAP/jquery-ui-touch-punch | |
| * | |
| * Depends: | |
| * jquery.ui.widget.js | |
| * jquery.ui.mouse.js | |
| */ | |
| (function( factory ) { | |
| if ( typeof define === "function" && define.amd ) { | |
| // AMD. Register as an anonymous module. | |
| define([ "jquery", "jquery-ui" ], factory ); | |
| } else { | |
| // Browser globals | |
| factory( jQuery ); | |
| } | |
| }(function ($) { | |
| // Detect touch support - Windows Surface devices and other touch devices | |
| $.mspointer = window.navigator.msPointerEnabled; | |
| $.touch = ( 'ontouchstart' in document | |
| || 'ontouchstart' in window | |
| || window.TouchEvent | |
| || (window.DocumentTouch && document instanceof DocumentTouch) | |
| || navigator.maxTouchPoints > 0 | |
| || navigator.msMaxTouchPoints > 0 | |
| ); | |
| // Ignore browsers without touch or mouse support | |
| if ((!$.touch && !$.mspointer) || !$.ui.mouse) { | |
| return; | |
| } | |
| let mouseProto = $.ui.mouse.prototype, | |
| _mouseInit = mouseProto._mouseInit, | |
| _mouseDestroy = mouseProto._mouseDestroy, | |
| touchHandled; | |
| /** | |
| * Get the x,y position of a touch event | |
| * @param {Object} event A touch event | |
| */ | |
| function getTouchCoords (event) { | |
| return { | |
| x: event.originalEvent.changedTouches[0].pageX, | |
| y: event.originalEvent.changedTouches[0].pageY | |
| }; | |
| } | |
| /** | |
| * 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; | |
| } | |
| //Ignore input or textarea elements so user can still enter text | |
| if ($(event.target).is("input") || $(event.target).is("textarea")) { | |
| return; | |
| } | |
| // Prevent "Ignored attempt to cancel a touchmove event with cancelable=false" errors | |
| if (event.cancelable) { | |
| event.preventDefault(); | |
| } | |
| let 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) { | |
| let self = this; | |
| // Interaction time | |
| this._startedMove = event.timeStamp; | |
| // Track movement to determine if interaction was a click | |
| self._startPos = getTouchCoords(event); | |
| // 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 moved | |
| 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 | |
| // Check for this in two ways - length of time of simulation and distance moved | |
| // Allow for Apple Stylus to be used also | |
| let timeMoving = event.timeStamp - this._startedMove; | |
| if (!this._touchMoved || timeMoving < 500) { | |
| // Simulate the click event | |
| simulateMouseEvent(event, 'click'); | |
| } else { | |
| let endPos = getTouchCoords(event); | |
| if ((Math.abs(endPos.x - this._startPos.x) < 10) && (Math.abs(endPos.y - this._startPos.y) < 10)) { | |
| // If the touch interaction did not move, it should trigger a click | |
| if (!this._touchMoved || event.originalEvent.changedTouches[0].touchType === 'stylus') { | |
| // Simulate the click event | |
| simulateMouseEvent(event, 'click'); | |
| } | |
| } | |
| } | |
| // Unset the flag to determine the touch movement stopped | |
| this._touchMoved = false; | |
| // 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 () { | |
| let self = this; | |
| // Microsoft Surface Support = remove original touch Action | |
| if ($.support.mspointer) { | |
| self.element[0].style.msTouchAction = 'none'; | |
| } | |
| // Delegate the touch handlers to the widget's element | |
| self.element.on({ | |
| 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 () { | |
| let self = this; | |
| // Delegate the touch handlers to the widget's element | |
| self.element.off({ | |
| touchstart: $.proxy(self, '_touchStart'), | |
| touchmove: $.proxy(self, '_touchMove'), | |
| touchend: $.proxy(self, '_touchEnd') | |
| }); | |
| // Call the original $.ui.mouse destroy method | |
| _mouseDestroy.call(self); | |
| }; | |
| })); | |