From 5db124d1c0ec506d48ff76789e471538d5f26497 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Thu, 23 Apr 2020 18:53:29 +0100 Subject: [PATCH] Fix for issue # 165 --- README.md | 2 + bower.json | 2 +- package.json | 2 +- src/2.0.3/jquery.mobile-events.js | 940 ++++++++++++++++++++++++++ src/2.0.3/jquery.mobile-events.min.js | 27 + src/jquery.mobile-events.js | 61 +- src/jquery.mobile-events.min.js | 2 +- 7 files changed, 1007 insertions(+), 29 deletions(-) create mode 100644 src/2.0.3/jquery.mobile-events.js create mode 100644 src/2.0.3/jquery.mobile-events.min.js diff --git a/README.md b/README.md index bbfd2e2..22e29bc 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,8 @@ As explained, the events are each triggered by native touch events, or alternati After almost 2 years in public beta, I am pleased to announce that the library is now officially launched as **version 1.0.0**. I'll be updating the version history over time with digests of fixes, features and improvements: ++ **Version 2.0.3** (2020-04-23) + + Fix for bug [#165](https://github.com/benmajor/jQuery-Touch-Events/issues/165) + **Version 2.0.2** (2020-04-21) + Fix for binding events to `document` and `window`. + Update NPM repo so that latest releases are detected. diff --git a/bower.json b/bower.json index 8676901..7d3e959 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jquery-touch-events", - "version": "2.0.2", + "version": "2.0.3", "main": "src/jquery.mobile-events.js", "ignore": [ "bower.json" diff --git a/package.json b/package.json index 622a6bd..07e77c7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@benmajor/jquery-touch-events", - "version": "2.0.2", + "version": "2.0.3", "description": "Polyfill to remove click delays and unify pointer device events.", "main": "src/jquery.mobile-events.js", "scripts": { diff --git a/src/2.0.3/jquery.mobile-events.js b/src/2.0.3/jquery.mobile-events.js new file mode 100644 index 0000000..627afdd --- /dev/null +++ b/src/2.0.3/jquery.mobile-events.js @@ -0,0 +1,940 @@ +/*! + * jQuery Mobile Events + * by Ben Major + * + * Copyright 2011-2019, Ben Major + * Licensed under the MIT License: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +"use strict"; + +(function ($) { + $.attrFn = $.attrFn || {}; + + var touchCapable = ('ontouchstart' in window), + + settings = { + tap_pixel_range: 5, + swipe_h_threshold: 50, + swipe_v_threshold: 50, + taphold_threshold: 750, + doubletap_int: 500, + shake_threshold: 15, + + touch_capable: touchCapable, + orientation_support: ('orientation' in window && 'onorientationchange' in window), + + startevent: (touchCapable) ? 'touchstart' : 'mousedown', + endevent: (touchCapable) ? 'touchend' : 'mouseup', + moveevent: (touchCapable) ? 'touchmove' : 'mousemove', + tapevent: (touchCapable) ? 'tap' : 'click', + scrollevent: (touchCapable) ? 'touchmove' : 'scroll', + + hold_timer: null, + tap_timer: null + }; + + // Declare touch namespace: + $.touch = { }; + + // Convenience functions: + $.isTouchCapable = function() { return settings.touch_capable; }; + $.getStartEvent = function() { return settings.startevent; }; + $.getEndEvent = function() { return settings.endevent; }; + $.getMoveEvent = function() { return settings.moveevent; }; + $.getTapEvent = function() { return settings.tapevent; }; + $.getScrollEvent = function() { return settings.scrollevent; }; + + // SETTERS: + // Set the X threshold of swipe events: + $.touch.setSwipeThresholdX = function( threshold ) { + if( typeof threshold !== 'number' ) { throw new Error('Threshold parameter must be a type of number'); } + settings.swipe_h_threshold = threshold; + }; + + // Set the Y threshold of swipe events: + $.touch.setSwipeThresholdY = function( threshold ) { + if( typeof threshold !== 'number' ) { throw new Error('Threshold parameter must be a type of number'); } + settings.swipe_v_threshold = threshold; + }; + + // Set the double tap interval: + $.touch.setDoubleTapInt = function( interval ) { + if( typeof interval !== 'number' ) { throw new Error('Interval parameter must be a type of number'); } + settings.doubletap_int = interval; + }; + + // Set the taphold threshold: + $.touch.setTapHoldThreshold = function( threshold ) { + if( typeof threshold !== 'number' ) { throw new Error('Threshold parameter must be a type of number'); } + settings.taphold_threshold = threshold; + }; + + // Set the pixel range for tapas: + $.touch.setTapRange = function( range ) { + if( typeof range !== 'number' ) { throw new Error('Ranger parameter must be a type of number'); } + settings.tap_pixel_range = threshold; + }; + + // Add Event shortcuts: + $.each(['tapstart', 'tapend', 'tapmove', 'tap', 'singletap', 'doubletap', 'taphold', 'swipe', 'swipeup', 'swiperight', 'swipedown', 'swipeleft', 'swipeend', 'scrollstart', 'scrollend', 'orientationchange', 'tap2', 'taphold2'], function (i, name) { + $.fn[name] = function (fn) { + return fn ? this.on(name, fn) : this.trigger(name); + }; + + $.attrFn[name] = true; + }); + + // tapstart Event: + $.event.special.tapstart = { + setup: function () { + + var thisObject = this, + $this = $(thisObject); + + $this.on(settings.startevent, function tapStartFunc(e) { + + $this.data('callee', tapStartFunc); + if (e.which && e.which !== 1) { + return false; + } + + var offset = ($this.get(0) !== window && $this.get(0) !== document) ? $this.offset() : { left: 0, top: 0 }; + var origEvent = e.originalEvent, + touchData = { + 'position': { + 'x': ((settings.touch_capable) ? origEvent.touches[0].pageX : e.pageX), + 'y': (settings.touch_capable) ? origEvent.touches[0].pageY : e.pageY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offset.left) : Math.round(e.pageX - offset.left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offset.top) : Math.round(e.pageY - offset.top) + }, + 'time': Date.now(), + 'target': e.target + }; + + triggerCustomEvent(thisObject, 'tapstart', e, touchData); + return true; + }); + }, + + remove: function () { + $(this).off(settings.startevent, $(this).data.callee); + } + }; + + // tapmove Event: + $.event.special.tapmove = { + setup: function() { + var thisObject = this, + $this = $(thisObject); + + $this.on(settings.moveevent, function tapMoveFunc(e) { + $this.data('callee', tapMoveFunc); + + var offset = ($this.get(0) !== window && $this.get(0) !== document) ? $this.offset() : { left: 0, top: 0 }; + var origEvent = e.originalEvent, + touchData = { + 'position': { + 'x': ((settings.touch_capable) ? origEvent.touches[0].pageX : e.pageX), + 'y': (settings.touch_capable) ? origEvent.touches[0].pageY : e.pageY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offset.left) : Math.round(e.pageX - offset.left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offset.top) : Math.round(e.pageY - offset.top) + }, + 'time': Date.now(), + 'target': e.target + }; + + triggerCustomEvent(thisObject, 'tapmove', e, touchData); + return true; + }); + }, + remove: function() { + $(this).off(settings.moveevent, $(this).data.callee); + } + }; + + // tapend Event: + $.event.special.tapend = { + setup: function () { + var thisObject = this, + $this = $(thisObject); + + $this.on(settings.endevent, function tapEndFunc(e) { + // Touch event data: + $this.data('callee', tapEndFunc); + + var offset = ($this.get(0) !== window && $this.get(0) !== document) ? $this.offset() : { left: 0, top: 0 }; + var origEvent = e.originalEvent; + var touchData = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].pageX : e.pageX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].pageY : e.pageY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offset.left) : Math.round(e.pageX - offset.left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offset.top) : Math.round(e.pageY - offset.top) + }, + 'time': Date.now(), + 'target': e.target + }; + triggerCustomEvent(thisObject, 'tapend', e, touchData); + return true; + }); + }, + remove: function () { + $(this).off(settings.endevent, $(this).data.callee); + } + }; + + // taphold Event: + $.event.special.taphold = { + setup: function () { + var thisObject = this, + $this = $(thisObject), + origTarget, + start_pos = { + x: 0, + y: 0 + }, + end_x = 0, + end_y = 0; + + $this.on(settings.startevent, function tapHoldFunc1(e) { + if (e.which && e.which !== 1) { + return false; + } else { + $this.data('tapheld', false); + origTarget = e.target; + + var origEvent = e.originalEvent; + var start_time = Date.now(), + startPosition = { + 'x': (settings.touch_capable) ? origEvent.touches[0].pageX : e.pageX, + 'y': (settings.touch_capable) ? origEvent.touches[0].pageY : e.pageY + }, + startOffset = { + 'x': (settings.touch_capable) ? origEvent.touches[0].pageX - origEvent.touches[0].target.offsetLeft : e.offsetX, + 'y': (settings.touch_capable) ? origEvent.touches[0].pageY - origEvent.touches[0].target.offsetTop : e.offsetY + }; + + start_pos.x = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageX : e.pageX; + start_pos.y = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageY : e.pageY; + + end_x = start_pos.x; + end_y = start_pos.y; + + // Get the element's threshold: + var ele_threshold = ($this.parent().data('threshold')) ? $this.parent().data('threshold') : $this.data('threshold'), + threshold = (typeof ele_threshold !== 'undefined' && ele_threshold !== false && parseInt(ele_threshold)) ? parseInt(ele_threshold) : settings.taphold_threshold; + + $this.data('hold_timer', window.setTimeout(function () { + + var diff_x = (start_pos.x - end_x), + diff_y = (start_pos.y - end_y); + + if (e.target == origTarget && ((start_pos.x == end_x && start_pos.y == end_y) || (diff_x >= -(settings.tap_pixel_range) && diff_x <= settings.tap_pixel_range && diff_y >= -(settings.tap_pixel_range) && diff_y <= settings.tap_pixel_range))) { + $this.data('tapheld', true); + + var end_time = Date.now(); + + var duration = end_time - start_time, + touches = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches : [ e ], + touchData = [ ]; + + var offset = ($this.get(0) !== window && $this.get(0) !== document) ? $this.offset() : { left: 0, top: 0 }; + for( var i = 0; i < touches.length; i++) + { + var touch = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[i].pageX : e.pageX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[i].pageY : e.pageY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - offset.left) : Math.round(e.pageX - offset.left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - offset.top) : Math.round(e.pageY - offset.top) + }, + 'time': Date.now(), + 'target': e.target, + 'duration': duration + }; + + touchData.push( touch ); + } + + var evt_name = ( touches.length == 2 ) ? 'taphold2' : 'taphold'; + + $this.data('callee1', tapHoldFunc1); + + triggerCustomEvent(thisObject, evt_name, e, touchData); + } + }, threshold) ); + + return true; + } + }).on(settings.endevent, function tapHoldFunc2() { + $this.data('callee2', tapHoldFunc2); + $this.data('tapheld', false); + window.clearTimeout( $this.data('hold_timer') ); + }) + .on(settings.moveevent, function tapHoldFunc3(e) { + $this.data('callee3', tapHoldFunc3); + + end_x = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageX : e.pageX; + end_y = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageY : e.pageY; + }); + }, + + remove: function () { + $(this).off(settings.startevent, $(this).data.callee1).off(settings.endevent, $(this).data.callee2).off(settings.moveevent, $(this).data.callee3); + } + }; + + // doubletap Event: + $.event.special.doubletap = { + setup: function () { + var thisObject = this, + $this = $(thisObject), + origTarget, + action, + firstTap = null, + origEvent, + cooloff, + cooling = false; + + $this.on(settings.startevent, function doubleTapFunc1(e) { + if (e.which && e.which !== 1) { + return false; + } + + $this.data('doubletapped', false); + origTarget = e.target; + $this.data('callee1', doubleTapFunc1); + + origEvent = e.originalEvent; + if (!firstTap) { + var offset = ($this.get(0) !== window && $this.get(0) !== document) ? $this.offset() : { left: 0, top: 0 }; + firstTap = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].pageX : e.pageX, + 'y': (settings.touch_capable) ? origEvent.touches[0].pageY : e.pageY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offset.left) : Math.round(e.pageX - offset.left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offset.top) : Math.round(e.pageY - offset.top) + }, + 'time': Date.now(), + 'target': e.target, + 'element': e.originalEvent.srcElement, + 'index': $(e.target).index() + }; + } + + return true; + }).on(settings.endevent, function doubleTapFunc2(e) { + + var now = Date.now(); + var lastTouch = $this.data('lastTouch') || now + 1; + var delta = now - lastTouch; + window.clearTimeout(action); + $this.data('callee2', doubleTapFunc2); + + if (delta < settings.doubletap_int && ($(e.target).index() == firstTap.index) && delta > 100) { + $this.data('doubletapped', true); + window.clearTimeout(settings.tap_timer); + + // Now get the current event: + var offset = ($this.get(0) !== window && $this.get(0) !== document) ? $this.offset() : { left: 0, top: 0 }; + var lastTap = { + 'position': { + 'x': (settings.touch_capable) ? e.originalEvent.changedTouches[0].pageX : e.pageX, + 'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].pageY : e.pageY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offset.left) : Math.round(e.pageX - offset.left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offset.top) : Math.round(e.pageY - offset.top) + }, + 'time': Date.now(), + 'target': e.target, + 'element': e.originalEvent.srcElement, + 'index': $(e.target).index() + }; + + var touchData = { + 'firstTap': firstTap, + 'secondTap': lastTap, + 'interval': lastTap.time - firstTap.time + }; + + if (!cooling) { + triggerCustomEvent(thisObject, 'doubletap', e, touchData); + firstTap = null; + } + + cooling = true; + + cooloff = window.setTimeout(function () { + cooling = false; + }, settings.doubletap_int); + + } else { + $this.data('lastTouch', now); + action = window.setTimeout(function () { + firstTap = null; + window.clearTimeout(action); + }, settings.doubletap_int, [e]); + } + $this.data('lastTouch', now); + }); + }, + remove: function () { + $(this).off(settings.startevent, $(this).data.callee1).off(settings.endevent, $(this).data.callee2); + } + }; + + // singletap Event: + // This is used in conjuction with doubletap when both events are needed on the same element + $.event.special.singletap = { + setup: function () { + var thisObject = this, + $this = $(thisObject), + origTarget = null, + startTime = null, + start_pos = { + x: 0, + y: 0 + }; + + $this.on(settings.startevent, function singleTapFunc1(e) { + if (e.which && e.which !== 1) { + return false; + } else { + startTime = Date.now(); + origTarget = e.target; + $this.data('callee1', singleTapFunc1); + + // Get the start x and y position: + start_pos.x = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageX : e.pageX; + start_pos.y = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageY : e.pageY; + + return true; + } + }).on(settings.endevent, function singleTapFunc2(e) { + $this.data('callee2', singleTapFunc2); + if (e.target == origTarget) { + + // Get the end point: + var end_pos_x = (e.originalEvent.changedTouches) ? e.originalEvent.changedTouches[0].pageX : e.pageX, + end_pos_y = (e.originalEvent.changedTouches) ? e.originalEvent.changedTouches[0].pageY : e.pageY; + + // We need to check if it was a taphold: + + settings.tap_timer = window.setTimeout(function () { + + var diff_x = (start_pos.x - end_pos_x), diff_y = (start_pos.y - end_pos_y); + + if(!$this.data('doubletapped') && !$this.data('tapheld') && (((start_pos.x == end_pos_x) && (start_pos.y == end_pos_y)) || (diff_x >= -(settings.tap_pixel_range) && diff_x <= settings.tap_pixel_range && diff_y >= -(settings.tap_pixel_range) && diff_y <= settings.tap_pixel_range))) { + + var offset = ($this.get(0) !== window && $this.get(0) !== document) ? $this.offset() : { left: 0, top: 0 }; + var origEvent = e.originalEvent; + var touchData = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].pageX : e.pageX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].pageY : e.pageY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offset.left) : Math.round(e.pageX - offset.left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offset.top) : Math.round(e.pageY - offset.top) + }, + 'time': Date.now(), + 'target': e.target + }; + + // Was it a taphold? + if((touchData.time - startTime) < settings.taphold_threshold) + { + triggerCustomEvent(thisObject, 'singletap', e, touchData); + } + } + }, settings.doubletap_int); + } + }); + }, + + remove: function () { + $(this).off(settings.startevent, $(this).data.callee1).off(settings.endevent, $(this).data.callee2); + } + }; + + // tap Event: + $.event.special.tap = { + setup: function () { + var thisObject = this, + $this = $(thisObject), + started = false, + origTarget = null, + start_time, + start_pos = { + x: 0, + y: 0 + }, + touches; + + $this.on(settings.startevent, function tapFunc1(e) { + $this.data('callee1', tapFunc1); + + if( e.which && e.which !== 1 ) + { + return false; + } + else + { + started = true; + start_pos.x = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageX : e.pageX; + start_pos.y = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageY : e.pageY; + start_time = Date.now(); + origTarget = e.target; + + touches = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches : [ e ]; + return true; + } + }).on(settings.endevent, function tapFunc2(e) { + $this.data('callee2', tapFunc2); + + // Only trigger if they've started, and the target matches: + var end_x = (e.originalEvent.targetTouches) ? e.originalEvent.changedTouches[0].pageX : e.pageX, + end_y = (e.originalEvent.targetTouches) ? e.originalEvent.changedTouches[0].pageY : e.pageY, + diff_x = (start_pos.x - end_x), + diff_y = (start_pos.y - end_y), + eventName; + + if (origTarget == e.target && started && ((Date.now() - start_time) < settings.taphold_threshold) && ((start_pos.x == end_x && start_pos.y == end_y) || (diff_x >= -(settings.tap_pixel_range) && diff_x <= settings.tap_pixel_range && diff_y >= -(settings.tap_pixel_range) && diff_y <= settings.tap_pixel_range))) { + var offset = ($this.get(0) !== window && $this.get(0) !== document) ? $this.offset() : { left: 0, top: 0 }; + var origEvent = e.originalEvent; + var touchData = [ ]; + + for( var i = 0; i < touches.length; i++) + { + var touch = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[i].pageX : e.pageX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[i].pageY : e.pageY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - offset.left) : Math.round(e.pageX - offset.left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - offset.top) : Math.round(e.pageY - offset.top) + }, + 'time': Date.now(), + 'target': e.target + }; + + touchData.push( touch ); + } + + var evt_name = ( touches.length == 2 ) ? 'tap2' : 'tap'; + + triggerCustomEvent(thisObject, evt_name, e, touchData); + } + }); + }, + + remove: function () { + $(this).off(settings.startevent, $(this).data.callee1).off(settings.endevent, $(this).data.callee2); + } + }; + + // swipe Event (also handles swipeup, swiperight, swipedown and swipeleft): + $.event.special.swipe = { + setup: function () { + var thisObject = this, + $this = $(thisObject), + started = false, + hasSwiped = false, + originalCoord = { + x: 0, + y: 0 + }, + finalCoord = { + x: 0, + y: 0 + }, + startEvnt; + + // Screen touched, store the original coordinate + + function touchStart(e) { + $this = $(e.currentTarget); + $this.data('callee1', touchStart); + originalCoord.x = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageX : e.pageX; + originalCoord.y = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageY : e.pageY; + finalCoord.x = originalCoord.x; + finalCoord.y = originalCoord.y; + started = true; + var offset = ($this.get(0) !== window && $this.get(0) !== document) ? $this.offset() : { left: 0, top: 0 }; + var origEvent = e.originalEvent; + // Read event data into our startEvt: + startEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].pageX : e.pageX, + 'y': (settings.touch_capable) ? origEvent.touches[0].pageY : e.pageY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offset.left) : Math.round(e.pageX - offset.left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offset.top) : Math.round(e.pageY - offset.top) + }, + 'time': Date.now(), + 'target': e.target + }; + } + + // Store coordinates as finger is swiping + + function touchMove(e) { + $this = $(e.currentTarget); + $this.data('callee2', touchMove); + finalCoord.x = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageX : e.pageX; + finalCoord.y = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageY : e.pageY; + + var swipedir; + + // We need to check if the element to which the event was bound contains a data-xthreshold | data-vthreshold: + var ele_x_threshold = ($this.parent().data('xthreshold')) ? $this.parent().data('xthreshold') : $this.data('xthreshold'), + ele_y_threshold = ($this.parent().data('ythreshold')) ? $this.parent().data('ythreshold') : $this.data('ythreshold'), + h_threshold = (typeof ele_x_threshold !== 'undefined' && ele_x_threshold !== false && parseInt(ele_x_threshold)) ? parseInt(ele_x_threshold) : settings.swipe_h_threshold, + v_threshold = (typeof ele_y_threshold !== 'undefined' && ele_y_threshold !== false && parseInt(ele_y_threshold)) ? parseInt(ele_y_threshold) : settings.swipe_v_threshold; + + if (Math.abs(finalCoord.x - originalCoord.x) > Math.abs(finalCoord.y - originalCoord.y)) { + if (originalCoord.x < finalCoord.x && (finalCoord.x - originalCoord.x > h_threshold)) { + swipedir = 'swiperight'; + } + if (originalCoord.x > finalCoord.x && (originalCoord.x - finalCoord.x > h_threshold)) { + swipedir = 'swipeleft'; + } + } + else { + if (originalCoord.y > finalCoord.y && (originalCoord.y - finalCoord.y > v_threshold)) { + swipedir = 'swipeup'; + } + if (originalCoord.y < finalCoord.y && (finalCoord.y - originalCoord.y > v_threshold)) { + swipedir = 'swipedown'; + } + } + + if (swipedir != undefined && started) { + originalCoord.x = 0; + originalCoord.y = 0; + finalCoord.x = 0; + finalCoord.y = 0; + started = false; + + // Read event data into our endEvnt: + var offset = ($this.get(0) !== window && $this.get(0) !== document) ? $this.offset() : { left: 0, top: 0 }; + var origEvent = e.originalEvent; + var endEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].pageX : e.pageX, + 'y': (settings.touch_capable) ? origEvent.touches[0].pageY : e.pageY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offset.left) : Math.round(e.pageX - offset.left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offset.top) : Math.round(e.pageY - offset.top) + }, + 'time': Date.now(), + 'target': e.target + }; + + // Calculate the swipe amount (normalized): + var xAmount = Math.abs(startEvnt.position.x - endEvnt.position.x), + yAmount = Math.abs(startEvnt.position.y - endEvnt.position.y); + + var touchData = { + 'startEvnt': startEvnt, + 'endEvnt': endEvnt, + 'direction': swipedir.replace('swipe', ''), + 'xAmount': xAmount, + 'yAmount': yAmount, + 'duration': endEvnt.time - startEvnt.time + }; + hasSwiped = true; + $this.trigger('swipe', touchData).trigger(swipedir, touchData); + } + } + + function touchEnd(e) { + $this = $(e.currentTarget); + var swipedir = ""; + $this.data('callee3', touchEnd); + if (hasSwiped) { + // We need to check if the element to which the event was bound contains a data-xthreshold | data-vthreshold: + var ele_x_threshold = $this.data('xthreshold'), + ele_y_threshold = $this.data('ythreshold'), + h_threshold = (typeof ele_x_threshold !== 'undefined' && ele_x_threshold !== false && parseInt(ele_x_threshold)) ? parseInt(ele_x_threshold) : settings.swipe_h_threshold, + v_threshold = (typeof ele_y_threshold !== 'undefined' && ele_y_threshold !== false && parseInt(ele_y_threshold)) ? parseInt(ele_y_threshold) : settings.swipe_v_threshold; + + var offset = ($this.get(0) !== window && $this.get(0) !== document) ? $this.offset() : { left: 0, top: 0 }; + var origEvent = e.originalEvent; + var endEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].pageX : e.pageX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].pageY : e.pageY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offset.left) : Math.round(e.pageX - offset.left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offset.top) : Math.round(e.pageY - offset.top) + }, + 'time': Date.now(), + 'target': e.target + }; + + // Calculate the swipe amount (normalized): + var xAmount = Math.abs(startEvnt.position.x - endEvnt.position.x), + yAmount = Math.abs(startEvnt.position.y - endEvnt.position.y); + + // Read event data into our endEvnt: + if (xAmount > yAmount) { + if (startEvnt.position.x < endEvnt.position.x && (endEvnt.position.x - startEvnt.position.x > h_threshold)) { + swipedir = 'swiperight'; + } + if (startEvnt.position.x > endEvnt.position.x && (startEvnt.position.x - endEvnt.position.x > h_threshold)) { + swipedir = 'swipeleft'; + } + } + else { + if (startEvnt.position.y > endEvnt.position.y && (startEvnt.position.y - endEvnt.position.y > v_threshold)) { + swipedir = 'swipeup'; + } + if (startEvnt.position.y < endEvnt.position.y && (endEvnt.position.y - startEvnt.position.y > v_threshold)) { + swipedir = 'swipedown'; + } + } + + var touchData = { + 'startEvnt': startEvnt, + 'endEvnt': endEvnt, + 'direction': swipedir.replace('swipe', ''), + 'xAmount': xAmount, + 'yAmount': yAmount, + 'duration': endEvnt.time - startEvnt.time + }; + $this.trigger('swipeend', touchData); + } + + started = false; + hasSwiped = false; + } + + $this.on(settings.startevent, touchStart); + $this.on(settings.moveevent, touchMove); + $this.on(settings.endevent, touchEnd); + }, + + remove: function () { + $(this).off(settings.startevent, $(this).data.callee1).off(settings.moveevent, $(this).data.callee2).off(settings.endevent, $(this).data.callee3); + } + }; + + // scrollstart Event (also handles scrollend): + $.event.special.scrollstart = { + setup: function () { + var thisObject = this, + $this = $(thisObject), + scrolling, + timer; + + function trigger(event, state) { + scrolling = state; + triggerCustomEvent(thisObject, scrolling ? 'scrollstart' : 'scrollend', event); + } + + // iPhone triggers scroll after a small delay; use touchmove instead + $this.on(settings.scrollevent, function scrollFunc(event) { + $this.data('callee', scrollFunc); + + if (!scrolling) { + trigger(event, true); + } + + clearTimeout(timer); + timer = setTimeout(function () { + trigger(event, false); + }, 50); + }); + }, + + remove: function () { + $(this).off(settings.scrollevent, $(this).data.callee); + } + }; + + // This is the orientation change (largely borrowed from jQuery Mobile): + var win = $(window), + special_event, + get_orientation, + last_orientation, + initial_orientation_is_landscape, + initial_orientation_is_default, + portrait_map = { + '0': true, + '180': true + }; + + if (settings.orientation_support) { + var ww = window.innerWidth || win.width(), + wh = window.innerHeight || win.height(), + landscape_threshold = 50; + + initial_orientation_is_landscape = ww > wh && (ww - wh) > landscape_threshold; + initial_orientation_is_default = portrait_map[window.orientation]; + + if ((initial_orientation_is_landscape && initial_orientation_is_default) || (!initial_orientation_is_landscape && !initial_orientation_is_default)) { + portrait_map = { + '-90': true, + '90': true + }; + } + } + + $.event.special.orientationchange = special_event = { + setup: function () { + // If the event is supported natively, return false so that jQuery + // will on to the event using DOM methods. + if (settings.orientation_support) { + return false; + } + + // Get the current orientation to avoid initial double-triggering. + last_orientation = get_orientation(); + + win.on('throttledresize', handler); + return true; + }, + teardown: function () { + if (settings.orientation_support) { + return false; + } + + win.off('throttledresize', handler); + return true; + }, + add: function (handleObj) { + // Save a reference to the bound event handler. + var old_handler = handleObj.handler; + + handleObj.handler = function (event) { + event.orientation = get_orientation(); + return old_handler.apply(this, arguments); + }; + } + }; + + // If the event is not supported natively, this handler will be bound to + // the window resize event to simulate the orientationchange event. + + function handler() { + // Get the current orientation. + var orientation = get_orientation(); + + if (orientation !== last_orientation) { + // The orientation has changed, so trigger the orientationchange event. + last_orientation = orientation; + win.trigger("orientationchange"); + } + } + + $.event.special.orientationchange.orientation = get_orientation = function () { + var isPortrait = true, + elem = document.documentElement; + + if (settings.orientation_support) { + isPortrait = portrait_map[window.orientation]; + } else { + isPortrait = elem && elem.clientWidth / elem.clientHeight < 1.1; + } + + return isPortrait ? 'portrait' : 'landscape'; + }; + + // throttle Handler: + $.event.special.throttledresize = { + setup: function () { + $(this).on('resize', throttle_handler); + }, + teardown: function () { + $(this).off('resize', throttle_handler); + } + }; + + var throttle = 250, + throttle_handler = function () { + curr = Date.now(); + diff = curr - lastCall; + + if (diff >= throttle) { + lastCall = curr; + $(this).trigger('throttledresize'); + + } else { + if (heldCall) { + window.clearTimeout(heldCall); + } + + // Promise a held call will still execute + heldCall = window.setTimeout(handler, throttle - diff); + } + }, + lastCall = 0, + heldCall, + curr, + diff; + + // Trigger a custom event: + + function triggerCustomEvent(obj, eventType, event, touchData) { + var originalType = event.type; + event.type = eventType; + + $.event.dispatch.call(obj, event, touchData); + event.type = originalType; + } + + // Correctly on anything we've overloaded: + $.each({ + scrollend: 'scrollstart', + swipeup: 'swipe', + swiperight: 'swipe', + swipedown: 'swipe', + swipeleft: 'swipe', + swipeend: 'swipe', + tap2: 'tap', + taphold2: 'taphold' + }, function (e, srcE) { + $.event.special[e] = { + setup: function () { + $(this).on(srcE, $.noop); + } + }; + }); + +}(jQuery)); \ No newline at end of file diff --git a/src/2.0.3/jquery.mobile-events.min.js b/src/2.0.3/jquery.mobile-events.min.js new file mode 100644 index 0000000..1a8870d --- /dev/null +++ b/src/2.0.3/jquery.mobile-events.min.js @@ -0,0 +1,27 @@ +/*! + * jQuery Mobile Events + * by Ben Major + * + * Copyright 2011-2019, Ben Major + * Licensed under the MIT License: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict";!function(e){e.attrFn=e.attrFn||{};var t="ontouchstart"in window,a={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,shake_threshold:15,touch_capable:t,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:t?"touchstart":"mousedown",endevent:t?"touchend":"mouseup",moveevent:t?"touchmove":"mousemove",tapevent:t?"tap":"click",scrollevent:t?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.touch={},e.isTouchCapable=function(){return a.touch_capable},e.getStartEvent=function(){return a.startevent},e.getEndEvent=function(){return a.endevent},e.getMoveEvent=function(){return a.moveevent},e.getTapEvent=function(){return a.tapevent},e.getScrollEvent=function(){return a.scrollevent},e.touch.setSwipeThresholdX=function(e){if("number"!=typeof e)throw new Error("Threshold parameter must be a type of number");a.swipe_h_threshold=e},e.touch.setSwipeThresholdY=function(e){if("number"!=typeof e)throw new Error("Threshold parameter must be a type of number");a.swipe_v_threshold=e},e.touch.setDoubleTapInt=function(e){if("number"!=typeof e)throw new Error("Interval parameter must be a type of number");a.doubletap_int=e},e.touch.setTapHoldThreshold=function(e){if("number"!=typeof e)throw new Error("Threshold parameter must be a type of number");a.taphold_threshold=e},e.touch.setTapRange=function(e){if("number"!=typeof e)throw new Error("Ranger parameter must be a type of number");a.tap_pixel_range=threshold},e.each(["tapstart","tapend","tapmove","tap","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange","tap2","taphold2"],function(t,a){e.fn[a]=function(e){return e?this.on(a,e):this.trigger(a)},e.attrFn[a]=!0}),e.event.special.tapstart={setup:function(){var t=this,o=e(t);o.on(a.startevent,function e(n){if(o.data("callee",e),n.which&&1!==n.which)return!1;var i=o.get(0)!==window&&o.get(0)!==document?o.offset():{left:0,top:0},r=n.originalEvent,p={position:{x:a.touch_capable?r.touches[0].pageX:n.pageX,y:a.touch_capable?r.touches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(r.changedTouches[0].pageX-i.left):Math.round(n.pageX-i.left),y:a.touch_capable?Math.round(r.changedTouches[0].pageY-i.top):Math.round(n.pageY-i.top)},time:Date.now(),target:n.target};return w(t,"tapstart",n,p),!0})},remove:function(){e(this).off(a.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,o=e(t);o.on(a.moveevent,function e(n){o.data("callee",e);var i=o.get(0)!==window&&o.get(0)!==document?o.offset():{left:0,top:0},r=n.originalEvent,p={position:{x:a.touch_capable?r.touches[0].pageX:n.pageX,y:a.touch_capable?r.touches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(r.changedTouches[0].pageX-i.left):Math.round(n.pageX-i.left),y:a.touch_capable?Math.round(r.changedTouches[0].pageY-i.top):Math.round(n.pageY-i.top)},time:Date.now(),target:n.target};return w(t,"tapmove",n,p),!0})},remove:function(){e(this).off(a.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,o=e(t);o.on(a.endevent,function e(n){o.data("callee",e);var i=o.get(0)!==window&&o.get(0)!==document?o.offset():{left:0,top:0},r=n.originalEvent,p={position:{x:a.touch_capable?r.changedTouches[0].pageX:n.pageX,y:a.touch_capable?r.changedTouches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(r.changedTouches[0].pageX-i.left):Math.round(n.pageX-i.left),y:a.touch_capable?Math.round(r.changedTouches[0].pageY-i.top):Math.round(n.pageY-i.top)},time:Date.now(),target:n.target};return w(t,"tapend",n,p),!0})},remove:function(){e(this).off(a.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,o=this,n=e(o),i={x:0,y:0},r=0,p=0;n.on(a.startevent,function e(h){if(h.which&&1!==h.which)return!1;n.data("tapheld",!1),t=h.target;var c=h.originalEvent,s=Date.now();a.touch_capable?c.touches[0].pageX:h.pageX,a.touch_capable?c.touches[0].pageY:h.pageY,a.touch_capable?(c.touches[0].pageX,c.touches[0].target.offsetLeft):h.offsetX,a.touch_capable?(c.touches[0].pageY,c.touches[0].target.offsetTop):h.offsetY;i.x=h.originalEvent.targetTouches?h.originalEvent.targetTouches[0].pageX:h.pageX,i.y=h.originalEvent.targetTouches?h.originalEvent.targetTouches[0].pageY:h.pageY,r=i.x,p=i.y;var u=n.parent().data("threshold")?n.parent().data("threshold"):n.data("threshold"),l=void 0!==u&&!1!==u&&parseInt(u)?parseInt(u):a.taphold_threshold;return n.data("hold_timer",window.setTimeout(function(){var u=i.x-r,l=i.y-p;if(h.target==t&&(i.x==r&&i.y==p||u>=-a.tap_pixel_range&&u<=a.tap_pixel_range&&l>=-a.tap_pixel_range&&l<=a.tap_pixel_range)){n.data("tapheld",!0);for(var g=Date.now()-s,d=h.originalEvent.targetTouches?h.originalEvent.targetTouches:[h],f=[],v=n.get(0)!==window&&n.get(0)!==document?n.offset():{left:0,top:0},_=0;_100){i.data("doubletapped",!0),window.clearTimeout(a.tap_timer);var l=i.get(0)!==window&&i.get(0)!==document?i.offset():{left:0,top:0},g={position:{x:a.touch_capable?c.originalEvent.changedTouches[0].pageX:c.pageX,y:a.touch_capable?c.originalEvent.changedTouches[0].pageY:c.pageY},offset:{x:a.touch_capable?Math.round(o.changedTouches[0].pageX-l.left):Math.round(c.pageX-l.left),y:a.touch_capable?Math.round(o.changedTouches[0].pageY-l.top):Math.round(c.pageY-l.top)},time:Date.now(),target:c.target,element:c.originalEvent.srcElement,index:e(c.target).index()},d={firstTap:r,secondTap:g,interval:g.time-r.time};p||(w(n,"doubletap",c,d),r=null),p=!0,window.setTimeout(function(){p=!1},a.doubletap_int)}else i.data("lastTouch",s),t=window.setTimeout(function(){r=null,window.clearTimeout(t)},a.doubletap_int,[c]);i.data("lastTouch",s)})},remove:function(){e(this).off(a.startevent,e(this).data.callee1).off(a.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,o=e(t),n=null,i=null,r={x:0,y:0};o.on(a.startevent,function e(t){return(!t.which||1===t.which)&&(i=Date.now(),n=t.target,o.data("callee1",e),r.x=t.originalEvent.targetTouches?t.originalEvent.targetTouches[0].pageX:t.pageX,r.y=t.originalEvent.targetTouches?t.originalEvent.targetTouches[0].pageY:t.pageY,!0)}).on(a.endevent,function e(p){if(o.data("callee2",e),p.target==n){var h=p.originalEvent.changedTouches?p.originalEvent.changedTouches[0].pageX:p.pageX,c=p.originalEvent.changedTouches?p.originalEvent.changedTouches[0].pageY:p.pageY;a.tap_timer=window.setTimeout(function(){var e=r.x-h,n=r.y-c;if(!o.data("doubletapped")&&!o.data("tapheld")&&(r.x==h&&r.y==c||e>=-a.tap_pixel_range&&e<=a.tap_pixel_range&&n>=-a.tap_pixel_range&&n<=a.tap_pixel_range)){var s=o.get(0)!==window&&o.get(0)!==document?o.offset():{left:0,top:0},u=p.originalEvent,l={position:{x:a.touch_capable?u.changedTouches[0].pageX:p.pageX,y:a.touch_capable?u.changedTouches[0].pageY:p.pageY},offset:{x:a.touch_capable?Math.round(u.changedTouches[0].pageX-s.left):Math.round(p.pageX-s.left),y:a.touch_capable?Math.round(u.changedTouches[0].pageY-s.top):Math.round(p.pageY-s.top)},time:Date.now(),target:p.target};l.time-i=-a.tap_pixel_range&&l<=a.tap_pixel_range&&g>=-a.tap_pixel_range&&g<=a.tap_pixel_range)){for(var d=i.get(0)!==window&&i.get(0)!==document?i.offset():{left:0,top:0},f=c.originalEvent,v=[],_=0;_Math.abs(p.y-r.y)?(r.xg&&(s="swiperight"),r.x>p.x&&r.x-p.x>g&&(s="swipeleft")):(r.y>p.y&&r.y-p.y>d&&(s="swipeup"),r.yd&&(s="swipedown")),null!=s&&n){r.x=0,r.y=0,p.x=0,p.y=0,n=!1;var f=o.get(0)!==window&&o.get(0)!==document?o.offset():{left:0,top:0},v=c.originalEvent,w={position:{x:a.touch_capable?v.touches[0].pageX:c.pageX,y:a.touch_capable?v.touches[0].pageY:c.pageY},offset:{x:a.touch_capable?Math.round(v.changedTouches[0].pageX-f.left):Math.round(c.pageX-f.left),y:a.touch_capable?Math.round(v.changedTouches[0].pageY-f.top):Math.round(c.pageY-f.top)},time:Date.now(),target:c.target},_=Math.abs(t.position.x-w.position.x),m=Math.abs(t.position.y-w.position.y),T={startEvnt:t,endEvnt:w,direction:s.replace("swipe",""),xAmount:_,yAmount:m,duration:w.time-t.time};i=!0,o.trigger("swipe",T).trigger(s,T)}}),o.on(a.endevent,function r(p){var h="";if((o=e(p.currentTarget)).data("callee3",r),i){var c=o.data("xthreshold"),s=o.data("ythreshold"),u=void 0!==c&&!1!==c&&parseInt(c)?parseInt(c):a.swipe_h_threshold,l=void 0!==s&&!1!==s&&parseInt(s)?parseInt(s):a.swipe_v_threshold,g=o.get(0)!==window&&o.get(0)!==document?o.offset():{left:0,top:0},d=p.originalEvent,f={position:{x:a.touch_capable?d.changedTouches[0].pageX:p.pageX,y:a.touch_capable?d.changedTouches[0].pageY:p.pageY},offset:{x:a.touch_capable?Math.round(d.changedTouches[0].pageX-g.left):Math.round(p.pageX-g.left),y:a.touch_capable?Math.round(d.changedTouches[0].pageY-g.top):Math.round(p.pageY-g.top)},time:Date.now(),target:p.target},v=Math.abs(t.position.x-f.position.x),w=Math.abs(t.position.y-f.position.y);v>w?(t.position.xu&&(h="swiperight"),t.position.x>f.position.x&&t.position.x-f.position.x>u&&(h="swipeleft")):(t.position.y>f.position.y&&t.position.y-f.position.y>l&&(h="swipeup"),t.position.yl&&(h="swipedown"));var _={startEvnt:t,endEvnt:f,direction:h.replace("swipe",""),xAmount:v,yAmount:w,duration:f.time-t.time};o.trigger("swipeend",_)}n=!1,i=!1})},remove:function(){e(this).off(a.startevent,e(this).data.callee1).off(a.moveevent,e(this).data.callee2).off(a.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){var t,o,n=this,i=e(n);function r(e,a){w(n,(t=a)?"scrollstart":"scrollend",e)}i.on(a.scrollevent,function e(a){i.data("callee",e),t||r(a,!0),clearTimeout(o),o=setTimeout(function(){r(a,!1)},50)})},remove:function(){e(this).off(a.scrollevent,e(this).data.callee)}};var o,n,i,r,p=e(window),h={0:!0,180:!0};if(a.orientation_support){var c=window.innerWidth||p.width(),s=window.innerHeight||p.height();i=c>s&&c-s>50,r=h[window.orientation],(i&&r||!i&&!r)&&(h={"-90":!0,90:!0})}function u(){var e=o();e!==n&&(n=e,p.trigger("orientationchange"))}e.event.special.orientationchange={setup:function(){return!a.orientation_support&&(n=o(),p.on("throttledresize",u),!0)},teardown:function(){return!a.orientation_support&&(p.off("throttledresize",u),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=o(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=o=function(){var e=document.documentElement;return(a.orientation_support?h[window.orientation]:e&&e.clientWidth/e.clientHeight<1.1)?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",f)},teardown:function(){e(this).off("resize",f)}};var l,g,d,f=function(){g=Date.now(),(d=g-v)>=250?(v=g,e(this).trigger("throttledresize")):(l&&window.clearTimeout(l),l=window.setTimeout(u,250-d))},v=0;function w(t,a,o,n){var i=o.type;o.type=a,e.event.dispatch.call(t,o,n),o.type=i}e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap",taphold2:"taphold"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); \ No newline at end of file diff --git a/src/jquery.mobile-events.js b/src/jquery.mobile-events.js index 1e11ee7..627afdd 100644 --- a/src/jquery.mobile-events.js +++ b/src/jquery.mobile-events.js @@ -624,19 +624,24 @@ ele_y_threshold = ($this.parent().data('ythreshold')) ? $this.parent().data('ythreshold') : $this.data('ythreshold'), h_threshold = (typeof ele_x_threshold !== 'undefined' && ele_x_threshold !== false && parseInt(ele_x_threshold)) ? parseInt(ele_x_threshold) : settings.swipe_h_threshold, v_threshold = (typeof ele_y_threshold !== 'undefined' && ele_y_threshold !== false && parseInt(ele_y_threshold)) ? parseInt(ele_y_threshold) : settings.swipe_v_threshold; - - if (originalCoord.y > finalCoord.y && (originalCoord.y - finalCoord.y > v_threshold)) { - swipedir = 'swipeup'; - } - if (originalCoord.x < finalCoord.x && (finalCoord.x - originalCoord.x > h_threshold)) { - swipedir = 'swiperight'; - } - if (originalCoord.y < finalCoord.y && (finalCoord.y - originalCoord.y > v_threshold)) { - swipedir = 'swipedown'; + + if (Math.abs(finalCoord.x - originalCoord.x) > Math.abs(finalCoord.y - originalCoord.y)) { + if (originalCoord.x < finalCoord.x && (finalCoord.x - originalCoord.x > h_threshold)) { + swipedir = 'swiperight'; + } + if (originalCoord.x > finalCoord.x && (originalCoord.x - finalCoord.x > h_threshold)) { + swipedir = 'swipeleft'; + } } - if (originalCoord.x > finalCoord.x && (originalCoord.x - finalCoord.x > h_threshold)) { - swipedir = 'swipeleft'; + else { + if (originalCoord.y > finalCoord.y && (originalCoord.y - finalCoord.y > v_threshold)) { + swipedir = 'swipeup'; + } + if (originalCoord.y < finalCoord.y && (finalCoord.y - originalCoord.y > v_threshold)) { + swipedir = 'swipedown'; + } } + if (swipedir != undefined && started) { originalCoord.x = 0; originalCoord.y = 0; @@ -703,24 +708,28 @@ 'target': e.target }; - // Read event data into our endEvnt: - if (startEvnt.position.y > endEvnt.position.y && (startEvnt.position.y - endEvnt.position.y > v_threshold)) { - swipedir = 'swipeup'; - } - if (startEvnt.position.x < endEvnt.position.x && (endEvnt.position.x - startEvnt.position.x > h_threshold)) { - swipedir = 'swiperight'; - } - if (startEvnt.position.y < endEvnt.position.y && (endEvnt.position.y - startEvnt.position.y > v_threshold)) { - swipedir = 'swipedown'; - } - if (startEvnt.position.x > endEvnt.position.x && (startEvnt.position.x - endEvnt.position.x > h_threshold)) { - swipedir = 'swipeleft'; - } - // Calculate the swipe amount (normalized): var xAmount = Math.abs(startEvnt.position.x - endEvnt.position.x), yAmount = Math.abs(startEvnt.position.y - endEvnt.position.y); + // Read event data into our endEvnt: + if (xAmount > yAmount) { + if (startEvnt.position.x < endEvnt.position.x && (endEvnt.position.x - startEvnt.position.x > h_threshold)) { + swipedir = 'swiperight'; + } + if (startEvnt.position.x > endEvnt.position.x && (startEvnt.position.x - endEvnt.position.x > h_threshold)) { + swipedir = 'swipeleft'; + } + } + else { + if (startEvnt.position.y > endEvnt.position.y && (startEvnt.position.y - endEvnt.position.y > v_threshold)) { + swipedir = 'swipeup'; + } + if (startEvnt.position.y < endEvnt.position.y && (endEvnt.position.y - startEvnt.position.y > v_threshold)) { + swipedir = 'swipedown'; + } + } + var touchData = { 'startEvnt': startEvnt, 'endEvnt': endEvnt, @@ -928,4 +937,4 @@ }; }); -}(jQuery)); +}(jQuery)); \ No newline at end of file diff --git a/src/jquery.mobile-events.min.js b/src/jquery.mobile-events.min.js index 6ac0a92..1a8870d 100644 --- a/src/jquery.mobile-events.min.js +++ b/src/jquery.mobile-events.min.js @@ -24,4 +24,4 @@ * THE SOFTWARE. * */ -"use strict";!function(e){e.attrFn=e.attrFn||{};var t="ontouchstart"in window,a={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,shake_threshold:15,touch_capable:t,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:t?"touchstart":"mousedown",endevent:t?"touchend":"mouseup",moveevent:t?"touchmove":"mousemove",tapevent:t?"tap":"click",scrollevent:t?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.touch={},e.isTouchCapable=function(){return a.touch_capable},e.getStartEvent=function(){return a.startevent},e.getEndEvent=function(){return a.endevent},e.getMoveEvent=function(){return a.moveevent},e.getTapEvent=function(){return a.tapevent},e.getScrollEvent=function(){return a.scrollevent},e.touch.setSwipeThresholdX=function(e){if("number"!=typeof e)throw new Error("Threshold parameter must be a type of number");a.swipe_h_threshold=e},e.touch.setSwipeThresholdY=function(e){if("number"!=typeof e)throw new Error("Threshold parameter must be a type of number");a.swipe_v_threshold=e},e.touch.setDoubleTapInt=function(e){if("number"!=typeof e)throw new Error("Interval parameter must be a type of number");a.doubletap_int=e},e.touch.setTapHoldThreshold=function(e){if("number"!=typeof e)throw new Error("Threshold parameter must be a type of number");a.taphold_threshold=e},e.touch.setTapRange=function(e){if("number"!=typeof e)throw new Error("Ranger parameter must be a type of number");a.tap_pixel_range=threshold},e.each(["tapstart","tapend","tapmove","tap","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange","tap2","taphold2"],function(t,a){e.fn[a]=function(e){return e?this.on(a,e):this.trigger(a)},e.attrFn[a]=!0}),e.event.special.tapstart={setup:function(){var t=this,o=e(t);o.on(a.startevent,function e(n){if(o.data("callee",e),n.which&&1!==n.which)return!1;var i=o.get(0)!==window&&o.get(0)!==document?o.offset():{left:0,top:0},r=n.originalEvent,p={position:{x:a.touch_capable?r.touches[0].pageX:n.pageX,y:a.touch_capable?r.touches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(r.changedTouches[0].pageX-i.left):Math.round(n.pageX-i.left),y:a.touch_capable?Math.round(r.changedTouches[0].pageY-i.top):Math.round(n.pageY-i.top)},time:Date.now(),target:n.target};return w(t,"tapstart",n,p),!0})},remove:function(){e(this).off(a.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,o=e(t);o.on(a.moveevent,function e(n){o.data("callee",e);var i=o.get(0)!==window&&o.get(0)!==document?o.offset():{left:0,top:0},r=n.originalEvent,p={position:{x:a.touch_capable?r.touches[0].pageX:n.pageX,y:a.touch_capable?r.touches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(r.changedTouches[0].pageX-i.left):Math.round(n.pageX-i.left),y:a.touch_capable?Math.round(r.changedTouches[0].pageY-i.top):Math.round(n.pageY-i.top)},time:Date.now(),target:n.target};return w(t,"tapmove",n,p),!0})},remove:function(){e(this).off(a.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,o=e(t);o.on(a.endevent,function e(n){o.data("callee",e);var i=o.get(0)!==window&&o.get(0)!==document?o.offset():{left:0,top:0},r=n.originalEvent,p={position:{x:a.touch_capable?r.changedTouches[0].pageX:n.pageX,y:a.touch_capable?r.changedTouches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(r.changedTouches[0].pageX-i.left):Math.round(n.pageX-i.left),y:a.touch_capable?Math.round(r.changedTouches[0].pageY-i.top):Math.round(n.pageY-i.top)},time:Date.now(),target:n.target};return w(t,"tapend",n,p),!0})},remove:function(){e(this).off(a.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,o=this,n=e(o),i={x:0,y:0},r=0,p=0;n.on(a.startevent,function e(h){if(h.which&&1!==h.which)return!1;n.data("tapheld",!1),t=h.target;var c=h.originalEvent,u=Date.now();a.touch_capable?c.touches[0].pageX:h.pageX,a.touch_capable?c.touches[0].pageY:h.pageY,a.touch_capable?(c.touches[0].pageX,c.touches[0].target.offsetLeft):h.offsetX,a.touch_capable?(c.touches[0].pageY,c.touches[0].target.offsetTop):h.offsetY;i.x=h.originalEvent.targetTouches?h.originalEvent.targetTouches[0].pageX:h.pageX,i.y=h.originalEvent.targetTouches?h.originalEvent.targetTouches[0].pageY:h.pageY,r=i.x,p=i.y;var s=n.parent().data("threshold")?n.parent().data("threshold"):n.data("threshold"),l=void 0!==s&&!1!==s&&parseInt(s)?parseInt(s):a.taphold_threshold;return n.data("hold_timer",window.setTimeout(function(){var s=i.x-r,l=i.y-p;if(h.target==t&&(i.x==r&&i.y==p||s>=-a.tap_pixel_range&&s<=a.tap_pixel_range&&l>=-a.tap_pixel_range&&l<=a.tap_pixel_range)){n.data("tapheld",!0);for(var g=Date.now()-u,d=h.originalEvent.targetTouches?h.originalEvent.targetTouches:[h],f=[],v=n.get(0)!==window&&n.get(0)!==document?n.offset():{left:0,top:0},_=0;_100){i.data("doubletapped",!0),window.clearTimeout(a.tap_timer);var l=i.get(0)!==window&&i.get(0)!==document?i.offset():{left:0,top:0},g={position:{x:a.touch_capable?c.originalEvent.changedTouches[0].pageX:c.pageX,y:a.touch_capable?c.originalEvent.changedTouches[0].pageY:c.pageY},offset:{x:a.touch_capable?Math.round(o.changedTouches[0].pageX-l.left):Math.round(c.pageX-l.left),y:a.touch_capable?Math.round(o.changedTouches[0].pageY-l.top):Math.round(c.pageY-l.top)},time:Date.now(),target:c.target,element:c.originalEvent.srcElement,index:e(c.target).index()},d={firstTap:r,secondTap:g,interval:g.time-r.time};p||(w(n,"doubletap",c,d),r=null),p=!0,window.setTimeout(function(){p=!1},a.doubletap_int)}else i.data("lastTouch",u),t=window.setTimeout(function(){r=null,window.clearTimeout(t)},a.doubletap_int,[c]);i.data("lastTouch",u)})},remove:function(){e(this).off(a.startevent,e(this).data.callee1).off(a.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,o=e(t),n=null,i=null,r={x:0,y:0};o.on(a.startevent,function e(t){return(!t.which||1===t.which)&&(i=Date.now(),n=t.target,o.data("callee1",e),r.x=t.originalEvent.targetTouches?t.originalEvent.targetTouches[0].pageX:t.pageX,r.y=t.originalEvent.targetTouches?t.originalEvent.targetTouches[0].pageY:t.pageY,!0)}).on(a.endevent,function e(p){if(o.data("callee2",e),p.target==n){var h=p.originalEvent.changedTouches?p.originalEvent.changedTouches[0].pageX:p.pageX,c=p.originalEvent.changedTouches?p.originalEvent.changedTouches[0].pageY:p.pageY;a.tap_timer=window.setTimeout(function(){var e=r.x-h,n=r.y-c;if(!o.data("doubletapped")&&!o.data("tapheld")&&(r.x==h&&r.y==c||e>=-a.tap_pixel_range&&e<=a.tap_pixel_range&&n>=-a.tap_pixel_range&&n<=a.tap_pixel_range)){var u=o.get(0)!==window&&o.get(0)!==document?o.offset():{left:0,top:0},s=p.originalEvent,l={position:{x:a.touch_capable?s.changedTouches[0].pageX:p.pageX,y:a.touch_capable?s.changedTouches[0].pageY:p.pageY},offset:{x:a.touch_capable?Math.round(s.changedTouches[0].pageX-u.left):Math.round(p.pageX-u.left),y:a.touch_capable?Math.round(s.changedTouches[0].pageY-u.top):Math.round(p.pageY-u.top)},time:Date.now(),target:p.target};l.time-i=-a.tap_pixel_range&&l<=a.tap_pixel_range&&g>=-a.tap_pixel_range&&g<=a.tap_pixel_range)){for(var d=i.get(0)!==window&&i.get(0)!==document?i.offset():{left:0,top:0},f=c.originalEvent,v=[],_=0;_p.y&&r.y-p.y>d&&(u="swipeup"),r.xg&&(u="swiperight"),r.yd&&(u="swipedown"),r.x>p.x&&r.x-p.x>g&&(u="swipeleft"),null!=u&&n){r.x=0,r.y=0,p.x=0,p.y=0,n=!1;var f=o.get(0)!==window&&o.get(0)!==document?o.offset():{left:0,top:0},v=c.originalEvent,w={position:{x:a.touch_capable?v.touches[0].pageX:c.pageX,y:a.touch_capable?v.touches[0].pageY:c.pageY},offset:{x:a.touch_capable?Math.round(v.changedTouches[0].pageX-f.left):Math.round(c.pageX-f.left),y:a.touch_capable?Math.round(v.changedTouches[0].pageY-f.top):Math.round(c.pageY-f.top)},time:Date.now(),target:c.target},_=Math.abs(t.position.x-w.position.x),m=Math.abs(t.position.y-w.position.y),T={startEvnt:t,endEvnt:w,direction:u.replace("swipe",""),xAmount:_,yAmount:m,duration:w.time-t.time};i=!0,o.trigger("swipe",T).trigger(u,T)}}),o.on(a.endevent,function r(p){var h="";if((o=e(p.currentTarget)).data("callee3",r),i){var c=o.data("xthreshold"),u=o.data("ythreshold"),s=void 0!==c&&!1!==c&&parseInt(c)?parseInt(c):a.swipe_h_threshold,l=void 0!==u&&!1!==u&&parseInt(u)?parseInt(u):a.swipe_v_threshold,g=o.get(0)!==window&&o.get(0)!==document?o.offset():{left:0,top:0},d=p.originalEvent,f={position:{x:a.touch_capable?d.changedTouches[0].pageX:p.pageX,y:a.touch_capable?d.changedTouches[0].pageY:p.pageY},offset:{x:a.touch_capable?Math.round(d.changedTouches[0].pageX-g.left):Math.round(p.pageX-g.left),y:a.touch_capable?Math.round(d.changedTouches[0].pageY-g.top):Math.round(p.pageY-g.top)},time:Date.now(),target:p.target};t.position.y>f.position.y&&t.position.y-f.position.y>l&&(h="swipeup"),t.position.xs&&(h="swiperight"),t.position.yl&&(h="swipedown"),t.position.x>f.position.x&&t.position.x-f.position.x>s&&(h="swipeleft");var v=Math.abs(t.position.x-f.position.x),w=Math.abs(t.position.y-f.position.y),_={startEvnt:t,endEvnt:f,direction:h.replace("swipe",""),xAmount:v,yAmount:w,duration:f.time-t.time};o.trigger("swipeend",_)}n=!1,i=!1})},remove:function(){e(this).off(a.startevent,e(this).data.callee1).off(a.moveevent,e(this).data.callee2).off(a.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){var t,o,n=this,i=e(n);function r(e,a){w(n,(t=a)?"scrollstart":"scrollend",e)}i.on(a.scrollevent,function e(a){i.data("callee",e),t||r(a,!0),clearTimeout(o),o=setTimeout(function(){r(a,!1)},50)})},remove:function(){e(this).off(a.scrollevent,e(this).data.callee)}};var o,n,i,r,p=e(window),h={0:!0,180:!0};if(a.orientation_support){var c=window.innerWidth||p.width(),u=window.innerHeight||p.height();i=c>u&&c-u>50,r=h[window.orientation],(i&&r||!i&&!r)&&(h={"-90":!0,90:!0})}function s(){var e=o();e!==n&&(n=e,p.trigger("orientationchange"))}e.event.special.orientationchange={setup:function(){return!a.orientation_support&&(n=o(),p.on("throttledresize",s),!0)},teardown:function(){return!a.orientation_support&&(p.off("throttledresize",s),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=o(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=o=function(){var e=document.documentElement;return(a.orientation_support?h[window.orientation]:e&&e.clientWidth/e.clientHeight<1.1)?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",f)},teardown:function(){e(this).off("resize",f)}};var l,g,d,f=function(){g=Date.now(),(d=g-v)>=250?(v=g,e(this).trigger("throttledresize")):(l&&window.clearTimeout(l),l=window.setTimeout(s,250-d))},v=0;function w(t,a,o,n){var i=o.type;o.type=a,e.event.dispatch.call(t,o,n),o.type=i}e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap",taphold2:"taphold"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); +"use strict";!function(e){e.attrFn=e.attrFn||{};var t="ontouchstart"in window,a={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,shake_threshold:15,touch_capable:t,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:t?"touchstart":"mousedown",endevent:t?"touchend":"mouseup",moveevent:t?"touchmove":"mousemove",tapevent:t?"tap":"click",scrollevent:t?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.touch={},e.isTouchCapable=function(){return a.touch_capable},e.getStartEvent=function(){return a.startevent},e.getEndEvent=function(){return a.endevent},e.getMoveEvent=function(){return a.moveevent},e.getTapEvent=function(){return a.tapevent},e.getScrollEvent=function(){return a.scrollevent},e.touch.setSwipeThresholdX=function(e){if("number"!=typeof e)throw new Error("Threshold parameter must be a type of number");a.swipe_h_threshold=e},e.touch.setSwipeThresholdY=function(e){if("number"!=typeof e)throw new Error("Threshold parameter must be a type of number");a.swipe_v_threshold=e},e.touch.setDoubleTapInt=function(e){if("number"!=typeof e)throw new Error("Interval parameter must be a type of number");a.doubletap_int=e},e.touch.setTapHoldThreshold=function(e){if("number"!=typeof e)throw new Error("Threshold parameter must be a type of number");a.taphold_threshold=e},e.touch.setTapRange=function(e){if("number"!=typeof e)throw new Error("Ranger parameter must be a type of number");a.tap_pixel_range=threshold},e.each(["tapstart","tapend","tapmove","tap","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange","tap2","taphold2"],function(t,a){e.fn[a]=function(e){return e?this.on(a,e):this.trigger(a)},e.attrFn[a]=!0}),e.event.special.tapstart={setup:function(){var t=this,o=e(t);o.on(a.startevent,function e(n){if(o.data("callee",e),n.which&&1!==n.which)return!1;var i=o.get(0)!==window&&o.get(0)!==document?o.offset():{left:0,top:0},r=n.originalEvent,p={position:{x:a.touch_capable?r.touches[0].pageX:n.pageX,y:a.touch_capable?r.touches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(r.changedTouches[0].pageX-i.left):Math.round(n.pageX-i.left),y:a.touch_capable?Math.round(r.changedTouches[0].pageY-i.top):Math.round(n.pageY-i.top)},time:Date.now(),target:n.target};return w(t,"tapstart",n,p),!0})},remove:function(){e(this).off(a.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,o=e(t);o.on(a.moveevent,function e(n){o.data("callee",e);var i=o.get(0)!==window&&o.get(0)!==document?o.offset():{left:0,top:0},r=n.originalEvent,p={position:{x:a.touch_capable?r.touches[0].pageX:n.pageX,y:a.touch_capable?r.touches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(r.changedTouches[0].pageX-i.left):Math.round(n.pageX-i.left),y:a.touch_capable?Math.round(r.changedTouches[0].pageY-i.top):Math.round(n.pageY-i.top)},time:Date.now(),target:n.target};return w(t,"tapmove",n,p),!0})},remove:function(){e(this).off(a.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,o=e(t);o.on(a.endevent,function e(n){o.data("callee",e);var i=o.get(0)!==window&&o.get(0)!==document?o.offset():{left:0,top:0},r=n.originalEvent,p={position:{x:a.touch_capable?r.changedTouches[0].pageX:n.pageX,y:a.touch_capable?r.changedTouches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(r.changedTouches[0].pageX-i.left):Math.round(n.pageX-i.left),y:a.touch_capable?Math.round(r.changedTouches[0].pageY-i.top):Math.round(n.pageY-i.top)},time:Date.now(),target:n.target};return w(t,"tapend",n,p),!0})},remove:function(){e(this).off(a.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,o=this,n=e(o),i={x:0,y:0},r=0,p=0;n.on(a.startevent,function e(h){if(h.which&&1!==h.which)return!1;n.data("tapheld",!1),t=h.target;var c=h.originalEvent,s=Date.now();a.touch_capable?c.touches[0].pageX:h.pageX,a.touch_capable?c.touches[0].pageY:h.pageY,a.touch_capable?(c.touches[0].pageX,c.touches[0].target.offsetLeft):h.offsetX,a.touch_capable?(c.touches[0].pageY,c.touches[0].target.offsetTop):h.offsetY;i.x=h.originalEvent.targetTouches?h.originalEvent.targetTouches[0].pageX:h.pageX,i.y=h.originalEvent.targetTouches?h.originalEvent.targetTouches[0].pageY:h.pageY,r=i.x,p=i.y;var u=n.parent().data("threshold")?n.parent().data("threshold"):n.data("threshold"),l=void 0!==u&&!1!==u&&parseInt(u)?parseInt(u):a.taphold_threshold;return n.data("hold_timer",window.setTimeout(function(){var u=i.x-r,l=i.y-p;if(h.target==t&&(i.x==r&&i.y==p||u>=-a.tap_pixel_range&&u<=a.tap_pixel_range&&l>=-a.tap_pixel_range&&l<=a.tap_pixel_range)){n.data("tapheld",!0);for(var g=Date.now()-s,d=h.originalEvent.targetTouches?h.originalEvent.targetTouches:[h],f=[],v=n.get(0)!==window&&n.get(0)!==document?n.offset():{left:0,top:0},_=0;_100){i.data("doubletapped",!0),window.clearTimeout(a.tap_timer);var l=i.get(0)!==window&&i.get(0)!==document?i.offset():{left:0,top:0},g={position:{x:a.touch_capable?c.originalEvent.changedTouches[0].pageX:c.pageX,y:a.touch_capable?c.originalEvent.changedTouches[0].pageY:c.pageY},offset:{x:a.touch_capable?Math.round(o.changedTouches[0].pageX-l.left):Math.round(c.pageX-l.left),y:a.touch_capable?Math.round(o.changedTouches[0].pageY-l.top):Math.round(c.pageY-l.top)},time:Date.now(),target:c.target,element:c.originalEvent.srcElement,index:e(c.target).index()},d={firstTap:r,secondTap:g,interval:g.time-r.time};p||(w(n,"doubletap",c,d),r=null),p=!0,window.setTimeout(function(){p=!1},a.doubletap_int)}else i.data("lastTouch",s),t=window.setTimeout(function(){r=null,window.clearTimeout(t)},a.doubletap_int,[c]);i.data("lastTouch",s)})},remove:function(){e(this).off(a.startevent,e(this).data.callee1).off(a.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,o=e(t),n=null,i=null,r={x:0,y:0};o.on(a.startevent,function e(t){return(!t.which||1===t.which)&&(i=Date.now(),n=t.target,o.data("callee1",e),r.x=t.originalEvent.targetTouches?t.originalEvent.targetTouches[0].pageX:t.pageX,r.y=t.originalEvent.targetTouches?t.originalEvent.targetTouches[0].pageY:t.pageY,!0)}).on(a.endevent,function e(p){if(o.data("callee2",e),p.target==n){var h=p.originalEvent.changedTouches?p.originalEvent.changedTouches[0].pageX:p.pageX,c=p.originalEvent.changedTouches?p.originalEvent.changedTouches[0].pageY:p.pageY;a.tap_timer=window.setTimeout(function(){var e=r.x-h,n=r.y-c;if(!o.data("doubletapped")&&!o.data("tapheld")&&(r.x==h&&r.y==c||e>=-a.tap_pixel_range&&e<=a.tap_pixel_range&&n>=-a.tap_pixel_range&&n<=a.tap_pixel_range)){var s=o.get(0)!==window&&o.get(0)!==document?o.offset():{left:0,top:0},u=p.originalEvent,l={position:{x:a.touch_capable?u.changedTouches[0].pageX:p.pageX,y:a.touch_capable?u.changedTouches[0].pageY:p.pageY},offset:{x:a.touch_capable?Math.round(u.changedTouches[0].pageX-s.left):Math.round(p.pageX-s.left),y:a.touch_capable?Math.round(u.changedTouches[0].pageY-s.top):Math.round(p.pageY-s.top)},time:Date.now(),target:p.target};l.time-i=-a.tap_pixel_range&&l<=a.tap_pixel_range&&g>=-a.tap_pixel_range&&g<=a.tap_pixel_range)){for(var d=i.get(0)!==window&&i.get(0)!==document?i.offset():{left:0,top:0},f=c.originalEvent,v=[],_=0;_Math.abs(p.y-r.y)?(r.xg&&(s="swiperight"),r.x>p.x&&r.x-p.x>g&&(s="swipeleft")):(r.y>p.y&&r.y-p.y>d&&(s="swipeup"),r.yd&&(s="swipedown")),null!=s&&n){r.x=0,r.y=0,p.x=0,p.y=0,n=!1;var f=o.get(0)!==window&&o.get(0)!==document?o.offset():{left:0,top:0},v=c.originalEvent,w={position:{x:a.touch_capable?v.touches[0].pageX:c.pageX,y:a.touch_capable?v.touches[0].pageY:c.pageY},offset:{x:a.touch_capable?Math.round(v.changedTouches[0].pageX-f.left):Math.round(c.pageX-f.left),y:a.touch_capable?Math.round(v.changedTouches[0].pageY-f.top):Math.round(c.pageY-f.top)},time:Date.now(),target:c.target},_=Math.abs(t.position.x-w.position.x),m=Math.abs(t.position.y-w.position.y),T={startEvnt:t,endEvnt:w,direction:s.replace("swipe",""),xAmount:_,yAmount:m,duration:w.time-t.time};i=!0,o.trigger("swipe",T).trigger(s,T)}}),o.on(a.endevent,function r(p){var h="";if((o=e(p.currentTarget)).data("callee3",r),i){var c=o.data("xthreshold"),s=o.data("ythreshold"),u=void 0!==c&&!1!==c&&parseInt(c)?parseInt(c):a.swipe_h_threshold,l=void 0!==s&&!1!==s&&parseInt(s)?parseInt(s):a.swipe_v_threshold,g=o.get(0)!==window&&o.get(0)!==document?o.offset():{left:0,top:0},d=p.originalEvent,f={position:{x:a.touch_capable?d.changedTouches[0].pageX:p.pageX,y:a.touch_capable?d.changedTouches[0].pageY:p.pageY},offset:{x:a.touch_capable?Math.round(d.changedTouches[0].pageX-g.left):Math.round(p.pageX-g.left),y:a.touch_capable?Math.round(d.changedTouches[0].pageY-g.top):Math.round(p.pageY-g.top)},time:Date.now(),target:p.target},v=Math.abs(t.position.x-f.position.x),w=Math.abs(t.position.y-f.position.y);v>w?(t.position.xu&&(h="swiperight"),t.position.x>f.position.x&&t.position.x-f.position.x>u&&(h="swipeleft")):(t.position.y>f.position.y&&t.position.y-f.position.y>l&&(h="swipeup"),t.position.yl&&(h="swipedown"));var _={startEvnt:t,endEvnt:f,direction:h.replace("swipe",""),xAmount:v,yAmount:w,duration:f.time-t.time};o.trigger("swipeend",_)}n=!1,i=!1})},remove:function(){e(this).off(a.startevent,e(this).data.callee1).off(a.moveevent,e(this).data.callee2).off(a.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){var t,o,n=this,i=e(n);function r(e,a){w(n,(t=a)?"scrollstart":"scrollend",e)}i.on(a.scrollevent,function e(a){i.data("callee",e),t||r(a,!0),clearTimeout(o),o=setTimeout(function(){r(a,!1)},50)})},remove:function(){e(this).off(a.scrollevent,e(this).data.callee)}};var o,n,i,r,p=e(window),h={0:!0,180:!0};if(a.orientation_support){var c=window.innerWidth||p.width(),s=window.innerHeight||p.height();i=c>s&&c-s>50,r=h[window.orientation],(i&&r||!i&&!r)&&(h={"-90":!0,90:!0})}function u(){var e=o();e!==n&&(n=e,p.trigger("orientationchange"))}e.event.special.orientationchange={setup:function(){return!a.orientation_support&&(n=o(),p.on("throttledresize",u),!0)},teardown:function(){return!a.orientation_support&&(p.off("throttledresize",u),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=o(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=o=function(){var e=document.documentElement;return(a.orientation_support?h[window.orientation]:e&&e.clientWidth/e.clientHeight<1.1)?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",f)},teardown:function(){e(this).off("resize",f)}};var l,g,d,f=function(){g=Date.now(),(d=g-v)>=250?(v=g,e(this).trigger("throttledresize")):(l&&window.clearTimeout(l),l=window.setTimeout(u,250-d))},v=0;function w(t,a,o,n){var i=o.type;o.type=a,e.event.dispatch.call(t,o,n),o.type=i}e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap",taphold2:"taphold"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); \ No newline at end of file