From a7707dd3591379133772fa53c719bced133f7713 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 17 Jul 2015 13:27:25 +0100 Subject: [PATCH 001/149] Fix for swipe thresholds There was a bug where the threshold of a `swipe` event would be ignored if the actual `move` event occurred on the element's children. This was fixed by checking for a `threshold` parameter on the parent element during the move event. --- src/jquery.mobile-events.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/jquery.mobile-events.js b/src/jquery.mobile-events.js index 2d45b7a..ba1ccb0 100644 --- a/src/jquery.mobile-events.js +++ b/src/jquery.mobile-events.js @@ -567,11 +567,13 @@ 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.data('xthreshold'), - ele_y_threshold = $this.data('ythreshold'), + 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; - + + console.log(h_threshold); + if (originalCoord.y > finalCoord.y && (originalCoord.y - finalCoord.y > v_threshold)) { swipedir = 'swipeup'; } From dbf9a9a72f1a79778920e3d52878ea7396a97542 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 17 Jul 2015 13:28:08 +0100 Subject: [PATCH 002/149] Fix for swipe thresholds There was a bug where the threshold of a `swipe` event would be ignored if the actual `move` event occurred on the element's children. This was fixed by checking for a `threshold` parameter on the parent element during the move event. --- src/jquery.mobile-events.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jquery.mobile-events.min.js b/src/jquery.mobile-events.min.js index 1500002..a9dfc3d 100644 --- a/src/jquery.mobile-events.min.js +++ b/src/jquery.mobile-events.min.js @@ -1 +1 @@ -(function(e){function d(){var e=o();if(e!==u){u=e;i.trigger("orientationchange")}}function E(t,n,r,i){var s=r.type;r.type=n;e.event.dispatch.call(t,r,i);r.type=s}e.attrFn=e.attrFn||{};var t=navigator.userAgent.toLowerCase(),n=t.indexOf("chrome")>-1&&(t.indexOf("windows")>-1||t.indexOf("macintosh")>-1||t.indexOf("linux")>-1)&&t.indexOf("mobile")<0&&t.indexOf("android")<0,r={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:"ontouchstart"in window&&!n,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:"ontouchstart"in window&&!n?"touchstart":"mousedown",endevent:"ontouchstart"in window&&!n?"touchend":"mouseup",moveevent:"ontouchstart"in window&&!n?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!n?"tap":"click",scrollevent:"ontouchstart"in window&&!n?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.isTouchCapable=function(){return r.touch_capable};e.getStartEvent=function(){return r.startevent};e.getEndEvent=function(){return r.endevent};e.getMoveEvent=function(){return r.moveevent};e.getTapEvent=function(){return r.tapevent};e.getScrollEvent=function(){return r.scrollevent};e.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],function(t,n){e.fn[n]=function(e){return e?this.on(n,e):this.trigger(n)};e.attrFn[n]=true});e.event.special.tapstart={setup:function(){var t=this,n=e(t);n.on(r.startevent,function(e){n.data("callee",arguments.callee);if(e.which&&e.which!==1){return false}var i=e.originalEvent,s={position:{x:r.touch_capable?i.touches[0].screenX:e.screenX,y:r.touch_capable?i.touches[0].screenY:e.screenY},offset:{x:r.touch_capable?i.touches[0].pageX-i.touches[0].target.offsetLeft:e.offsetX,y:r.touch_capable?i.touches[0].pageY-i.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};E(t,"tapstart",e,s);return true})},remove:function(){e(this).off(r.startevent,e(this).data.callee)}};e.event.special.tapmove={setup:function(){var t=this,n=e(t);n.on(r.moveevent,function(e){n.data("callee",arguments.callee);var i=e.originalEvent,s={position:{x:r.touch_capable?i.touches[0].screenX:e.screenX,y:r.touch_capable?i.touches[0].screenY:e.screenY},offset:{x:r.touch_capable?i.touches[0].pageX-i.touches[0].target.offsetLeft:e.offsetX,y:r.touch_capable?i.touches[0].pageY-i.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};E(t,"tapmove",e,s);return true})},remove:function(){e(this).off(r.moveevent,e(this).data.callee)}};e.event.special.tapend={setup:function(){var t=this,n=e(t);n.on(r.endevent,function(e){n.data("callee",arguments.callee);var i=e.originalEvent;var s={position:{x:r.touch_capable?i.changedTouches[0].screenX:e.screenX,y:r.touch_capable?i.changedTouches[0].screenY:e.screenY},offset:{x:r.touch_capable?i.changedTouches[0].pageX-i.changedTouches[0].target.offsetLeft:e.offsetX,y:r.touch_capable?i.changedTouches[0].pageY-i.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};E(t,"tapend",e,s);return true})},remove:function(){e(this).off(r.endevent,e(this).data.callee)}};e.event.special.taphold={setup:function(){var t=this,n=e(t),i,s,o={x:0,y:0},u=0,a=0;n.on(r.startevent,function(e){if(e.which&&e.which!==1){return false}else{n.data("tapheld",false);i=e.target;var s=e.originalEvent;var f=Date.now(),l={x:r.touch_capable?s.touches[0].screenX:e.screenX,y:r.touch_capable?s.touches[0].screenY:e.screenY},c={x:r.touch_capable?s.touches[0].pageX-s.touches[0].target.offsetLeft:e.offsetX,y:r.touch_capable?s.touches[0].pageY-s.touches[0].target.offsetTop:e.offsetY};o.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX;o.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY;u=o.x;a=o.y;r.hold_timer=window.setTimeout(function(){var h=o.x-u,p=o.y-a;if(e.target==i&&(o.x==u&&o.y==a||h>=-r.tap_pixel_range&&h<=r.tap_pixel_range&&p>=-r.tap_pixel_range&&p<=r.tap_pixel_range)){n.data("tapheld",true);var d=Date.now(),v={x:r.touch_capable?s.touches[0].screenX:e.screenX,y:r.touch_capable?s.touches[0].screenY:e.screenY},m={x:r.touch_capable?s.touches[0].pageX-s.touches[0].target.offsetLeft:e.offsetX,y:r.touch_capable?s.touches[0].pageY-s.touches[0].target.offsetTop:e.offsetY};duration=d-f;var g={startTime:f,endTime:d,startPosition:l,startOffset:c,endPosition:v,endOffset:m,duration:duration,target:e.target};n.data("callee1",arguments.callee);E(t,"taphold",e,g)}},r.taphold_threshold);return true}}).on(r.endevent,function(){n.data("callee2",arguments.callee);n.data("tapheld",false);window.clearTimeout(r.hold_timer)}).on(r.moveevent,function(e){n.data("callee3",arguments.callee);u=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX;a=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY})},remove:function(){e(this).off(r.startevent,e(this).data.callee1).off(r.endevent,e(this).data.callee2).off(r.moveevent,e(this).data.callee3)}};e.event.special.doubletap={setup:function(){var t=this,n=e(t),i,s,o,u,a,f=false;n.on(r.startevent,function(e){if(e.which&&e.which!==1){return false}n.data("doubletapped",false);i=e.target;n.data("callee1",arguments.callee);u=e.originalEvent;o={position:{x:r.touch_capable?u.touches[0].screenX:e.screenX,y:r.touch_capable?u.touches[0].screenY:e.screenY},offset:{x:r.touch_capable?u.touches[0].pageX-u.touches[0].target.offsetLeft:e.offsetX,y:r.touch_capable?u.touches[0].pageY-u.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return true}).on(r.endevent,function(e){var u=Date.now();var l=n.data("lastTouch")||u+1;var c=u-l;window.clearTimeout(s);n.data("callee2",arguments.callee);if(c100){n.data("doubletapped",true);window.clearTimeout(r.tap_timer);var h={position:{x:r.touch_capable?e.originalEvent.changedTouches[0].screenX:e.screenX,y:r.touch_capable?e.originalEvent.changedTouches[0].screenY:e.screenY},offset:{x:r.touch_capable?e.originalEvent.changedTouches[0].pageX-e.originalEvent.changedTouches[0].target.offsetLeft:e.offsetX,y:r.touch_capable?e.originalEvent.changedTouches[0].pageY-e.originalEvent.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};var p={firstTap:o,secondTap:h,interval:h.time-o.time};if(!f){E(t,"doubletap",e,p)}f=true;a=window.setTimeout(function(e){f=false},r.doubletap_int)}else{n.data("lastTouch",u);s=window.setTimeout(function(e){window.clearTimeout(s)},r.doubletap_int,[e])}n.data("lastTouch",u)})},remove:function(){e(this).off(r.startevent,e(this).data.callee1).off(r.endevent,e(this).data.callee2)}};e.event.special.singletap={setup:function(){var t=this,n=e(t),i=null,s=null,o={x:0,y:0};n.on(r.startevent,function(e){if(e.which&&e.which!==1){return false}else{s=Date.now();i=e.target;n.data("callee1",arguments.callee);o.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX;o.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY;return true}}).on(r.endevent,function(e){n.data("callee2",arguments.callee);if(e.target==i){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;r.tap_timer=window.setTimeout(function(){if(!n.data("doubletapped")&&!n.data("tapheld")&&o.x==end_pos_x&&o.y==end_pos_y){var i=e.originalEvent;var u={position:{x:r.touch_capable?i.changedTouches[0].screenX:e.screenX,y:r.touch_capable?i.changedTouches[0].screenY:e.screenY},offset:{x:r.touch_capable?i.changedTouches[0].pageX-i.changedTouches[0].target.offsetLeft:e.offsetX,y:r.touch_capable?i.changedTouches[0].pageY-i.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};if(u.time-s=-r.tap_pixel_range&&c<=r.tap_pixel_range&&h>=-r.tap_pixel_range&&h<=r.tap_pixel_range)){var d=e.originalEvent;var v=[];for(var m=0;mu.y&&o.y-u.y>p){f="swipeup"}if(o.xh){f="swiperight"}if(o.yp){f="swipedown"}if(o.x>u.x&&o.x-u.x>h){f="swipeleft"}if(f!=undefined&&i){o.x=0;o.y=0;u.x=0;u.y=0;i=false;var d=t.originalEvent;endEvnt={position:{x:r.touch_capable?d.touches[0].screenX:t.screenX,y:r.touch_capable?d.touches[0].screenY:t.screenY},offset:{x:r.touch_capable?d.touches[0].pageX-d.touches[0].target.offsetLeft:t.offsetX,y:r.touch_capable?d.touches[0].pageY-d.touches[0].target.offsetTop:t.offsetY},time:Date.now(),target:t.target};var v=Math.abs(a.position.x-endEvnt.position.x),m=Math.abs(a.position.y-endEvnt.position.y);var g={startEvnt:a,endEvnt:endEvnt,direction:f.replace("swipe",""),xAmount:v,yAmount:m,duration:endEvnt.time-a.time};s=true;n.trigger("swipe",g).trigger(f,g)}}function c(t){n=e(t.target);var o="";n.data("callee3",arguments.callee);if(s){var u=n.data("xthreshold"),f=n.data("ythreshold"),l=typeof u!=="undefined"&&u!==false&&parseInt(u)?parseInt(u):r.swipe_h_threshold,c=typeof f!=="undefined"&&f!==false&&parseInt(f)?parseInt(f):r.swipe_v_threshold;var h=t.originalEvent;endEvnt={position:{x:r.touch_capable?h.changedTouches[0].screenX:t.screenX,y:r.touch_capable?h.changedTouches[0].screenY:t.screenY},offset:{x:r.touch_capable?h.changedTouches[0].pageX-h.changedTouches[0].target.offsetLeft:t.offsetX,y:r.touch_capable?h.changedTouches[0].pageY-h.changedTouches[0].target.offsetTop:t.offsetY},time:Date.now(),target:t.target};if(a.position.y>endEvnt.position.y&&a.position.y-endEvnt.position.y>c){o="swipeup"}if(a.position.xl){o="swiperight"}if(a.position.yc){o="swipedown"}if(a.position.x>endEvnt.position.x&&a.position.x-endEvnt.position.x>l){o="swipeleft"}var p=Math.abs(a.position.x-endEvnt.position.x),d=Math.abs(a.position.y-endEvnt.position.y);var v={startEvnt:a,endEvnt:endEvnt,direction:o.replace("swipe",""),xAmount:p,yAmount:d,duration:endEvnt.time-a.time};n.trigger("swipeend",v)}i=false;s=false}var t=this,n=e(t),i=false,s=false,o={x:0,y:0},u={x:0,y:0},a;n.on(r.startevent,f);n.on(r.moveevent,l);n.on(r.endevent,c)},remove:function(){e(this).off(r.startevent,e(this).data.callee1).off(r.moveevent,e(this).data.callee2).off(r.endevent,e(this).data.callee3)}};e.event.special.scrollstart={setup:function(){function o(e,n){i=n;E(t,i?"scrollstart":"scrollend",e)}var t=this,n=e(t),i,s;n.on(r.scrollevent,function(e){n.data("callee",arguments.callee);if(!i){o(e,true)}clearTimeout(s);s=setTimeout(function(){o(e,false)},50)})},remove:function(){e(this).off(r.scrollevent,e(this).data.callee)}};var i=e(window),s,o,u,a,f,l={0:true,180:true};if(r.orientation_support){var c=window.innerWidth||i.width(),h=window.innerHeight||i.height(),p=50;a=c>h&&c-h>p;f=l[window.orientation];if(a&&f||!a&&!f){l={"-90":true,90:true}}}e.event.special.orientationchange=s={setup:function(){if(r.orientation_support){return false}u=o();i.on("throttledresize",d);return true},teardown:function(){if(r.orientation_support){return false}i.off("throttledresize",d);return true},add:function(e){var t=e.handler;e.handler=function(e){e.orientation=o();return t.apply(this,arguments)}}};e.event.special.orientationchange.orientation=o=function(){var e=true,t=document.documentElement;if(r.orientation_support){e=l[window.orientation]}else{e=t&&t.clientWidth/t.clientHeight<1.1}return e?"portrait":"landscape"};e.event.special.throttledresize={setup:function(){e(this).on("resize",m)},teardown:function(){e(this).off("resize",m)}};var v=250,m=function(){b=Date.now();w=b-g;if(w>=v){g=b;e(this).trigger("throttledresize")}else{if(y){window.clearTimeout(y)}y=window.setTimeout(d,v-w)}},g=0,y,b,w;e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,n,r){e.event.special[t]={setup:function(){e(this).on(n,e.noop)}}})})(jQuery) +!function(e){function t(){var e=c();e!==r&&(r=e,l.trigger("orientationchange"))}function a(t,a,n,o){var i=n.type;n.type=a,e.event.dispatch.call(t,n,o),n.type=i}e.attrFn=e.attrFn||{};var n=navigator.userAgent.toLowerCase(),o=n.indexOf("chrome")>-1&&(n.indexOf("windows")>-1||n.indexOf("macintosh")>-1||n.indexOf("linux")>-1)&&n.indexOf("mobile")<0&&n.indexOf("android")<0,i={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:"ontouchstart"in window&&!o,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:"ontouchstart"in window&&!o?"touchstart":"mousedown",endevent:"ontouchstart"in window&&!o?"touchend":"mouseup",moveevent:"ontouchstart"in window&&!o?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!o?"tap":"click",scrollevent:"ontouchstart"in window&&!o?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.isTouchCapable=function(){return i.touch_capable},e.getStartEvent=function(){return i.startevent},e.getEndEvent=function(){return i.endevent},e.getMoveEvent=function(){return i.moveevent},e.getTapEvent=function(){return i.tapevent},e.getScrollEvent=function(){return i.scrollevent},e.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],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,n=e(t);n.on(i.startevent,function(e){if(n.data("callee",arguments.callee),e.which&&1!==e.which)return!1;var o=e.originalEvent,s={position:{x:i.touch_capable?o.touches[0].screenX:e.screenX,y:i.touch_capable?o.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.touches[0].pageX-o.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.touches[0].pageY-o.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapstart",e,s),!0})},remove:function(){e(this).off(i.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,n=e(t);n.on(i.moveevent,function(e){n.data("callee",arguments.callee);var o=e.originalEvent,s={position:{x:i.touch_capable?o.touches[0].screenX:e.screenX,y:i.touch_capable?o.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.touches[0].pageX-o.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.touches[0].pageY-o.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapmove",e,s),!0})},remove:function(){e(this).off(i.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,n=e(t);n.on(i.endevent,function(e){n.data("callee",arguments.callee);var o=e.originalEvent,s={position:{x:i.touch_capable?o.changedTouches[0].screenX:e.screenX,y:i.touch_capable?o.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.changedTouches[0].pageX-o.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.changedTouches[0].pageY-o.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapend",e,s),!0})},remove:function(){e(this).off(i.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,n=this,o=e(n),s={x:0,y:0},c=0,r=0;o.on(i.startevent,function(e){if(e.which&&1!==e.which)return!1;o.data("tapheld",!1),t=e.target;var h=e.originalEvent,u=Date.now(),l={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},p={x:i.touch_capable?h.touches[0].pageX-h.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?h.touches[0].pageY-h.touches[0].target.offsetTop:e.offsetY};return s.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,s.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,c=s.x,r=s.y,i.hold_timer=window.setTimeout(function(){var g=s.x-c,f=s.y-r;if(e.target==t&&(s.x==c&&s.y==r||g>=-i.tap_pixel_range&&g<=i.tap_pixel_range&&f>=-i.tap_pixel_range&&f<=i.tap_pixel_range)){o.data("tapheld",!0);var d=Date.now(),v={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},w={x:i.touch_capable?h.touches[0].pageX-h.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?h.touches[0].pageY-h.touches[0].target.offsetTop:e.offsetY};duration=d-u;var _={startTime:u,endTime:d,startPosition:l,startOffset:p,endPosition:v,endOffset:w,duration:duration,target:e.target};o.data("callee1",arguments.callee),a(n,"taphold",e,_)}},i.taphold_threshold),!0}).on(i.endevent,function(){o.data("callee2",arguments.callee),o.data("tapheld",!1),window.clearTimeout(i.hold_timer)}).on(i.moveevent,function(e){o.data("callee3",arguments.callee),c=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,r=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2).off(i.moveevent,e(this).data.callee3)}},e.event.special.doubletap={setup:function(){var t,n,o,s,c,r=this,h=e(r),u=!1;h.on(i.startevent,function(e){return e.which&&1!==e.which?!1:(h.data("doubletapped",!1),t=e.target,h.data("callee1",arguments.callee),s=e.originalEvent,o={position:{x:i.touch_capable?s.touches[0].screenX:e.screenX,y:i.touch_capable?s.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?s.touches[0].pageX-s.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?s.touches[0].pageY-s.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target},!0)}).on(i.endevent,function(e){var s=Date.now(),l=h.data("lastTouch")||s+1,p=s-l;if(window.clearTimeout(n),h.data("callee2",arguments.callee),p100){h.data("doubletapped",!0),window.clearTimeout(i.tap_timer);var g={position:{x:i.touch_capable?e.originalEvent.changedTouches[0].screenX:e.screenX,y:i.touch_capable?e.originalEvent.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?e.originalEvent.changedTouches[0].pageX-e.originalEvent.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?e.originalEvent.changedTouches[0].pageY-e.originalEvent.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target},f={firstTap:o,secondTap:g,interval:g.time-o.time};u||a(r,"doubletap",e,f),u=!0,c=window.setTimeout(function(){u=!1},i.doubletap_int)}else h.data("lastTouch",s),n=window.setTimeout(function(){window.clearTimeout(n)},i.doubletap_int,[e]);h.data("lastTouch",s)})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,n=e(t),o=null,s=null,c={x:0,y:0};n.on(i.startevent,function(e){return e.which&&1!==e.which?!1:(s=Date.now(),o=e.target,n.data("callee1",arguments.callee),c.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,c.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,!0)}).on(i.endevent,function(e){n.data("callee2",arguments.callee),e.target==o&&(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,i.tap_timer=window.setTimeout(function(){if(!n.data("doubletapped")&&!n.data("tapheld")&&c.x==end_pos_x&&c.y==end_pos_y){var o=e.originalEvent,r={position:{x:i.touch_capable?o.changedTouches[0].screenX:e.screenX,y:i.touch_capable?o.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.changedTouches[0].pageX-o.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.changedTouches[0].pageY-o.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};r.time-s=-i.tap_pixel_range&&g<=i.tap_pixel_range&&f>=-i.tap_pixel_range&&f<=i.tap_pixel_range)){for(var d=e.originalEvent,v=[],w=0;wl.y&&u.y-l.y>g&&(a="swipeup"),u.xp&&(a="swiperight"),u.yg&&(a="swipedown"),u.x>l.x&&u.x-l.x>p&&(a="swipeleft"),void 0!=a&&r){u.x=0,u.y=0,l.x=0,l.y=0,r=!1;var f=t.originalEvent;endEvnt={position:{x:i.touch_capable?f.touches[0].screenX:t.screenX,y:i.touch_capable?f.touches[0].screenY:t.screenY},offset:{x:i.touch_capable?f.touches[0].pageX-f.touches[0].target.offsetLeft:t.offsetX,y:i.touch_capable?f.touches[0].pageY-f.touches[0].target.offsetTop:t.offsetY},time:Date.now(),target:t.target};var d=Math.abs(o.position.x-endEvnt.position.x),v=Math.abs(o.position.y-endEvnt.position.y),w={startEvnt:o,endEvnt:endEvnt,direction:a.replace("swipe",""),xAmount:d,yAmount:v,duration:endEvnt.time-o.time};h=!0,c.trigger("swipe",w).trigger(a,w)}}function n(t){c=e(t.target);var a="";if(c.data("callee3",arguments.callee),h){var n=c.data("xthreshold"),s=c.data("ythreshold"),u="undefined"!=typeof n&&n!==!1&&parseInt(n)?parseInt(n):i.swipe_h_threshold,l="undefined"!=typeof s&&s!==!1&&parseInt(s)?parseInt(s):i.swipe_v_threshold,p=t.originalEvent;endEvnt={position:{x:i.touch_capable?p.changedTouches[0].screenX:t.screenX,y:i.touch_capable?p.changedTouches[0].screenY:t.screenY},offset:{x:i.touch_capable?p.changedTouches[0].pageX-p.changedTouches[0].target.offsetLeft:t.offsetX,y:i.touch_capable?p.changedTouches[0].pageY-p.changedTouches[0].target.offsetTop:t.offsetY},time:Date.now(),target:t.target},o.position.y>endEvnt.position.y&&o.position.y-endEvnt.position.y>l&&(a="swipeup"),o.position.xu&&(a="swiperight"),o.position.yl&&(a="swipedown"),o.position.x>endEvnt.position.x&&o.position.x-endEvnt.position.x>u&&(a="swipeleft");var g=Math.abs(o.position.x-endEvnt.position.x),f=Math.abs(o.position.y-endEvnt.position.y),d={startEvnt:o,endEvnt:endEvnt,direction:a.replace("swipe",""),xAmount:g,yAmount:f,duration:endEvnt.time-o.time};c.trigger("swipeend",d)}r=!1,h=!1}var o,s=this,c=e(s),r=!1,h=!1,u={x:0,y:0},l={x:0,y:0};c.on(i.startevent,t),c.on(i.moveevent,a),c.on(i.endevent,n)},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.moveevent,e(this).data.callee2).off(i.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){function t(e,t){n=t,a(s,n?"scrollstart":"scrollend",e)}var n,o,s=this,c=e(s);c.on(i.scrollevent,function(e){c.data("callee",arguments.callee),n||t(e,!0),clearTimeout(o),o=setTimeout(function(){t(e,!1)},50)})},remove:function(){e(this).off(i.scrollevent,e(this).data.callee)}};var s,c,r,h,u,l=e(window),p={0:!0,180:!0};if(i.orientation_support){var g=window.innerWidth||l.width(),f=window.innerHeight||l.height(),d=50;h=g>f&&g-f>d,u=p[window.orientation],(h&&u||!h&&!u)&&(p={"-90":!0,90:!0})}e.event.special.orientationchange=s={setup:function(){return i.orientation_support?!1:(r=c(),l.on("throttledresize",t),!0)},teardown:function(){return i.orientation_support?!1:(l.off("throttledresize",t),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=c(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=c=function(){var e=!0,t=document.documentElement;return e=i.orientation_support?p[window.orientation]:t&&t.clientWidth/t.clientHeight<1.1,e?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",m)},teardown:function(){e(this).off("resize",m)}};var v,w,_,T=250,m=function(){w=Date.now(),_=w-x,_>=T?(x=w,e(this).trigger("throttledresize")):(v&&window.clearTimeout(v),v=window.setTimeout(t,T-_))},x=0;e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); From d438ce2ba50ad4adb7921f15ff99205652fb70a8 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 17 Jul 2015 13:29:55 +0100 Subject: [PATCH 003/149] Removing console.log() from production --- src/jquery.mobile-events.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/jquery.mobile-events.js b/src/jquery.mobile-events.js index ba1ccb0..95d42a4 100644 --- a/src/jquery.mobile-events.js +++ b/src/jquery.mobile-events.js @@ -570,9 +570,7 @@ 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; - - console.log(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'; From cacd19fcf4d4d77a08c80c9807d5a8b2a21f3edc Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 17 Jul 2015 13:30:14 +0100 Subject: [PATCH 004/149] Removing console.log() from production --- src/jquery.mobile-events.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jquery.mobile-events.min.js b/src/jquery.mobile-events.min.js index a9dfc3d..6cd66a5 100644 --- a/src/jquery.mobile-events.min.js +++ b/src/jquery.mobile-events.min.js @@ -1 +1 @@ -!function(e){function t(){var e=c();e!==r&&(r=e,l.trigger("orientationchange"))}function a(t,a,n,o){var i=n.type;n.type=a,e.event.dispatch.call(t,n,o),n.type=i}e.attrFn=e.attrFn||{};var n=navigator.userAgent.toLowerCase(),o=n.indexOf("chrome")>-1&&(n.indexOf("windows")>-1||n.indexOf("macintosh")>-1||n.indexOf("linux")>-1)&&n.indexOf("mobile")<0&&n.indexOf("android")<0,i={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:"ontouchstart"in window&&!o,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:"ontouchstart"in window&&!o?"touchstart":"mousedown",endevent:"ontouchstart"in window&&!o?"touchend":"mouseup",moveevent:"ontouchstart"in window&&!o?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!o?"tap":"click",scrollevent:"ontouchstart"in window&&!o?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.isTouchCapable=function(){return i.touch_capable},e.getStartEvent=function(){return i.startevent},e.getEndEvent=function(){return i.endevent},e.getMoveEvent=function(){return i.moveevent},e.getTapEvent=function(){return i.tapevent},e.getScrollEvent=function(){return i.scrollevent},e.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],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,n=e(t);n.on(i.startevent,function(e){if(n.data("callee",arguments.callee),e.which&&1!==e.which)return!1;var o=e.originalEvent,s={position:{x:i.touch_capable?o.touches[0].screenX:e.screenX,y:i.touch_capable?o.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.touches[0].pageX-o.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.touches[0].pageY-o.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapstart",e,s),!0})},remove:function(){e(this).off(i.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,n=e(t);n.on(i.moveevent,function(e){n.data("callee",arguments.callee);var o=e.originalEvent,s={position:{x:i.touch_capable?o.touches[0].screenX:e.screenX,y:i.touch_capable?o.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.touches[0].pageX-o.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.touches[0].pageY-o.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapmove",e,s),!0})},remove:function(){e(this).off(i.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,n=e(t);n.on(i.endevent,function(e){n.data("callee",arguments.callee);var o=e.originalEvent,s={position:{x:i.touch_capable?o.changedTouches[0].screenX:e.screenX,y:i.touch_capable?o.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.changedTouches[0].pageX-o.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.changedTouches[0].pageY-o.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapend",e,s),!0})},remove:function(){e(this).off(i.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,n=this,o=e(n),s={x:0,y:0},c=0,r=0;o.on(i.startevent,function(e){if(e.which&&1!==e.which)return!1;o.data("tapheld",!1),t=e.target;var h=e.originalEvent,u=Date.now(),l={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},p={x:i.touch_capable?h.touches[0].pageX-h.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?h.touches[0].pageY-h.touches[0].target.offsetTop:e.offsetY};return s.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,s.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,c=s.x,r=s.y,i.hold_timer=window.setTimeout(function(){var g=s.x-c,f=s.y-r;if(e.target==t&&(s.x==c&&s.y==r||g>=-i.tap_pixel_range&&g<=i.tap_pixel_range&&f>=-i.tap_pixel_range&&f<=i.tap_pixel_range)){o.data("tapheld",!0);var d=Date.now(),v={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},w={x:i.touch_capable?h.touches[0].pageX-h.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?h.touches[0].pageY-h.touches[0].target.offsetTop:e.offsetY};duration=d-u;var _={startTime:u,endTime:d,startPosition:l,startOffset:p,endPosition:v,endOffset:w,duration:duration,target:e.target};o.data("callee1",arguments.callee),a(n,"taphold",e,_)}},i.taphold_threshold),!0}).on(i.endevent,function(){o.data("callee2",arguments.callee),o.data("tapheld",!1),window.clearTimeout(i.hold_timer)}).on(i.moveevent,function(e){o.data("callee3",arguments.callee),c=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,r=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2).off(i.moveevent,e(this).data.callee3)}},e.event.special.doubletap={setup:function(){var t,n,o,s,c,r=this,h=e(r),u=!1;h.on(i.startevent,function(e){return e.which&&1!==e.which?!1:(h.data("doubletapped",!1),t=e.target,h.data("callee1",arguments.callee),s=e.originalEvent,o={position:{x:i.touch_capable?s.touches[0].screenX:e.screenX,y:i.touch_capable?s.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?s.touches[0].pageX-s.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?s.touches[0].pageY-s.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target},!0)}).on(i.endevent,function(e){var s=Date.now(),l=h.data("lastTouch")||s+1,p=s-l;if(window.clearTimeout(n),h.data("callee2",arguments.callee),p100){h.data("doubletapped",!0),window.clearTimeout(i.tap_timer);var g={position:{x:i.touch_capable?e.originalEvent.changedTouches[0].screenX:e.screenX,y:i.touch_capable?e.originalEvent.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?e.originalEvent.changedTouches[0].pageX-e.originalEvent.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?e.originalEvent.changedTouches[0].pageY-e.originalEvent.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target},f={firstTap:o,secondTap:g,interval:g.time-o.time};u||a(r,"doubletap",e,f),u=!0,c=window.setTimeout(function(){u=!1},i.doubletap_int)}else h.data("lastTouch",s),n=window.setTimeout(function(){window.clearTimeout(n)},i.doubletap_int,[e]);h.data("lastTouch",s)})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,n=e(t),o=null,s=null,c={x:0,y:0};n.on(i.startevent,function(e){return e.which&&1!==e.which?!1:(s=Date.now(),o=e.target,n.data("callee1",arguments.callee),c.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,c.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,!0)}).on(i.endevent,function(e){n.data("callee2",arguments.callee),e.target==o&&(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,i.tap_timer=window.setTimeout(function(){if(!n.data("doubletapped")&&!n.data("tapheld")&&c.x==end_pos_x&&c.y==end_pos_y){var o=e.originalEvent,r={position:{x:i.touch_capable?o.changedTouches[0].screenX:e.screenX,y:i.touch_capable?o.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.changedTouches[0].pageX-o.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.changedTouches[0].pageY-o.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};r.time-s=-i.tap_pixel_range&&g<=i.tap_pixel_range&&f>=-i.tap_pixel_range&&f<=i.tap_pixel_range)){for(var d=e.originalEvent,v=[],w=0;wl.y&&u.y-l.y>g&&(a="swipeup"),u.xp&&(a="swiperight"),u.yg&&(a="swipedown"),u.x>l.x&&u.x-l.x>p&&(a="swipeleft"),void 0!=a&&r){u.x=0,u.y=0,l.x=0,l.y=0,r=!1;var f=t.originalEvent;endEvnt={position:{x:i.touch_capable?f.touches[0].screenX:t.screenX,y:i.touch_capable?f.touches[0].screenY:t.screenY},offset:{x:i.touch_capable?f.touches[0].pageX-f.touches[0].target.offsetLeft:t.offsetX,y:i.touch_capable?f.touches[0].pageY-f.touches[0].target.offsetTop:t.offsetY},time:Date.now(),target:t.target};var d=Math.abs(o.position.x-endEvnt.position.x),v=Math.abs(o.position.y-endEvnt.position.y),w={startEvnt:o,endEvnt:endEvnt,direction:a.replace("swipe",""),xAmount:d,yAmount:v,duration:endEvnt.time-o.time};h=!0,c.trigger("swipe",w).trigger(a,w)}}function n(t){c=e(t.target);var a="";if(c.data("callee3",arguments.callee),h){var n=c.data("xthreshold"),s=c.data("ythreshold"),u="undefined"!=typeof n&&n!==!1&&parseInt(n)?parseInt(n):i.swipe_h_threshold,l="undefined"!=typeof s&&s!==!1&&parseInt(s)?parseInt(s):i.swipe_v_threshold,p=t.originalEvent;endEvnt={position:{x:i.touch_capable?p.changedTouches[0].screenX:t.screenX,y:i.touch_capable?p.changedTouches[0].screenY:t.screenY},offset:{x:i.touch_capable?p.changedTouches[0].pageX-p.changedTouches[0].target.offsetLeft:t.offsetX,y:i.touch_capable?p.changedTouches[0].pageY-p.changedTouches[0].target.offsetTop:t.offsetY},time:Date.now(),target:t.target},o.position.y>endEvnt.position.y&&o.position.y-endEvnt.position.y>l&&(a="swipeup"),o.position.xu&&(a="swiperight"),o.position.yl&&(a="swipedown"),o.position.x>endEvnt.position.x&&o.position.x-endEvnt.position.x>u&&(a="swipeleft");var g=Math.abs(o.position.x-endEvnt.position.x),f=Math.abs(o.position.y-endEvnt.position.y),d={startEvnt:o,endEvnt:endEvnt,direction:a.replace("swipe",""),xAmount:g,yAmount:f,duration:endEvnt.time-o.time};c.trigger("swipeend",d)}r=!1,h=!1}var o,s=this,c=e(s),r=!1,h=!1,u={x:0,y:0},l={x:0,y:0};c.on(i.startevent,t),c.on(i.moveevent,a),c.on(i.endevent,n)},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.moveevent,e(this).data.callee2).off(i.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){function t(e,t){n=t,a(s,n?"scrollstart":"scrollend",e)}var n,o,s=this,c=e(s);c.on(i.scrollevent,function(e){c.data("callee",arguments.callee),n||t(e,!0),clearTimeout(o),o=setTimeout(function(){t(e,!1)},50)})},remove:function(){e(this).off(i.scrollevent,e(this).data.callee)}};var s,c,r,h,u,l=e(window),p={0:!0,180:!0};if(i.orientation_support){var g=window.innerWidth||l.width(),f=window.innerHeight||l.height(),d=50;h=g>f&&g-f>d,u=p[window.orientation],(h&&u||!h&&!u)&&(p={"-90":!0,90:!0})}e.event.special.orientationchange=s={setup:function(){return i.orientation_support?!1:(r=c(),l.on("throttledresize",t),!0)},teardown:function(){return i.orientation_support?!1:(l.off("throttledresize",t),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=c(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=c=function(){var e=!0,t=document.documentElement;return e=i.orientation_support?p[window.orientation]:t&&t.clientWidth/t.clientHeight<1.1,e?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",m)},teardown:function(){e(this).off("resize",m)}};var v,w,_,T=250,m=function(){w=Date.now(),_=w-x,_>=T?(x=w,e(this).trigger("throttledresize")):(v&&window.clearTimeout(v),v=window.setTimeout(t,T-_))},x=0;e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); +!function(e){function t(){var e=c();e!==r&&(r=e,l.trigger("orientationchange"))}function a(t,a,n,o){var i=n.type;n.type=a,e.event.dispatch.call(t,n,o),n.type=i}e.attrFn=e.attrFn||{};var n=navigator.userAgent.toLowerCase(),o=n.indexOf("chrome")>-1&&(n.indexOf("windows")>-1||n.indexOf("macintosh")>-1||n.indexOf("linux")>-1)&&n.indexOf("mobile")<0&&n.indexOf("android")<0,i={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:"ontouchstart"in window&&!o,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:"ontouchstart"in window&&!o?"touchstart":"mousedown",endevent:"ontouchstart"in window&&!o?"touchend":"mouseup",moveevent:"ontouchstart"in window&&!o?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!o?"tap":"click",scrollevent:"ontouchstart"in window&&!o?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.isTouchCapable=function(){return i.touch_capable},e.getStartEvent=function(){return i.startevent},e.getEndEvent=function(){return i.endevent},e.getMoveEvent=function(){return i.moveevent},e.getTapEvent=function(){return i.tapevent},e.getScrollEvent=function(){return i.scrollevent},e.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],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,n=e(t);n.on(i.startevent,function(e){if(n.data("callee",arguments.callee),e.which&&1!==e.which)return!1;var o=e.originalEvent,s={position:{x:i.touch_capable?o.touches[0].screenX:e.screenX,y:i.touch_capable?o.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.touches[0].pageX-o.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.touches[0].pageY-o.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapstart",e,s),!0})},remove:function(){e(this).off(i.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,n=e(t);n.on(i.moveevent,function(e){n.data("callee",arguments.callee);var o=e.originalEvent,s={position:{x:i.touch_capable?o.touches[0].screenX:e.screenX,y:i.touch_capable?o.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.touches[0].pageX-o.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.touches[0].pageY-o.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapmove",e,s),!0})},remove:function(){e(this).off(i.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,n=e(t);n.on(i.endevent,function(e){n.data("callee",arguments.callee);var o=e.originalEvent,s={position:{x:i.touch_capable?o.changedTouches[0].screenX:e.screenX,y:i.touch_capable?o.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.changedTouches[0].pageX-o.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.changedTouches[0].pageY-o.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapend",e,s),!0})},remove:function(){e(this).off(i.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,n=this,o=e(n),s={x:0,y:0},c=0,r=0;o.on(i.startevent,function(e){if(e.which&&1!==e.which)return!1;o.data("tapheld",!1),t=e.target;var h=e.originalEvent,u=Date.now(),l={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},p={x:i.touch_capable?h.touches[0].pageX-h.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?h.touches[0].pageY-h.touches[0].target.offsetTop:e.offsetY};return s.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,s.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,c=s.x,r=s.y,i.hold_timer=window.setTimeout(function(){var g=s.x-c,f=s.y-r;if(e.target==t&&(s.x==c&&s.y==r||g>=-i.tap_pixel_range&&g<=i.tap_pixel_range&&f>=-i.tap_pixel_range&&f<=i.tap_pixel_range)){o.data("tapheld",!0);var d=Date.now(),v={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},w={x:i.touch_capable?h.touches[0].pageX-h.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?h.touches[0].pageY-h.touches[0].target.offsetTop:e.offsetY};duration=d-u;var _={startTime:u,endTime:d,startPosition:l,startOffset:p,endPosition:v,endOffset:w,duration:duration,target:e.target};o.data("callee1",arguments.callee),a(n,"taphold",e,_)}},i.taphold_threshold),!0}).on(i.endevent,function(){o.data("callee2",arguments.callee),o.data("tapheld",!1),window.clearTimeout(i.hold_timer)}).on(i.moveevent,function(e){o.data("callee3",arguments.callee),c=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,r=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2).off(i.moveevent,e(this).data.callee3)}},e.event.special.doubletap={setup:function(){var t,n,o,s,c,r=this,h=e(r),u=!1;h.on(i.startevent,function(e){return e.which&&1!==e.which?!1:(h.data("doubletapped",!1),t=e.target,h.data("callee1",arguments.callee),s=e.originalEvent,o={position:{x:i.touch_capable?s.touches[0].screenX:e.screenX,y:i.touch_capable?s.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?s.touches[0].pageX-s.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?s.touches[0].pageY-s.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target},!0)}).on(i.endevent,function(e){var s=Date.now(),l=h.data("lastTouch")||s+1,p=s-l;if(window.clearTimeout(n),h.data("callee2",arguments.callee),p100){h.data("doubletapped",!0),window.clearTimeout(i.tap_timer);var g={position:{x:i.touch_capable?e.originalEvent.changedTouches[0].screenX:e.screenX,y:i.touch_capable?e.originalEvent.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?e.originalEvent.changedTouches[0].pageX-e.originalEvent.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?e.originalEvent.changedTouches[0].pageY-e.originalEvent.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target},f={firstTap:o,secondTap:g,interval:g.time-o.time};u||a(r,"doubletap",e,f),u=!0,c=window.setTimeout(function(){u=!1},i.doubletap_int)}else h.data("lastTouch",s),n=window.setTimeout(function(){window.clearTimeout(n)},i.doubletap_int,[e]);h.data("lastTouch",s)})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,n=e(t),o=null,s=null,c={x:0,y:0};n.on(i.startevent,function(e){return e.which&&1!==e.which?!1:(s=Date.now(),o=e.target,n.data("callee1",arguments.callee),c.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,c.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,!0)}).on(i.endevent,function(e){n.data("callee2",arguments.callee),e.target==o&&(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,i.tap_timer=window.setTimeout(function(){if(!n.data("doubletapped")&&!n.data("tapheld")&&c.x==end_pos_x&&c.y==end_pos_y){var o=e.originalEvent,r={position:{x:i.touch_capable?o.changedTouches[0].screenX:e.screenX,y:i.touch_capable?o.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.changedTouches[0].pageX-o.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.changedTouches[0].pageY-o.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};r.time-s=-i.tap_pixel_range&&g<=i.tap_pixel_range&&f>=-i.tap_pixel_range&&f<=i.tap_pixel_range)){for(var d=e.originalEvent,v=[],w=0;wl.y&&u.y-l.y>g&&(a="swipeup"),u.xp&&(a="swiperight"),u.yg&&(a="swipedown"),u.x>l.x&&u.x-l.x>p&&(a="swipeleft"),void 0!=a&&r){u.x=0,u.y=0,l.x=0,l.y=0,r=!1;var f=t.originalEvent;endEvnt={position:{x:i.touch_capable?f.touches[0].screenX:t.screenX,y:i.touch_capable?f.touches[0].screenY:t.screenY},offset:{x:i.touch_capable?f.touches[0].pageX-f.touches[0].target.offsetLeft:t.offsetX,y:i.touch_capable?f.touches[0].pageY-f.touches[0].target.offsetTop:t.offsetY},time:Date.now(),target:t.target};var d=Math.abs(o.position.x-endEvnt.position.x),v=Math.abs(o.position.y-endEvnt.position.y),w={startEvnt:o,endEvnt:endEvnt,direction:a.replace("swipe",""),xAmount:d,yAmount:v,duration:endEvnt.time-o.time};h=!0,c.trigger("swipe",w).trigger(a,w)}}function n(t){c=e(t.target);var a="";if(c.data("callee3",arguments.callee),h){var n=c.data("xthreshold"),s=c.data("ythreshold"),u="undefined"!=typeof n&&n!==!1&&parseInt(n)?parseInt(n):i.swipe_h_threshold,l="undefined"!=typeof s&&s!==!1&&parseInt(s)?parseInt(s):i.swipe_v_threshold,p=t.originalEvent;endEvnt={position:{x:i.touch_capable?p.changedTouches[0].screenX:t.screenX,y:i.touch_capable?p.changedTouches[0].screenY:t.screenY},offset:{x:i.touch_capable?p.changedTouches[0].pageX-p.changedTouches[0].target.offsetLeft:t.offsetX,y:i.touch_capable?p.changedTouches[0].pageY-p.changedTouches[0].target.offsetTop:t.offsetY},time:Date.now(),target:t.target},o.position.y>endEvnt.position.y&&o.position.y-endEvnt.position.y>l&&(a="swipeup"),o.position.xu&&(a="swiperight"),o.position.yl&&(a="swipedown"),o.position.x>endEvnt.position.x&&o.position.x-endEvnt.position.x>u&&(a="swipeleft");var g=Math.abs(o.position.x-endEvnt.position.x),f=Math.abs(o.position.y-endEvnt.position.y),d={startEvnt:o,endEvnt:endEvnt,direction:a.replace("swipe",""),xAmount:g,yAmount:f,duration:endEvnt.time-o.time};c.trigger("swipeend",d)}r=!1,h=!1}var o,s=this,c=e(s),r=!1,h=!1,u={x:0,y:0},l={x:0,y:0};c.on(i.startevent,t),c.on(i.moveevent,a),c.on(i.endevent,n)},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.moveevent,e(this).data.callee2).off(i.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){function t(e,t){n=t,a(s,n?"scrollstart":"scrollend",e)}var n,o,s=this,c=e(s);c.on(i.scrollevent,function(e){c.data("callee",arguments.callee),n||t(e,!0),clearTimeout(o),o=setTimeout(function(){t(e,!1)},50)})},remove:function(){e(this).off(i.scrollevent,e(this).data.callee)}};var s,c,r,h,u,l=e(window),p={0:!0,180:!0};if(i.orientation_support){var g=window.innerWidth||l.width(),f=window.innerHeight||l.height(),d=50;h=g>f&&g-f>d,u=p[window.orientation],(h&&u||!h&&!u)&&(p={"-90":!0,90:!0})}e.event.special.orientationchange=s={setup:function(){return i.orientation_support?!1:(r=c(),l.on("throttledresize",t),!0)},teardown:function(){return i.orientation_support?!1:(l.off("throttledresize",t),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=c(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=c=function(){var e=!0,t=document.documentElement;return e=i.orientation_support?p[window.orientation]:t&&t.clientWidth/t.clientHeight<1.1,e?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",m)},teardown:function(){e(this).off("resize",m)}};var v,w,_,T=250,m=function(){w=Date.now(),_=w-x,_>=T?(x=w,e(this).trigger("throttledresize")):(v&&window.clearTimeout(v),v=window.setTimeout(t,T-_))},x=0;e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); From fb25a12c804ad9aef1f5f1dfa772d9eafb33b087 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Sat, 18 Jul 2015 11:28:48 +0100 Subject: [PATCH 005/149] Fixed e.currentTarget issue --- src/{ => v1}/jquery.mobile-events.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename src/{ => v1}/jquery.mobile-events.js (99%) diff --git a/src/jquery.mobile-events.js b/src/v1/jquery.mobile-events.js similarity index 99% rename from src/jquery.mobile-events.js rename to src/v1/jquery.mobile-events.js index 95d42a4..f935863 100644 --- a/src/jquery.mobile-events.js +++ b/src/v1/jquery.mobile-events.js @@ -533,7 +533,7 @@ // Screen touched, store the original coordinate function touchStart(e) { - $this = $(e.target); + $this = $(e.currentTarget); $this.data('callee1', arguments.callee); originalCoord.x = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageX : e.pageX; originalCoord.y = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageY : e.pageY; @@ -559,7 +559,7 @@ // Store coordinates as finger is swiping function touchMove(e) { - $this = $(e.target); + $this = $(e.currentTarget); $this.data('callee2', arguments.callee); finalCoord.x = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageX : e.pageX; finalCoord.y = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageY : e.pageY; @@ -624,7 +624,7 @@ } function touchEnd(e) { - $this = $(e.target); + $this = $(e.currentTarget); var swipedir = ""; $this.data('callee3', arguments.callee); if (hasSwiped) { From 99d7700a094b2d55c0b39ca982fffd93627c69ef Mon Sep 17 00:00:00 2001 From: Ben Major Date: Sat, 18 Jul 2015 11:29:13 +0100 Subject: [PATCH 006/149] Fixed e.currentTarget issue --- src/{ => v1}/jquery.mobile-events.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/{ => v1}/jquery.mobile-events.min.js (65%) diff --git a/src/jquery.mobile-events.min.js b/src/v1/jquery.mobile-events.min.js similarity index 65% rename from src/jquery.mobile-events.min.js rename to src/v1/jquery.mobile-events.min.js index 6cd66a5..63b10c9 100644 --- a/src/jquery.mobile-events.min.js +++ b/src/v1/jquery.mobile-events.min.js @@ -1 +1 @@ -!function(e){function t(){var e=c();e!==r&&(r=e,l.trigger("orientationchange"))}function a(t,a,n,o){var i=n.type;n.type=a,e.event.dispatch.call(t,n,o),n.type=i}e.attrFn=e.attrFn||{};var n=navigator.userAgent.toLowerCase(),o=n.indexOf("chrome")>-1&&(n.indexOf("windows")>-1||n.indexOf("macintosh")>-1||n.indexOf("linux")>-1)&&n.indexOf("mobile")<0&&n.indexOf("android")<0,i={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:"ontouchstart"in window&&!o,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:"ontouchstart"in window&&!o?"touchstart":"mousedown",endevent:"ontouchstart"in window&&!o?"touchend":"mouseup",moveevent:"ontouchstart"in window&&!o?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!o?"tap":"click",scrollevent:"ontouchstart"in window&&!o?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.isTouchCapable=function(){return i.touch_capable},e.getStartEvent=function(){return i.startevent},e.getEndEvent=function(){return i.endevent},e.getMoveEvent=function(){return i.moveevent},e.getTapEvent=function(){return i.tapevent},e.getScrollEvent=function(){return i.scrollevent},e.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],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,n=e(t);n.on(i.startevent,function(e){if(n.data("callee",arguments.callee),e.which&&1!==e.which)return!1;var o=e.originalEvent,s={position:{x:i.touch_capable?o.touches[0].screenX:e.screenX,y:i.touch_capable?o.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.touches[0].pageX-o.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.touches[0].pageY-o.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapstart",e,s),!0})},remove:function(){e(this).off(i.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,n=e(t);n.on(i.moveevent,function(e){n.data("callee",arguments.callee);var o=e.originalEvent,s={position:{x:i.touch_capable?o.touches[0].screenX:e.screenX,y:i.touch_capable?o.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.touches[0].pageX-o.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.touches[0].pageY-o.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapmove",e,s),!0})},remove:function(){e(this).off(i.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,n=e(t);n.on(i.endevent,function(e){n.data("callee",arguments.callee);var o=e.originalEvent,s={position:{x:i.touch_capable?o.changedTouches[0].screenX:e.screenX,y:i.touch_capable?o.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.changedTouches[0].pageX-o.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.changedTouches[0].pageY-o.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapend",e,s),!0})},remove:function(){e(this).off(i.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,n=this,o=e(n),s={x:0,y:0},c=0,r=0;o.on(i.startevent,function(e){if(e.which&&1!==e.which)return!1;o.data("tapheld",!1),t=e.target;var h=e.originalEvent,u=Date.now(),l={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},p={x:i.touch_capable?h.touches[0].pageX-h.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?h.touches[0].pageY-h.touches[0].target.offsetTop:e.offsetY};return s.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,s.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,c=s.x,r=s.y,i.hold_timer=window.setTimeout(function(){var g=s.x-c,f=s.y-r;if(e.target==t&&(s.x==c&&s.y==r||g>=-i.tap_pixel_range&&g<=i.tap_pixel_range&&f>=-i.tap_pixel_range&&f<=i.tap_pixel_range)){o.data("tapheld",!0);var d=Date.now(),v={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},w={x:i.touch_capable?h.touches[0].pageX-h.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?h.touches[0].pageY-h.touches[0].target.offsetTop:e.offsetY};duration=d-u;var _={startTime:u,endTime:d,startPosition:l,startOffset:p,endPosition:v,endOffset:w,duration:duration,target:e.target};o.data("callee1",arguments.callee),a(n,"taphold",e,_)}},i.taphold_threshold),!0}).on(i.endevent,function(){o.data("callee2",arguments.callee),o.data("tapheld",!1),window.clearTimeout(i.hold_timer)}).on(i.moveevent,function(e){o.data("callee3",arguments.callee),c=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,r=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2).off(i.moveevent,e(this).data.callee3)}},e.event.special.doubletap={setup:function(){var t,n,o,s,c,r=this,h=e(r),u=!1;h.on(i.startevent,function(e){return e.which&&1!==e.which?!1:(h.data("doubletapped",!1),t=e.target,h.data("callee1",arguments.callee),s=e.originalEvent,o={position:{x:i.touch_capable?s.touches[0].screenX:e.screenX,y:i.touch_capable?s.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?s.touches[0].pageX-s.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?s.touches[0].pageY-s.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target},!0)}).on(i.endevent,function(e){var s=Date.now(),l=h.data("lastTouch")||s+1,p=s-l;if(window.clearTimeout(n),h.data("callee2",arguments.callee),p100){h.data("doubletapped",!0),window.clearTimeout(i.tap_timer);var g={position:{x:i.touch_capable?e.originalEvent.changedTouches[0].screenX:e.screenX,y:i.touch_capable?e.originalEvent.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?e.originalEvent.changedTouches[0].pageX-e.originalEvent.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?e.originalEvent.changedTouches[0].pageY-e.originalEvent.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target},f={firstTap:o,secondTap:g,interval:g.time-o.time};u||a(r,"doubletap",e,f),u=!0,c=window.setTimeout(function(){u=!1},i.doubletap_int)}else h.data("lastTouch",s),n=window.setTimeout(function(){window.clearTimeout(n)},i.doubletap_int,[e]);h.data("lastTouch",s)})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,n=e(t),o=null,s=null,c={x:0,y:0};n.on(i.startevent,function(e){return e.which&&1!==e.which?!1:(s=Date.now(),o=e.target,n.data("callee1",arguments.callee),c.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,c.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,!0)}).on(i.endevent,function(e){n.data("callee2",arguments.callee),e.target==o&&(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,i.tap_timer=window.setTimeout(function(){if(!n.data("doubletapped")&&!n.data("tapheld")&&c.x==end_pos_x&&c.y==end_pos_y){var o=e.originalEvent,r={position:{x:i.touch_capable?o.changedTouches[0].screenX:e.screenX,y:i.touch_capable?o.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.changedTouches[0].pageX-o.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.changedTouches[0].pageY-o.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};r.time-s=-i.tap_pixel_range&&g<=i.tap_pixel_range&&f>=-i.tap_pixel_range&&f<=i.tap_pixel_range)){for(var d=e.originalEvent,v=[],w=0;wl.y&&u.y-l.y>g&&(a="swipeup"),u.xp&&(a="swiperight"),u.yg&&(a="swipedown"),u.x>l.x&&u.x-l.x>p&&(a="swipeleft"),void 0!=a&&r){u.x=0,u.y=0,l.x=0,l.y=0,r=!1;var f=t.originalEvent;endEvnt={position:{x:i.touch_capable?f.touches[0].screenX:t.screenX,y:i.touch_capable?f.touches[0].screenY:t.screenY},offset:{x:i.touch_capable?f.touches[0].pageX-f.touches[0].target.offsetLeft:t.offsetX,y:i.touch_capable?f.touches[0].pageY-f.touches[0].target.offsetTop:t.offsetY},time:Date.now(),target:t.target};var d=Math.abs(o.position.x-endEvnt.position.x),v=Math.abs(o.position.y-endEvnt.position.y),w={startEvnt:o,endEvnt:endEvnt,direction:a.replace("swipe",""),xAmount:d,yAmount:v,duration:endEvnt.time-o.time};h=!0,c.trigger("swipe",w).trigger(a,w)}}function n(t){c=e(t.target);var a="";if(c.data("callee3",arguments.callee),h){var n=c.data("xthreshold"),s=c.data("ythreshold"),u="undefined"!=typeof n&&n!==!1&&parseInt(n)?parseInt(n):i.swipe_h_threshold,l="undefined"!=typeof s&&s!==!1&&parseInt(s)?parseInt(s):i.swipe_v_threshold,p=t.originalEvent;endEvnt={position:{x:i.touch_capable?p.changedTouches[0].screenX:t.screenX,y:i.touch_capable?p.changedTouches[0].screenY:t.screenY},offset:{x:i.touch_capable?p.changedTouches[0].pageX-p.changedTouches[0].target.offsetLeft:t.offsetX,y:i.touch_capable?p.changedTouches[0].pageY-p.changedTouches[0].target.offsetTop:t.offsetY},time:Date.now(),target:t.target},o.position.y>endEvnt.position.y&&o.position.y-endEvnt.position.y>l&&(a="swipeup"),o.position.xu&&(a="swiperight"),o.position.yl&&(a="swipedown"),o.position.x>endEvnt.position.x&&o.position.x-endEvnt.position.x>u&&(a="swipeleft");var g=Math.abs(o.position.x-endEvnt.position.x),f=Math.abs(o.position.y-endEvnt.position.y),d={startEvnt:o,endEvnt:endEvnt,direction:a.replace("swipe",""),xAmount:g,yAmount:f,duration:endEvnt.time-o.time};c.trigger("swipeend",d)}r=!1,h=!1}var o,s=this,c=e(s),r=!1,h=!1,u={x:0,y:0},l={x:0,y:0};c.on(i.startevent,t),c.on(i.moveevent,a),c.on(i.endevent,n)},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.moveevent,e(this).data.callee2).off(i.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){function t(e,t){n=t,a(s,n?"scrollstart":"scrollend",e)}var n,o,s=this,c=e(s);c.on(i.scrollevent,function(e){c.data("callee",arguments.callee),n||t(e,!0),clearTimeout(o),o=setTimeout(function(){t(e,!1)},50)})},remove:function(){e(this).off(i.scrollevent,e(this).data.callee)}};var s,c,r,h,u,l=e(window),p={0:!0,180:!0};if(i.orientation_support){var g=window.innerWidth||l.width(),f=window.innerHeight||l.height(),d=50;h=g>f&&g-f>d,u=p[window.orientation],(h&&u||!h&&!u)&&(p={"-90":!0,90:!0})}e.event.special.orientationchange=s={setup:function(){return i.orientation_support?!1:(r=c(),l.on("throttledresize",t),!0)},teardown:function(){return i.orientation_support?!1:(l.off("throttledresize",t),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=c(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=c=function(){var e=!0,t=document.documentElement;return e=i.orientation_support?p[window.orientation]:t&&t.clientWidth/t.clientHeight<1.1,e?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",m)},teardown:function(){e(this).off("resize",m)}};var v,w,_,T=250,m=function(){w=Date.now(),_=w-x,_>=T?(x=w,e(this).trigger("throttledresize")):(v&&window.clearTimeout(v),v=window.setTimeout(t,T-_))},x=0;e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); +!function(e){function t(){var e=c();e!==r&&(r=e,l.trigger("orientationchange"))}function a(t,a,n,o){var i=n.type;n.type=a,e.event.dispatch.call(t,n,o),n.type=i}e.attrFn=e.attrFn||{};var n=navigator.userAgent.toLowerCase(),o=n.indexOf("chrome")>-1&&(n.indexOf("windows")>-1||n.indexOf("macintosh")>-1||n.indexOf("linux")>-1)&&n.indexOf("mobile")<0&&n.indexOf("android")<0,i={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:"ontouchstart"in window&&!o,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:"ontouchstart"in window&&!o?"touchstart":"mousedown",endevent:"ontouchstart"in window&&!o?"touchend":"mouseup",moveevent:"ontouchstart"in window&&!o?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!o?"tap":"click",scrollevent:"ontouchstart"in window&&!o?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.isTouchCapable=function(){return i.touch_capable},e.getStartEvent=function(){return i.startevent},e.getEndEvent=function(){return i.endevent},e.getMoveEvent=function(){return i.moveevent},e.getTapEvent=function(){return i.tapevent},e.getScrollEvent=function(){return i.scrollevent},e.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],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,n=e(t);n.on(i.startevent,function(e){if(n.data("callee",arguments.callee),e.which&&1!==e.which)return!1;var o=e.originalEvent,s={position:{x:i.touch_capable?o.touches[0].screenX:e.screenX,y:i.touch_capable?o.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.touches[0].pageX-o.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.touches[0].pageY-o.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapstart",e,s),!0})},remove:function(){e(this).off(i.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,n=e(t);n.on(i.moveevent,function(e){n.data("callee",arguments.callee);var o=e.originalEvent,s={position:{x:i.touch_capable?o.touches[0].screenX:e.screenX,y:i.touch_capable?o.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.touches[0].pageX-o.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.touches[0].pageY-o.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapmove",e,s),!0})},remove:function(){e(this).off(i.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,n=e(t);n.on(i.endevent,function(e){n.data("callee",arguments.callee);var o=e.originalEvent,s={position:{x:i.touch_capable?o.changedTouches[0].screenX:e.screenX,y:i.touch_capable?o.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.changedTouches[0].pageX-o.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.changedTouches[0].pageY-o.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapend",e,s),!0})},remove:function(){e(this).off(i.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,n=this,o=e(n),s={x:0,y:0},c=0,r=0;o.on(i.startevent,function(e){if(e.which&&1!==e.which)return!1;o.data("tapheld",!1),t=e.target;var h=e.originalEvent,u=Date.now(),l={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},p={x:i.touch_capable?h.touches[0].pageX-h.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?h.touches[0].pageY-h.touches[0].target.offsetTop:e.offsetY};return s.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,s.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,c=s.x,r=s.y,i.hold_timer=window.setTimeout(function(){var g=s.x-c,f=s.y-r;if(e.target==t&&(s.x==c&&s.y==r||g>=-i.tap_pixel_range&&g<=i.tap_pixel_range&&f>=-i.tap_pixel_range&&f<=i.tap_pixel_range)){o.data("tapheld",!0);var d=Date.now(),v={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},w={x:i.touch_capable?h.touches[0].pageX-h.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?h.touches[0].pageY-h.touches[0].target.offsetTop:e.offsetY};duration=d-u;var _={startTime:u,endTime:d,startPosition:l,startOffset:p,endPosition:v,endOffset:w,duration:duration,target:e.target};o.data("callee1",arguments.callee),a(n,"taphold",e,_)}},i.taphold_threshold),!0}).on(i.endevent,function(){o.data("callee2",arguments.callee),o.data("tapheld",!1),window.clearTimeout(i.hold_timer)}).on(i.moveevent,function(e){o.data("callee3",arguments.callee),c=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,r=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2).off(i.moveevent,e(this).data.callee3)}},e.event.special.doubletap={setup:function(){var t,n,o,s,c,r=this,h=e(r),u=!1;h.on(i.startevent,function(e){return e.which&&1!==e.which?!1:(h.data("doubletapped",!1),t=e.target,h.data("callee1",arguments.callee),s=e.originalEvent,o={position:{x:i.touch_capable?s.touches[0].screenX:e.screenX,y:i.touch_capable?s.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?s.touches[0].pageX-s.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?s.touches[0].pageY-s.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target},!0)}).on(i.endevent,function(e){var s=Date.now(),l=h.data("lastTouch")||s+1,p=s-l;if(window.clearTimeout(n),h.data("callee2",arguments.callee),p100){h.data("doubletapped",!0),window.clearTimeout(i.tap_timer);var g={position:{x:i.touch_capable?e.originalEvent.changedTouches[0].screenX:e.screenX,y:i.touch_capable?e.originalEvent.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?e.originalEvent.changedTouches[0].pageX-e.originalEvent.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?e.originalEvent.changedTouches[0].pageY-e.originalEvent.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target},f={firstTap:o,secondTap:g,interval:g.time-o.time};u||a(r,"doubletap",e,f),u=!0,c=window.setTimeout(function(){u=!1},i.doubletap_int)}else h.data("lastTouch",s),n=window.setTimeout(function(){window.clearTimeout(n)},i.doubletap_int,[e]);h.data("lastTouch",s)})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,n=e(t),o=null,s=null,c={x:0,y:0};n.on(i.startevent,function(e){return e.which&&1!==e.which?!1:(s=Date.now(),o=e.target,n.data("callee1",arguments.callee),c.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,c.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,!0)}).on(i.endevent,function(e){n.data("callee2",arguments.callee),e.target==o&&(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,i.tap_timer=window.setTimeout(function(){if(!n.data("doubletapped")&&!n.data("tapheld")&&c.x==end_pos_x&&c.y==end_pos_y){var o=e.originalEvent,r={position:{x:i.touch_capable?o.changedTouches[0].screenX:e.screenX,y:i.touch_capable?o.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.changedTouches[0].pageX-o.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.changedTouches[0].pageY-o.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};r.time-s=-i.tap_pixel_range&&g<=i.tap_pixel_range&&f>=-i.tap_pixel_range&&f<=i.tap_pixel_range)){for(var d=e.originalEvent,v=[],w=0;wl.y&&u.y-l.y>g&&(a="swipeup"),u.xp&&(a="swiperight"),u.yg&&(a="swipedown"),u.x>l.x&&u.x-l.x>p&&(a="swipeleft"),void 0!=a&&r){u.x=0,u.y=0,l.x=0,l.y=0,r=!1;var f=t.originalEvent;endEvnt={position:{x:i.touch_capable?f.touches[0].screenX:t.screenX,y:i.touch_capable?f.touches[0].screenY:t.screenY},offset:{x:i.touch_capable?f.touches[0].pageX-f.touches[0].target.offsetLeft:t.offsetX,y:i.touch_capable?f.touches[0].pageY-f.touches[0].target.offsetTop:t.offsetY},time:Date.now(),target:t.target};var d=Math.abs(o.position.x-endEvnt.position.x),v=Math.abs(o.position.y-endEvnt.position.y),w={startEvnt:o,endEvnt:endEvnt,direction:a.replace("swipe",""),xAmount:d,yAmount:v,duration:endEvnt.time-o.time};h=!0,c.trigger("swipe",w).trigger(a,w)}}function n(t){c=e(t.currentTarget);var a="";if(c.data("callee3",arguments.callee),h){var n=c.data("xthreshold"),s=c.data("ythreshold"),u="undefined"!=typeof n&&n!==!1&&parseInt(n)?parseInt(n):i.swipe_h_threshold,l="undefined"!=typeof s&&s!==!1&&parseInt(s)?parseInt(s):i.swipe_v_threshold,p=t.originalEvent;endEvnt={position:{x:i.touch_capable?p.changedTouches[0].screenX:t.screenX,y:i.touch_capable?p.changedTouches[0].screenY:t.screenY},offset:{x:i.touch_capable?p.changedTouches[0].pageX-p.changedTouches[0].target.offsetLeft:t.offsetX,y:i.touch_capable?p.changedTouches[0].pageY-p.changedTouches[0].target.offsetTop:t.offsetY},time:Date.now(),target:t.target},o.position.y>endEvnt.position.y&&o.position.y-endEvnt.position.y>l&&(a="swipeup"),o.position.xu&&(a="swiperight"),o.position.yl&&(a="swipedown"),o.position.x>endEvnt.position.x&&o.position.x-endEvnt.position.x>u&&(a="swipeleft");var g=Math.abs(o.position.x-endEvnt.position.x),f=Math.abs(o.position.y-endEvnt.position.y),d={startEvnt:o,endEvnt:endEvnt,direction:a.replace("swipe",""),xAmount:g,yAmount:f,duration:endEvnt.time-o.time};c.trigger("swipeend",d)}r=!1,h=!1}var o,s=this,c=e(s),r=!1,h=!1,u={x:0,y:0},l={x:0,y:0};c.on(i.startevent,t),c.on(i.moveevent,a),c.on(i.endevent,n)},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.moveevent,e(this).data.callee2).off(i.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){function t(e,t){n=t,a(s,n?"scrollstart":"scrollend",e)}var n,o,s=this,c=e(s);c.on(i.scrollevent,function(e){c.data("callee",arguments.callee),n||t(e,!0),clearTimeout(o),o=setTimeout(function(){t(e,!1)},50)})},remove:function(){e(this).off(i.scrollevent,e(this).data.callee)}};var s,c,r,h,u,l=e(window),p={0:!0,180:!0};if(i.orientation_support){var g=window.innerWidth||l.width(),f=window.innerHeight||l.height(),d=50;h=g>f&&g-f>d,u=p[window.orientation],(h&&u||!h&&!u)&&(p={"-90":!0,90:!0})}e.event.special.orientationchange=s={setup:function(){return i.orientation_support?!1:(r=c(),l.on("throttledresize",t),!0)},teardown:function(){return i.orientation_support?!1:(l.off("throttledresize",t),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=c(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=c=function(){var e=!0,t=document.documentElement;return e=i.orientation_support?p[window.orientation]:t&&t.clientWidth/t.clientHeight<1.1,e?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",m)},teardown:function(){e(this).off("resize",m)}};var v,w,_,T=250,m=function(){w=Date.now(),_=w-x,_>=T?(x=w,e(this).trigger("throttledresize")):(v&&window.clearTimeout(v),v=window.setTimeout(t,T-_))},x=0;e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); From d71d498d2d70763f6594318acc4ca8dc82465031 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Sat, 18 Jul 2015 11:32:59 +0100 Subject: [PATCH 007/149] Added information about versioning. --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 8854b3d..ccc7576 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,14 @@ This is a series of plugins that create additional events that can be used in co As explained, the events are each triggered by native touch events, or alternatively by click events. The plugin automatically detects whether the user's device is touch compatible, and will use the correct native events whenever required. It is hoped that these events will help to aid single-environment development with jQuery for mobile web app development. +Version History: +--------------- + +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: + +**2015-07-18 - Version 1.0.0** +The library officially entered 1.0.0 after minor bug fixes and final adjustments. + Utility Functions: ----------------- In addition to the numerous additional events that are provided, the library also includes a number of utility functions that can be used to further leverage the power of native events within your website or application. These utility functions can be used for unifying basic events, such as `tapstart` or `mousedown`. From ed469a4c55a5113bcd36fa0f4e6228c37052bb78 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Sat, 18 Jul 2015 11:33:19 +0100 Subject: [PATCH 008/149] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ccc7576..f9d1f90 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Version History: 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: -**2015-07-18 - Version 1.0.0** ++ **2015-07-18 - Version 1.0.0** The library officially entered 1.0.0 after minor bug fixes and final adjustments. Utility Functions: From 9205c8e3721e1d2202ff80fee4bc8a8f81aa1708 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Sat, 18 Jul 2015 11:33:37 +0100 Subject: [PATCH 009/149] Fixed formatting --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f9d1f90..0a37c19 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Version History: 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: -+ **2015-07-18 - Version 1.0.0** ++ **2015-07-18 - Version 1.0.0** The library officially entered 1.0.0 after minor bug fixes and final adjustments. Utility Functions: From 410c22ed95c19932993b5f042c535aa9f9db5b94 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Sat, 18 Jul 2015 11:34:51 +0100 Subject: [PATCH 010/149] Rename src/v1/jquery.mobile-events.js to src/1.0.0/jquery.mobile-events.js --- src/{v1 => 1.0.0}/jquery.mobile-events.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{v1 => 1.0.0}/jquery.mobile-events.js (100%) diff --git a/src/v1/jquery.mobile-events.js b/src/1.0.0/jquery.mobile-events.js similarity index 100% rename from src/v1/jquery.mobile-events.js rename to src/1.0.0/jquery.mobile-events.js From 8c0142b269335543baefa75888e63a9d15c8a103 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Sat, 18 Jul 2015 11:35:07 +0100 Subject: [PATCH 011/149] Rename src/v1/jquery.mobile-events.min.js to src/1.0.0/jquery.mobile-events.min.js --- src/{v1 => 1.0.0}/jquery.mobile-events.min.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{v1 => 1.0.0}/jquery.mobile-events.min.js (100%) diff --git a/src/v1/jquery.mobile-events.min.js b/src/1.0.0/jquery.mobile-events.min.js similarity index 100% rename from src/v1/jquery.mobile-events.min.js rename to src/1.0.0/jquery.mobile-events.min.js From 6a2eaaafbce44e24f89f011b173f60a3d3f96fd2 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 21 Aug 2015 11:28:22 +0100 Subject: [PATCH 012/149] Create bower.json Added a Bower package for easy install. --- src/1.0.1/bower.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/1.0.1/bower.json diff --git a/src/1.0.1/bower.json b/src/1.0.1/bower.json new file mode 100644 index 0000000..ec6e56e --- /dev/null +++ b/src/1.0.1/bower.json @@ -0,0 +1,11 @@ +{ + "name": "jquery-touch-events", + "version": "1.0.1", + "main": "jquery.mobile-events.js.js", + "ignore": [ + "bower.json", + ], + "dependencies": { + "jquery": ">=1.7.0" + } +} From 34f87218ba2c744743b864147dcf5b5a2c95fd5f Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 21 Aug 2015 11:29:09 +0100 Subject: [PATCH 013/149] Create jquery.mobile-events.js Fixed bug where IE 10 and 11 on Windows Phone did not correctly trigger the events (related to `MSPointer` events). --- src/1.0.1/jquery.mobile-events.js | 875 ++++++++++++++++++++++++++++++ 1 file changed, 875 insertions(+) create mode 100644 src/1.0.1/jquery.mobile-events.js diff --git a/src/1.0.1/jquery.mobile-events.js b/src/1.0.1/jquery.mobile-events.js new file mode 100644 index 0000000..a3113e2 --- /dev/null +++ b/src/1.0.1/jquery.mobile-events.js @@ -0,0 +1,875 @@ +/*! + * jQuery Mobile Events + * by Ben Major (www.ben-major.co.uk) + * + * Copyright 2011, 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. + * + */ +(function ($) { + $.attrFn = $.attrFn || {}; + + // navigator.userAgent.toLowerCase() isn't reliable for Chrome installs + // on mobile devices. As such, we will create a boolean isChromeDesktop + // The reason that we need to do this is because Chrome annoyingly + // purports support for touch events even if the underlying hardware + // does not! + var agent = navigator.userAgent.toLowerCase(), + isChromeDesktop = (agent.indexOf('chrome') > -1 && ((agent.indexOf('windows') > -1) || (agent.indexOf('macintosh') > -1) || (agent.indexOf('linux') > -1)) && agent.indexOf('mobile') < 0 && agent.indexOf('android') < 0), + + settings = { + tap_pixel_range: 5, + swipe_h_threshold: 50, + swipe_v_threshold: 50, + taphold_threshold: 750, + doubletap_int: 500, + + touch_capable: ('ontouchstart' in window && !isChromeDesktop), + orientation_support: ('orientation' in window && 'onorientationchange' in window), + + startevent: (window.navigator.msPointerEnabled) ? 'MSPointerDown' : (('ontouchstart' in window && !isChromeDesktop) ? 'touchstart' : 'mousedown'), + endevent: (window.navigator.msPointerEnabled) ? 'MSPointerUp' : (('ontouchstart' in window && !isChromeDesktop) ? 'touchend' : 'mouseup'), + moveevent: (window.navigator.msPointerEnabled) ? 'MSPointerMove' : (('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'mousemove'), + tapevent: ('ontouchstart' in window && !isChromeDesktop) ? 'tap' : 'click', + scrollevent: ('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'scroll', + + hold_timer: null, + tap_timer: null + }; + + // 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; }; + + // Add Event shortcuts: + $.each(['tapstart', 'tapend', 'tapmove', 'tap', 'tap2', 'tap3', 'tap4', 'singletap', 'doubletap', 'taphold', 'swipe', 'swipeup', 'swiperight', 'swipedown', 'swipeleft', 'swipeend', 'scrollstart', 'scrollend', 'orientationchange'], 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 (e) { + $this.data('callee', arguments.callee); + if (e.which && e.which !== 1) { + return false; + } + + var origEvent = e.originalEvent, + touchData = { + 'position': { + 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + '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 + }, + '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(e) { + $this.data('callee', arguments.callee); + + var origEvent = e.originalEvent, + touchData = { + 'position': { + 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + '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 + }, + '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 (e) { + // Touch event data: + $this.data('callee', arguments.callee); + + var origEvent = e.originalEvent; + var touchData = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].pageX - origEvent.changedTouches[0].target.offsetLeft : e.offsetX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].pageY - origEvent.changedTouches[0].target.offsetTop : e.offsetY + }, + '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, + timer, + start_pos = { + x: 0, + y: 0 + }, + end_x = 0, + end_y = 0; + + $this.on(settings.startevent, function (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].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 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; + + settings.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(), + endPosition = { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + endOffset = { + '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 + }; + duration = end_time - start_time; + + // Build the touch data: + var touchData = { + 'startTime': start_time, + 'endTime': end_time, + 'startPosition': startPosition, + 'startOffset': startOffset, + 'endPosition': endPosition, + 'endOffset': endOffset, + 'duration': duration, + 'target': e.target + } + $this.data('callee1', arguments.callee); + triggerCustomEvent(thisObject, 'taphold', e, touchData); + } + }, settings.taphold_threshold); + + return true; + } + }).on(settings.endevent, function () { + $this.data('callee2', arguments.callee); + $this.data('tapheld', false); + window.clearTimeout(settings.hold_timer); + }) + .on(settings.moveevent, function (e) { + $this.data('callee3', arguments.callee); + + 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, + origEvent, + cooloff, + cooling = false; + + $this.on(settings.startevent, function (e) { + if (e.which && e.which !== 1) { + return false; + } + $this.data('doubletapped', false); + origTarget = e.target; + $this.data('callee1', arguments.callee); + + origEvent = e.originalEvent; + firstTap = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + '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 + }, + 'time': Date.now(), + 'target': e.target + }; + + return true; + }).on(settings.endevent, function (e) { + + var now = Date.now(); + var lastTouch = $this.data('lastTouch') || now + 1; + var delta = now - lastTouch; + window.clearTimeout(action); + $this.data('callee2', arguments.callee); + + if (delta < settings.doubletap_int && (e.target == origTarget) && delta > 100) { + $this.data('doubletapped', true); + window.clearTimeout(settings.tap_timer); + + // Now get the current event: + var lastTap = { + 'position': { + 'x': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? e.originalEvent.changedTouches[0].pageX - e.originalEvent.changedTouches[0].target.offsetLeft : e.offsetX, + 'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].pageY - e.originalEvent.changedTouches[0].target.offsetTop : e.offsetY + }, + 'time': Date.now(), + 'target': e.target + } + + var touchData = { + 'firstTap': firstTap, + 'secondTap': lastTap, + 'interval': lastTap.time - firstTap.time + }; + + if (!cooling) { + triggerCustomEvent(thisObject, 'doubletap', e, touchData); + } + + cooling = true; + + cooloff = window.setTimeout(function (e) { + cooling = false; + }, settings.doubletap_int); + + } else { + $this.data('lastTouch', now); + action = window.setTimeout(function (e) { + 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 (e) { + if (e.which && e.which !== 1) { + return false; + } else { + startTime = Date.now(); + origTarget = e.target; + $this.data('callee1', arguments.callee); + + // 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 (e) { + $this.data('callee2', arguments.callee); + if (e.target == origTarget) { + // Get the end point: + 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 () { + if (!$this.data('doubletapped') && !$this.data('tapheld') && (start_pos.x == end_pos_x) && (start_pos.y == end_pos_y)) { + var origEvent = e.originalEvent; + var touchData = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].pageX - origEvent.changedTouches[0].target.offsetLeft : e.offsetX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].pageY - origEvent.changedTouches[0].target.offsetTop : e.offsetY + }, + '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 (e) { + $this.data('callee1', arguments.callee); + + 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 (e) { + $this.data('callee2', arguments.callee); + + // 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 origEvent = e.originalEvent; + var touchData = [ ]; + + for( var i = 0; i < touches.length; i++) + { + var touch = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[i].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[i].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[i].pageX - origEvent.changedTouches[i].target.offsetLeft : e.offsetX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[i].pageY - origEvent.changedTouches[i].target.offsetTop : e.offsetY + }, + 'time': Date.now(), + 'target': e.target + }; + + touchData.push( touch ); + } + + switch( touches.length ) + { + case 1: + eventName = 'tap'; + break; + + case 2: + eventName = 'tap2'; + break; + + case 3: + eventName = 'tap3'; + break; + + case 4: + eventName = 'tap4'; + break; + } + + triggerCustomEvent(thisObject, eventName, 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', arguments.callee); + 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 origEvent = e.originalEvent; + // Read event data into our startEvt: + startEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + '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 + }, + 'time': Date.now(), + 'target': e.target + }; + } + + // Store coordinates as finger is swiping + + function touchMove(e) { + $this = $(e.currentTarget); + $this.data('callee2', arguments.callee); + 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 (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 (originalCoord.x > finalCoord.x && (originalCoord.x - finalCoord.x > h_threshold)) { + swipedir = 'swipeleft'; + } + 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 origEvent = e.originalEvent; + endEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + '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 + }, + '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', arguments.callee); + 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 origEvent = e.originalEvent; + endEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].pageX - origEvent.changedTouches[0].target.offsetLeft : e.offsetX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].pageY - origEvent.changedTouches[0].target.offsetTop : e.offsetY + }, + 'time': Date.now(), + '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); + + 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 (event) { + $this.data('callee', arguments.callee); + + 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' + }, function (e, srcE, touchData) { + $.event.special[e] = { + setup: function () { + $(this).on(srcE, $.noop); + } + }; + }); + +})(jQuery); From 2dae00b38ffb9c7e634c8cd48f515981fbe17dd1 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 21 Aug 2015 11:29:54 +0100 Subject: [PATCH 014/149] Create jquery.mobile-events.min.js Fixed bug where IE 10 and 11 on Windows Phone did not correctly trigger the events (related to `MSPointer` events). --- src/1.0.1/jquery.mobile-events.min.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/1.0.1/jquery.mobile-events.min.js diff --git a/src/1.0.1/jquery.mobile-events.min.js b/src/1.0.1/jquery.mobile-events.min.js new file mode 100644 index 0000000..5e78598 --- /dev/null +++ b/src/1.0.1/jquery.mobile-events.min.js @@ -0,0 +1 @@ +!function(e){function t(){var e=c();e!==r&&(r=e,l.trigger("orientationchange"))}function a(t,a,n,o){var i=n.type;n.type=a,e.event.dispatch.call(t,n,o),n.type=i}e.attrFn=e.attrFn||{};var n=navigator.userAgent.toLowerCase(),o=n.indexOf("chrome")>-1&&(n.indexOf("windows")>-1||n.indexOf("macintosh")>-1||n.indexOf("linux")>-1)&&n.indexOf("mobile")<0&&n.indexOf("android")<0,i={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:"ontouchstart"in window&&!o,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:window.navigator.msPointerEnabled?"MSPointerDown":"ontouchstart"in window&&!o?"touchstart":"mousedown",endevent:window.navigator.msPointerEnabled?"MSPointerUp":"ontouchstart"in window&&!o?"touchend":"mouseup",moveevent:window.navigator.msPointerEnabled?"MSPointerMove":"ontouchstart"in window&&!o?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!o?"tap":"click",scrollevent:"ontouchstart"in window&&!o?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.isTouchCapable=function(){return i.touch_capable},e.getStartEvent=function(){return i.startevent},e.getEndEvent=function(){return i.endevent},e.getMoveEvent=function(){return i.moveevent},e.getTapEvent=function(){return i.tapevent},e.getScrollEvent=function(){return i.scrollevent},e.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],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,n=e(t);n.on(i.startevent,function(e){if(n.data("callee",arguments.callee),e.which&&1!==e.which)return!1;var o=e.originalEvent,s={position:{x:i.touch_capable?o.touches[0].screenX:e.screenX,y:i.touch_capable?o.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.touches[0].pageX-o.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.touches[0].pageY-o.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapstart",e,s),!0})},remove:function(){e(this).off(i.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,n=e(t);n.on(i.moveevent,function(e){n.data("callee",arguments.callee);var o=e.originalEvent,s={position:{x:i.touch_capable?o.touches[0].screenX:e.screenX,y:i.touch_capable?o.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.touches[0].pageX-o.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.touches[0].pageY-o.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapmove",e,s),!0})},remove:function(){e(this).off(i.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,n=e(t);n.on(i.endevent,function(e){n.data("callee",arguments.callee);var o=e.originalEvent,s={position:{x:i.touch_capable?o.changedTouches[0].screenX:e.screenX,y:i.touch_capable?o.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.changedTouches[0].pageX-o.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.changedTouches[0].pageY-o.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapend",e,s),!0})},remove:function(){e(this).off(i.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,n=this,o=e(n),s={x:0,y:0},c=0,r=0;o.on(i.startevent,function(e){if(e.which&&1!==e.which)return!1;o.data("tapheld",!1),t=e.target;var h=e.originalEvent,u=Date.now(),l={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},p={x:i.touch_capable?h.touches[0].pageX-h.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?h.touches[0].pageY-h.touches[0].target.offsetTop:e.offsetY};return s.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,s.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,c=s.x,r=s.y,i.hold_timer=window.setTimeout(function(){var g=s.x-c,d=s.y-r;if(e.target==t&&(s.x==c&&s.y==r||g>=-i.tap_pixel_range&&g<=i.tap_pixel_range&&d>=-i.tap_pixel_range&&d<=i.tap_pixel_range)){o.data("tapheld",!0);var f=Date.now(),v={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},w={x:i.touch_capable?h.touches[0].pageX-h.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?h.touches[0].pageY-h.touches[0].target.offsetTop:e.offsetY};duration=f-u;var _={startTime:u,endTime:f,startPosition:l,startOffset:p,endPosition:v,endOffset:w,duration:duration,target:e.target};o.data("callee1",arguments.callee),a(n,"taphold",e,_)}},i.taphold_threshold),!0}).on(i.endevent,function(){o.data("callee2",arguments.callee),o.data("tapheld",!1),window.clearTimeout(i.hold_timer)}).on(i.moveevent,function(e){o.data("callee3",arguments.callee),c=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,r=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2).off(i.moveevent,e(this).data.callee3)}},e.event.special.doubletap={setup:function(){var t,n,o,s,c,r=this,h=e(r),u=!1;h.on(i.startevent,function(e){return e.which&&1!==e.which?!1:(h.data("doubletapped",!1),t=e.target,h.data("callee1",arguments.callee),s=e.originalEvent,o={position:{x:i.touch_capable?s.touches[0].screenX:e.screenX,y:i.touch_capable?s.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?s.touches[0].pageX-s.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?s.touches[0].pageY-s.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target},!0)}).on(i.endevent,function(e){var s=Date.now(),l=h.data("lastTouch")||s+1,p=s-l;if(window.clearTimeout(n),h.data("callee2",arguments.callee),p100){h.data("doubletapped",!0),window.clearTimeout(i.tap_timer);var g={position:{x:i.touch_capable?e.originalEvent.changedTouches[0].screenX:e.screenX,y:i.touch_capable?e.originalEvent.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?e.originalEvent.changedTouches[0].pageX-e.originalEvent.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?e.originalEvent.changedTouches[0].pageY-e.originalEvent.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target},d={firstTap:o,secondTap:g,interval:g.time-o.time};u||a(r,"doubletap",e,d),u=!0,c=window.setTimeout(function(){u=!1},i.doubletap_int)}else h.data("lastTouch",s),n=window.setTimeout(function(){window.clearTimeout(n)},i.doubletap_int,[e]);h.data("lastTouch",s)})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,n=e(t),o=null,s=null,c={x:0,y:0};n.on(i.startevent,function(e){return e.which&&1!==e.which?!1:(s=Date.now(),o=e.target,n.data("callee1",arguments.callee),c.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,c.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,!0)}).on(i.endevent,function(e){n.data("callee2",arguments.callee),e.target==o&&(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,i.tap_timer=window.setTimeout(function(){if(!n.data("doubletapped")&&!n.data("tapheld")&&c.x==end_pos_x&&c.y==end_pos_y){var o=e.originalEvent,r={position:{x:i.touch_capable?o.changedTouches[0].screenX:e.screenX,y:i.touch_capable?o.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.changedTouches[0].pageX-o.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.changedTouches[0].pageY-o.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};r.time-s=-i.tap_pixel_range&&g<=i.tap_pixel_range&&d>=-i.tap_pixel_range&&d<=i.tap_pixel_range)){for(var f=e.originalEvent,v=[],w=0;wl.y&&u.y-l.y>g&&(a="swipeup"),u.xp&&(a="swiperight"),u.yg&&(a="swipedown"),u.x>l.x&&u.x-l.x>p&&(a="swipeleft"),void 0!=a&&r){u.x=0,u.y=0,l.x=0,l.y=0,r=!1;var d=t.originalEvent;endEvnt={position:{x:i.touch_capable?d.touches[0].screenX:t.screenX,y:i.touch_capable?d.touches[0].screenY:t.screenY},offset:{x:i.touch_capable?d.touches[0].pageX-d.touches[0].target.offsetLeft:t.offsetX,y:i.touch_capable?d.touches[0].pageY-d.touches[0].target.offsetTop:t.offsetY},time:Date.now(),target:t.target};var f=Math.abs(o.position.x-endEvnt.position.x),v=Math.abs(o.position.y-endEvnt.position.y),w={startEvnt:o,endEvnt:endEvnt,direction:a.replace("swipe",""),xAmount:f,yAmount:v,duration:endEvnt.time-o.time};h=!0,c.trigger("swipe",w).trigger(a,w)}}function n(t){c=e(t.currentTarget);var a="";if(c.data("callee3",arguments.callee),h){var n=c.data("xthreshold"),s=c.data("ythreshold"),u="undefined"!=typeof n&&n!==!1&&parseInt(n)?parseInt(n):i.swipe_h_threshold,l="undefined"!=typeof s&&s!==!1&&parseInt(s)?parseInt(s):i.swipe_v_threshold,p=t.originalEvent;endEvnt={position:{x:i.touch_capable?p.changedTouches[0].screenX:t.screenX,y:i.touch_capable?p.changedTouches[0].screenY:t.screenY},offset:{x:i.touch_capable?p.changedTouches[0].pageX-p.changedTouches[0].target.offsetLeft:t.offsetX,y:i.touch_capable?p.changedTouches[0].pageY-p.changedTouches[0].target.offsetTop:t.offsetY},time:Date.now(),target:t.target},o.position.y>endEvnt.position.y&&o.position.y-endEvnt.position.y>l&&(a="swipeup"),o.position.xu&&(a="swiperight"),o.position.yl&&(a="swipedown"),o.position.x>endEvnt.position.x&&o.position.x-endEvnt.position.x>u&&(a="swipeleft");var g=Math.abs(o.position.x-endEvnt.position.x),d=Math.abs(o.position.y-endEvnt.position.y),f={startEvnt:o,endEvnt:endEvnt,direction:a.replace("swipe",""),xAmount:g,yAmount:d,duration:endEvnt.time-o.time};c.trigger("swipeend",f)}r=!1,h=!1}var o,s=this,c=e(s),r=!1,h=!1,u={x:0,y:0},l={x:0,y:0};c.on(i.startevent,t),c.on(i.moveevent,a),c.on(i.endevent,n)},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.moveevent,e(this).data.callee2).off(i.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){function t(e,t){n=t,a(s,n?"scrollstart":"scrollend",e)}var n,o,s=this,c=e(s);c.on(i.scrollevent,function(e){c.data("callee",arguments.callee),n||t(e,!0),clearTimeout(o),o=setTimeout(function(){t(e,!1)},50)})},remove:function(){e(this).off(i.scrollevent,e(this).data.callee)}};var s,c,r,h,u,l=e(window),p={0:!0,180:!0};if(i.orientation_support){var g=window.innerWidth||l.width(),d=window.innerHeight||l.height(),f=50;h=g>d&&g-d>f,u=p[window.orientation],(h&&u||!h&&!u)&&(p={"-90":!0,90:!0})}e.event.special.orientationchange=s={setup:function(){return i.orientation_support?!1:(r=c(),l.on("throttledresize",t),!0)},teardown:function(){return i.orientation_support?!1:(l.off("throttledresize",t),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=c(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=c=function(){var e=!0,t=document.documentElement;return e=i.orientation_support?p[window.orientation]:t&&t.clientWidth/t.clientHeight<1.1,e?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",m)},teardown:function(){e(this).off("resize",m)}};var v,w,_,T=250,m=function(){w=Date.now(),_=w-x,_>=T?(x=w,e(this).trigger("throttledresize")):(v&&window.clearTimeout(v),v=window.setTimeout(t,T-_))},x=0;e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); From b08fb9e13f6f21f5dfa088af023ec5af43cb3a89 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 21 Aug 2015 11:32:54 +0100 Subject: [PATCH 015/149] Update jquery.mobile-events.js Fix for `touch_capable` --- src/1.0.1/jquery.mobile-events.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/1.0.1/jquery.mobile-events.js b/src/1.0.1/jquery.mobile-events.js index a3113e2..92041d0 100644 --- a/src/1.0.1/jquery.mobile-events.js +++ b/src/1.0.1/jquery.mobile-events.js @@ -42,7 +42,7 @@ taphold_threshold: 750, doubletap_int: 500, - touch_capable: ('ontouchstart' in window && !isChromeDesktop), + touch_capable: (window.navigator.msPointerEnabled) ? false : ('ontouchstart' in window && !isChromeDesktop), orientation_support: ('orientation' in window && 'onorientationchange' in window), startevent: (window.navigator.msPointerEnabled) ? 'MSPointerDown' : (('ontouchstart' in window && !isChromeDesktop) ? 'touchstart' : 'mousedown'), From 62dd060856a8e22c76ca4ae9d8f78cc67b619611 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 21 Aug 2015 11:33:24 +0100 Subject: [PATCH 016/149] Update jquery.mobile-events.min.js Fixed `touch_capable` for MSPointerEnabled. --- src/1.0.1/jquery.mobile-events.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/1.0.1/jquery.mobile-events.min.js b/src/1.0.1/jquery.mobile-events.min.js index 5e78598..24e60d1 100644 --- a/src/1.0.1/jquery.mobile-events.min.js +++ b/src/1.0.1/jquery.mobile-events.min.js @@ -1 +1 @@ -!function(e){function t(){var e=c();e!==r&&(r=e,l.trigger("orientationchange"))}function a(t,a,n,o){var i=n.type;n.type=a,e.event.dispatch.call(t,n,o),n.type=i}e.attrFn=e.attrFn||{};var n=navigator.userAgent.toLowerCase(),o=n.indexOf("chrome")>-1&&(n.indexOf("windows")>-1||n.indexOf("macintosh")>-1||n.indexOf("linux")>-1)&&n.indexOf("mobile")<0&&n.indexOf("android")<0,i={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:"ontouchstart"in window&&!o,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:window.navigator.msPointerEnabled?"MSPointerDown":"ontouchstart"in window&&!o?"touchstart":"mousedown",endevent:window.navigator.msPointerEnabled?"MSPointerUp":"ontouchstart"in window&&!o?"touchend":"mouseup",moveevent:window.navigator.msPointerEnabled?"MSPointerMove":"ontouchstart"in window&&!o?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!o?"tap":"click",scrollevent:"ontouchstart"in window&&!o?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.isTouchCapable=function(){return i.touch_capable},e.getStartEvent=function(){return i.startevent},e.getEndEvent=function(){return i.endevent},e.getMoveEvent=function(){return i.moveevent},e.getTapEvent=function(){return i.tapevent},e.getScrollEvent=function(){return i.scrollevent},e.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],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,n=e(t);n.on(i.startevent,function(e){if(n.data("callee",arguments.callee),e.which&&1!==e.which)return!1;var o=e.originalEvent,s={position:{x:i.touch_capable?o.touches[0].screenX:e.screenX,y:i.touch_capable?o.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.touches[0].pageX-o.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.touches[0].pageY-o.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapstart",e,s),!0})},remove:function(){e(this).off(i.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,n=e(t);n.on(i.moveevent,function(e){n.data("callee",arguments.callee);var o=e.originalEvent,s={position:{x:i.touch_capable?o.touches[0].screenX:e.screenX,y:i.touch_capable?o.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.touches[0].pageX-o.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.touches[0].pageY-o.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapmove",e,s),!0})},remove:function(){e(this).off(i.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,n=e(t);n.on(i.endevent,function(e){n.data("callee",arguments.callee);var o=e.originalEvent,s={position:{x:i.touch_capable?o.changedTouches[0].screenX:e.screenX,y:i.touch_capable?o.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.changedTouches[0].pageX-o.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.changedTouches[0].pageY-o.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapend",e,s),!0})},remove:function(){e(this).off(i.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,n=this,o=e(n),s={x:0,y:0},c=0,r=0;o.on(i.startevent,function(e){if(e.which&&1!==e.which)return!1;o.data("tapheld",!1),t=e.target;var h=e.originalEvent,u=Date.now(),l={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},p={x:i.touch_capable?h.touches[0].pageX-h.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?h.touches[0].pageY-h.touches[0].target.offsetTop:e.offsetY};return s.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,s.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,c=s.x,r=s.y,i.hold_timer=window.setTimeout(function(){var g=s.x-c,d=s.y-r;if(e.target==t&&(s.x==c&&s.y==r||g>=-i.tap_pixel_range&&g<=i.tap_pixel_range&&d>=-i.tap_pixel_range&&d<=i.tap_pixel_range)){o.data("tapheld",!0);var f=Date.now(),v={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},w={x:i.touch_capable?h.touches[0].pageX-h.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?h.touches[0].pageY-h.touches[0].target.offsetTop:e.offsetY};duration=f-u;var _={startTime:u,endTime:f,startPosition:l,startOffset:p,endPosition:v,endOffset:w,duration:duration,target:e.target};o.data("callee1",arguments.callee),a(n,"taphold",e,_)}},i.taphold_threshold),!0}).on(i.endevent,function(){o.data("callee2",arguments.callee),o.data("tapheld",!1),window.clearTimeout(i.hold_timer)}).on(i.moveevent,function(e){o.data("callee3",arguments.callee),c=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,r=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2).off(i.moveevent,e(this).data.callee3)}},e.event.special.doubletap={setup:function(){var t,n,o,s,c,r=this,h=e(r),u=!1;h.on(i.startevent,function(e){return e.which&&1!==e.which?!1:(h.data("doubletapped",!1),t=e.target,h.data("callee1",arguments.callee),s=e.originalEvent,o={position:{x:i.touch_capable?s.touches[0].screenX:e.screenX,y:i.touch_capable?s.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?s.touches[0].pageX-s.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?s.touches[0].pageY-s.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target},!0)}).on(i.endevent,function(e){var s=Date.now(),l=h.data("lastTouch")||s+1,p=s-l;if(window.clearTimeout(n),h.data("callee2",arguments.callee),p100){h.data("doubletapped",!0),window.clearTimeout(i.tap_timer);var g={position:{x:i.touch_capable?e.originalEvent.changedTouches[0].screenX:e.screenX,y:i.touch_capable?e.originalEvent.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?e.originalEvent.changedTouches[0].pageX-e.originalEvent.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?e.originalEvent.changedTouches[0].pageY-e.originalEvent.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target},d={firstTap:o,secondTap:g,interval:g.time-o.time};u||a(r,"doubletap",e,d),u=!0,c=window.setTimeout(function(){u=!1},i.doubletap_int)}else h.data("lastTouch",s),n=window.setTimeout(function(){window.clearTimeout(n)},i.doubletap_int,[e]);h.data("lastTouch",s)})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,n=e(t),o=null,s=null,c={x:0,y:0};n.on(i.startevent,function(e){return e.which&&1!==e.which?!1:(s=Date.now(),o=e.target,n.data("callee1",arguments.callee),c.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,c.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,!0)}).on(i.endevent,function(e){n.data("callee2",arguments.callee),e.target==o&&(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,i.tap_timer=window.setTimeout(function(){if(!n.data("doubletapped")&&!n.data("tapheld")&&c.x==end_pos_x&&c.y==end_pos_y){var o=e.originalEvent,r={position:{x:i.touch_capable?o.changedTouches[0].screenX:e.screenX,y:i.touch_capable?o.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.changedTouches[0].pageX-o.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.changedTouches[0].pageY-o.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};r.time-s=-i.tap_pixel_range&&g<=i.tap_pixel_range&&d>=-i.tap_pixel_range&&d<=i.tap_pixel_range)){for(var f=e.originalEvent,v=[],w=0;wl.y&&u.y-l.y>g&&(a="swipeup"),u.xp&&(a="swiperight"),u.yg&&(a="swipedown"),u.x>l.x&&u.x-l.x>p&&(a="swipeleft"),void 0!=a&&r){u.x=0,u.y=0,l.x=0,l.y=0,r=!1;var d=t.originalEvent;endEvnt={position:{x:i.touch_capable?d.touches[0].screenX:t.screenX,y:i.touch_capable?d.touches[0].screenY:t.screenY},offset:{x:i.touch_capable?d.touches[0].pageX-d.touches[0].target.offsetLeft:t.offsetX,y:i.touch_capable?d.touches[0].pageY-d.touches[0].target.offsetTop:t.offsetY},time:Date.now(),target:t.target};var f=Math.abs(o.position.x-endEvnt.position.x),v=Math.abs(o.position.y-endEvnt.position.y),w={startEvnt:o,endEvnt:endEvnt,direction:a.replace("swipe",""),xAmount:f,yAmount:v,duration:endEvnt.time-o.time};h=!0,c.trigger("swipe",w).trigger(a,w)}}function n(t){c=e(t.currentTarget);var a="";if(c.data("callee3",arguments.callee),h){var n=c.data("xthreshold"),s=c.data("ythreshold"),u="undefined"!=typeof n&&n!==!1&&parseInt(n)?parseInt(n):i.swipe_h_threshold,l="undefined"!=typeof s&&s!==!1&&parseInt(s)?parseInt(s):i.swipe_v_threshold,p=t.originalEvent;endEvnt={position:{x:i.touch_capable?p.changedTouches[0].screenX:t.screenX,y:i.touch_capable?p.changedTouches[0].screenY:t.screenY},offset:{x:i.touch_capable?p.changedTouches[0].pageX-p.changedTouches[0].target.offsetLeft:t.offsetX,y:i.touch_capable?p.changedTouches[0].pageY-p.changedTouches[0].target.offsetTop:t.offsetY},time:Date.now(),target:t.target},o.position.y>endEvnt.position.y&&o.position.y-endEvnt.position.y>l&&(a="swipeup"),o.position.xu&&(a="swiperight"),o.position.yl&&(a="swipedown"),o.position.x>endEvnt.position.x&&o.position.x-endEvnt.position.x>u&&(a="swipeleft");var g=Math.abs(o.position.x-endEvnt.position.x),d=Math.abs(o.position.y-endEvnt.position.y),f={startEvnt:o,endEvnt:endEvnt,direction:a.replace("swipe",""),xAmount:g,yAmount:d,duration:endEvnt.time-o.time};c.trigger("swipeend",f)}r=!1,h=!1}var o,s=this,c=e(s),r=!1,h=!1,u={x:0,y:0},l={x:0,y:0};c.on(i.startevent,t),c.on(i.moveevent,a),c.on(i.endevent,n)},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.moveevent,e(this).data.callee2).off(i.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){function t(e,t){n=t,a(s,n?"scrollstart":"scrollend",e)}var n,o,s=this,c=e(s);c.on(i.scrollevent,function(e){c.data("callee",arguments.callee),n||t(e,!0),clearTimeout(o),o=setTimeout(function(){t(e,!1)},50)})},remove:function(){e(this).off(i.scrollevent,e(this).data.callee)}};var s,c,r,h,u,l=e(window),p={0:!0,180:!0};if(i.orientation_support){var g=window.innerWidth||l.width(),d=window.innerHeight||l.height(),f=50;h=g>d&&g-d>f,u=p[window.orientation],(h&&u||!h&&!u)&&(p={"-90":!0,90:!0})}e.event.special.orientationchange=s={setup:function(){return i.orientation_support?!1:(r=c(),l.on("throttledresize",t),!0)},teardown:function(){return i.orientation_support?!1:(l.off("throttledresize",t),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=c(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=c=function(){var e=!0,t=document.documentElement;return e=i.orientation_support?p[window.orientation]:t&&t.clientWidth/t.clientHeight<1.1,e?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",m)},teardown:function(){e(this).off("resize",m)}};var v,w,_,T=250,m=function(){w=Date.now(),_=w-x,_>=T?(x=w,e(this).trigger("throttledresize")):(v&&window.clearTimeout(v),v=window.setTimeout(t,T-_))},x=0;e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); +!function(e){function t(){var e=c();e!==r&&(r=e,l.trigger("orientationchange"))}function a(t,a,n,o){var i=n.type;n.type=a,e.event.dispatch.call(t,n,o),n.type=i}e.attrFn=e.attrFn||{};var n=navigator.userAgent.toLowerCase(),o=n.indexOf("chrome")>-1&&(n.indexOf("windows")>-1||n.indexOf("macintosh")>-1||n.indexOf("linux")>-1)&&n.indexOf("mobile")<0&&n.indexOf("android")<0,i={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:window.navigator.msPointerEnabled?!1:"ontouchstart"in window&&!o,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:window.navigator.msPointerEnabled?"MSPointerDown":"ontouchstart"in window&&!o?"touchstart":"mousedown",endevent:window.navigator.msPointerEnabled?"MSPointerUp":"ontouchstart"in window&&!o?"touchend":"mouseup",moveevent:window.navigator.msPointerEnabled?"MSPointerMove":"ontouchstart"in window&&!o?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!o?"tap":"click",scrollevent:"ontouchstart"in window&&!o?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.isTouchCapable=function(){return i.touch_capable},e.getStartEvent=function(){return i.startevent},e.getEndEvent=function(){return i.endevent},e.getMoveEvent=function(){return i.moveevent},e.getTapEvent=function(){return i.tapevent},e.getScrollEvent=function(){return i.scrollevent},e.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],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,n=e(t);n.on(i.startevent,function(e){if(n.data("callee",arguments.callee),e.which&&1!==e.which)return!1;var o=e.originalEvent,s={position:{x:i.touch_capable?o.touches[0].screenX:e.screenX,y:i.touch_capable?o.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.touches[0].pageX-o.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.touches[0].pageY-o.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapstart",e,s),!0})},remove:function(){e(this).off(i.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,n=e(t);n.on(i.moveevent,function(e){n.data("callee",arguments.callee);var o=e.originalEvent,s={position:{x:i.touch_capable?o.touches[0].screenX:e.screenX,y:i.touch_capable?o.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.touches[0].pageX-o.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.touches[0].pageY-o.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapmove",e,s),!0})},remove:function(){e(this).off(i.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,n=e(t);n.on(i.endevent,function(e){n.data("callee",arguments.callee);var o=e.originalEvent,s={position:{x:i.touch_capable?o.changedTouches[0].screenX:e.screenX,y:i.touch_capable?o.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.changedTouches[0].pageX-o.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.changedTouches[0].pageY-o.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapend",e,s),!0})},remove:function(){e(this).off(i.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,n=this,o=e(n),s={x:0,y:0},c=0,r=0;o.on(i.startevent,function(e){if(e.which&&1!==e.which)return!1;o.data("tapheld",!1),t=e.target;var h=e.originalEvent,u=Date.now(),l={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},p={x:i.touch_capable?h.touches[0].pageX-h.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?h.touches[0].pageY-h.touches[0].target.offsetTop:e.offsetY};return s.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,s.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,c=s.x,r=s.y,i.hold_timer=window.setTimeout(function(){var g=s.x-c,d=s.y-r;if(e.target==t&&(s.x==c&&s.y==r||g>=-i.tap_pixel_range&&g<=i.tap_pixel_range&&d>=-i.tap_pixel_range&&d<=i.tap_pixel_range)){o.data("tapheld",!0);var f=Date.now(),v={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},w={x:i.touch_capable?h.touches[0].pageX-h.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?h.touches[0].pageY-h.touches[0].target.offsetTop:e.offsetY};duration=f-u;var _={startTime:u,endTime:f,startPosition:l,startOffset:p,endPosition:v,endOffset:w,duration:duration,target:e.target};o.data("callee1",arguments.callee),a(n,"taphold",e,_)}},i.taphold_threshold),!0}).on(i.endevent,function(){o.data("callee2",arguments.callee),o.data("tapheld",!1),window.clearTimeout(i.hold_timer)}).on(i.moveevent,function(e){o.data("callee3",arguments.callee),c=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,r=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2).off(i.moveevent,e(this).data.callee3)}},e.event.special.doubletap={setup:function(){var t,n,o,s,c,r=this,h=e(r),u=!1;h.on(i.startevent,function(e){return e.which&&1!==e.which?!1:(h.data("doubletapped",!1),t=e.target,h.data("callee1",arguments.callee),s=e.originalEvent,o={position:{x:i.touch_capable?s.touches[0].screenX:e.screenX,y:i.touch_capable?s.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?s.touches[0].pageX-s.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?s.touches[0].pageY-s.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target},!0)}).on(i.endevent,function(e){var s=Date.now(),l=h.data("lastTouch")||s+1,p=s-l;if(window.clearTimeout(n),h.data("callee2",arguments.callee),p100){h.data("doubletapped",!0),window.clearTimeout(i.tap_timer);var g={position:{x:i.touch_capable?e.originalEvent.changedTouches[0].screenX:e.screenX,y:i.touch_capable?e.originalEvent.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?e.originalEvent.changedTouches[0].pageX-e.originalEvent.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?e.originalEvent.changedTouches[0].pageY-e.originalEvent.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target},d={firstTap:o,secondTap:g,interval:g.time-o.time};u||a(r,"doubletap",e,d),u=!0,c=window.setTimeout(function(){u=!1},i.doubletap_int)}else h.data("lastTouch",s),n=window.setTimeout(function(){window.clearTimeout(n)},i.doubletap_int,[e]);h.data("lastTouch",s)})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,n=e(t),o=null,s=null,c={x:0,y:0};n.on(i.startevent,function(e){return e.which&&1!==e.which?!1:(s=Date.now(),o=e.target,n.data("callee1",arguments.callee),c.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,c.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,!0)}).on(i.endevent,function(e){n.data("callee2",arguments.callee),e.target==o&&(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,i.tap_timer=window.setTimeout(function(){if(!n.data("doubletapped")&&!n.data("tapheld")&&c.x==end_pos_x&&c.y==end_pos_y){var o=e.originalEvent,r={position:{x:i.touch_capable?o.changedTouches[0].screenX:e.screenX,y:i.touch_capable?o.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?o.changedTouches[0].pageX-o.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?o.changedTouches[0].pageY-o.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};r.time-s=-i.tap_pixel_range&&g<=i.tap_pixel_range&&d>=-i.tap_pixel_range&&d<=i.tap_pixel_range)){for(var f=e.originalEvent,v=[],w=0;wl.y&&u.y-l.y>g&&(a="swipeup"),u.xp&&(a="swiperight"),u.yg&&(a="swipedown"),u.x>l.x&&u.x-l.x>p&&(a="swipeleft"),void 0!=a&&r){u.x=0,u.y=0,l.x=0,l.y=0,r=!1;var d=t.originalEvent;endEvnt={position:{x:i.touch_capable?d.touches[0].screenX:t.screenX,y:i.touch_capable?d.touches[0].screenY:t.screenY},offset:{x:i.touch_capable?d.touches[0].pageX-d.touches[0].target.offsetLeft:t.offsetX,y:i.touch_capable?d.touches[0].pageY-d.touches[0].target.offsetTop:t.offsetY},time:Date.now(),target:t.target};var f=Math.abs(o.position.x-endEvnt.position.x),v=Math.abs(o.position.y-endEvnt.position.y),w={startEvnt:o,endEvnt:endEvnt,direction:a.replace("swipe",""),xAmount:f,yAmount:v,duration:endEvnt.time-o.time};h=!0,c.trigger("swipe",w).trigger(a,w)}}function n(t){c=e(t.currentTarget);var a="";if(c.data("callee3",arguments.callee),h){var n=c.data("xthreshold"),s=c.data("ythreshold"),u="undefined"!=typeof n&&n!==!1&&parseInt(n)?parseInt(n):i.swipe_h_threshold,l="undefined"!=typeof s&&s!==!1&&parseInt(s)?parseInt(s):i.swipe_v_threshold,p=t.originalEvent;endEvnt={position:{x:i.touch_capable?p.changedTouches[0].screenX:t.screenX,y:i.touch_capable?p.changedTouches[0].screenY:t.screenY},offset:{x:i.touch_capable?p.changedTouches[0].pageX-p.changedTouches[0].target.offsetLeft:t.offsetX,y:i.touch_capable?p.changedTouches[0].pageY-p.changedTouches[0].target.offsetTop:t.offsetY},time:Date.now(),target:t.target},o.position.y>endEvnt.position.y&&o.position.y-endEvnt.position.y>l&&(a="swipeup"),o.position.xu&&(a="swiperight"),o.position.yl&&(a="swipedown"),o.position.x>endEvnt.position.x&&o.position.x-endEvnt.position.x>u&&(a="swipeleft");var g=Math.abs(o.position.x-endEvnt.position.x),d=Math.abs(o.position.y-endEvnt.position.y),f={startEvnt:o,endEvnt:endEvnt,direction:a.replace("swipe",""),xAmount:g,yAmount:d,duration:endEvnt.time-o.time};c.trigger("swipeend",f)}r=!1,h=!1}var o,s=this,c=e(s),r=!1,h=!1,u={x:0,y:0},l={x:0,y:0};c.on(i.startevent,t),c.on(i.moveevent,a),c.on(i.endevent,n)},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.moveevent,e(this).data.callee2).off(i.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){function t(e,t){n=t,a(s,n?"scrollstart":"scrollend",e)}var n,o,s=this,c=e(s);c.on(i.scrollevent,function(e){c.data("callee",arguments.callee),n||t(e,!0),clearTimeout(o),o=setTimeout(function(){t(e,!1)},50)})},remove:function(){e(this).off(i.scrollevent,e(this).data.callee)}};var s,c,r,h,u,l=e(window),p={0:!0,180:!0};if(i.orientation_support){var g=window.innerWidth||l.width(),d=window.innerHeight||l.height(),f=50;h=g>d&&g-d>f,u=p[window.orientation],(h&&u||!h&&!u)&&(p={"-90":!0,90:!0})}e.event.special.orientationchange=s={setup:function(){return i.orientation_support?!1:(r=c(),l.on("throttledresize",t),!0)},teardown:function(){return i.orientation_support?!1:(l.off("throttledresize",t),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=c(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=c=function(){var e=!0,t=document.documentElement;return e=i.orientation_support?p[window.orientation]:t&&t.clientWidth/t.clientHeight<1.1,e?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",m)},teardown:function(){e(this).off("resize",m)}};var v,w,_,T=250,m=function(){w=Date.now(),_=w-x,_>=T?(x=w,e(this).trigger("throttledresize")):(v&&window.clearTimeout(v),v=window.setTimeout(t,T-_))},x=0;e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); From 6cb63293f9438ee973565c84531a466ece751c2c Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 21 Aug 2015 11:36:16 +0100 Subject: [PATCH 017/149] Update README.md Added documentation for 1.0.1. --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0a37c19..169deed 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,11 @@ Version History: 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: + **2015-07-18 - Version 1.0.0** -The library officially entered 1.0.0 after minor bug fixes and final adjustments. + + The library officially entered 1.0.0 after minor bug fixes and final adjustments. + ++ **2015-08-21 - Version 1.0.1** + + Added Bower package for easy install + + Fixed a bug where Internet Explorer under Windows Mobile did not trigger certain events. Utility Functions: ----------------- From fd10e45dc62fe4c259359a23d06dbcd29b2522c5 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 21 Aug 2015 11:39:44 +0100 Subject: [PATCH 018/149] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 169deed..4e48727 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -jQuery Mobile Events +jQuery Touch Events ==================== This is a series of plugins that create additional events that can be used in combination with jQuery when developing for mobile devices. The events are also compatible with desktop browsers to ensure ultimate compatibility for your projects. In time, we will update the Repository to include some very basic demonstrations to get you started with using the events, but for now, we've put together a list of the events that are provided, and what they do. From 8407cc842c53fb36607cc001a5e6d0e524ad080f Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 21 Aug 2015 11:49:39 +0100 Subject: [PATCH 019/149] Update and rename src/1.0.1/bower.json to bower.json --- src/1.0.1/bower.json => bower.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/1.0.1/bower.json => bower.json (75%) diff --git a/src/1.0.1/bower.json b/bower.json similarity index 75% rename from src/1.0.1/bower.json rename to bower.json index ec6e56e..2291990 100644 --- a/src/1.0.1/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "jquery-touch-events", "version": "1.0.1", - "main": "jquery.mobile-events.js.js", + "main": "src/1.0.1/jquery.mobile-events.js.js", "ignore": [ "bower.json", ], From 4f618fa7006ac944c0cad4dfca7e020f91cf0310 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 21 Aug 2015 11:50:31 +0100 Subject: [PATCH 020/149] Update bower.json --- bower.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bower.json b/bower.json index 2291990..bd54fa2 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "jquery-touch-events", "version": "1.0.1", - "main": "src/1.0.1/jquery.mobile-events.js.js", + "main": "src/1.0.1/jquery.mobile-events.js", "ignore": [ "bower.json", ], From 892b7740bf188c4897deaa4f16c47921c987cbe1 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 21 Aug 2015 11:50:45 +0100 Subject: [PATCH 021/149] Update bower.json --- bower.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bower.json b/bower.json index bd54fa2..1b5dcdc 100644 --- a/bower.json +++ b/bower.json @@ -3,7 +3,7 @@ "version": "1.0.1", "main": "src/1.0.1/jquery.mobile-events.js", "ignore": [ - "bower.json", + "bower.json" ], "dependencies": { "jquery": ">=1.7.0" From 00e82663fcdf7087ef5ab57d639ea122c2e36fd8 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Sun, 23 Aug 2015 15:34:56 +0100 Subject: [PATCH 022/149] Update README.md Updated Readme to include: - Restructure for sections - Bower install documentation - Manual installation method documentation - Reformatted code --- README.md | 203 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 134 insertions(+), 69 deletions(-) diff --git a/README.md b/README.md index 4e48727..f07e017 100644 --- a/README.md +++ b/README.md @@ -1,43 +1,112 @@ -jQuery Touch Events -==================== +# jQuery Touch Events + This is a series of plugins that create additional events that can be used in combination with jQuery when developing for mobile devices. The events are also compatible with desktop browsers to ensure ultimate compatibility for your projects. In time, we will update the Repository to include some very basic demonstrations to get you started with using the events, but for now, we've put together a list of the events that are provided, and what they do. As explained, the events are each triggered by native touch events, or alternatively by click events. The plugin automatically detects whether the user's device is touch compatible, and will use the correct native events whenever required. It is hoped that these events will help to aid single-environment development with jQuery for mobile web app development. -Version History: ---------------- +## Table of Contents: -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: -+ **2015-07-18 - Version 1.0.0** - + The library officially entered 1.0.0 after minor bug fixes and final adjustments. +1. [Version History](#1-version-history) +2. [Installation](#2-installation) +3. [Usage](#3-usage) +4. [Events](#4-the-events) +5. [Callback Data](#5-callback-data) +6. [Defining Thresholds](#6-defining-thresholds) +7. [Utility Functions](#7-utility-functions) +8. [Demo](#8-demo) +9. [Requirements](#9-requirements) +10. [License](#10-license) + +## 1. Version History: -+ **2015-08-21 - Version 1.0.1** +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 1.0.1** (2015-08-21) + Added Bower package for easy install + Fixed a bug where Internet Explorer under Windows Mobile did not trigger certain events. -Utility Functions: ------------------ -In addition to the numerous additional events that are provided, the library also includes a number of utility functions that can be used to further leverage the power of native events within your website or application. These utility functions can be used for unifying basic events, such as `tapstart` or `mousedown`. ++ **Version 1.0.0** (2015-07-18) + + The library officially entered 1.0.0 after minor bug fixes and final adjustments. -The following utility functions are provided (each function is registered to the jQuery namespace, and should be called with `$.funcName()` (or `jQuery.funcName()` for compatibility): +## 2. Installation: -+ `isTouchCapable()`: -Returns `true` or `false` depending upon whether touch events are supported. -+ `getStartEvent()`: -Returns `touchstart` for touch-enabled devices, or `mousedown` for standard environments. -+ `getEndEvent()`: -Returns `touchend` for touch-enabled devices, or `mouseup` for standard environments. -+ `getMoveEvent()`: -Returns `touchmove` for touch-enabled devices, or `mousemove` for standard environments. -+ `getTapEvent()`: -Returns `tap` for touch-enabled devices, or `click` for standard environments. -+ `getScrollEvent()`: -Returns `touchmove` for touch-enabled devices, or `scroll` for standard environments. **Caution should be exercised when using this function, since some mobile browsers will correctly bind to `scroll` as well as `touchmove`.** -Events Provided: ---------------- +jQuery Touch Events, as the name suggests, require only the jQuery library (version 1.7+) to run. You should download the latest release from the `src` folder, and include the Javascript file within your project, **after** jQuery has been included. It is recommended to also wrap your code inside the `DOMReady` callback function of jQuery (`$(function() { })`, for example). +**Manual installation:** + +Once you have downloaded the JS files from the master branch, you should include them using the following code: + +``` + +``` + +Alternatively, you can also install jQuery-touch-events using Bower as follows: + +``` +$ bower install jquery-touch-events +``` + +### 3. Usage: +All of the events outlined above have been written using jQuery's ``event.special`` object, and so can be used in conjunction with jQuery's event handling functions, as well as shortcut wrappers. As a result, all of the events that are supported by this library may be handled using any of jQuery's own event-specific methods, such as `bind()`, `on()`, `live()` (for legacy) and `one()`. + +The following code snippets showcase some basic usage with jQuery: + +**Binding a ``tap`` event to an element:** +``` +$('#myElement').bind('tap', function(e) { + console.log('User tapped #myElement'); +}); +``` + +**Using with ``.on()`` and ``.live()``:** +``` +$('#myElement').live('tap', function(e) { + console.log('User tapped #myElement'); +}); +``` +``` +$('#myElement').on('tap', function(e) { + console.log('User tapped #myElement'); +}); +``` + +**Triggering the event:** +``` +$('#myElement').trigger('tap'); +``` + +**Removing the event with ``.off()``, ``.die()`` and ``.unbind()``:** +``` +$('#myElement').off('tap', hander); +``` +``` +$('#myElement').die('tap', hander); +``` +``` +$('#myElement').unbind('tap', hander); +``` + +**Using method wrapper:** +``` +$('#myElement').tap(function(e) { + console.log('User tapped #myElement'); +}); +``` + +**Method chaining:** +Chaining has also been preserved, so you can easily use these events in conjuction with other jQuery functions, or attach multiple events in a single, chained LOC: +``` +$('#myElement').singletap(function() { + console.log('singletap'); +}).doubletap(function() { + console.log('doubletap'); +}); +``` + + +## 4. The Events: + **`tapstart`** Fired as soon as the user begins touching an element (or clicking, for desktop environments). @@ -72,17 +141,19 @@ Triggered as soon as scrolling is stopped on the target element. + **`orientationchange`** This event is triggered when the orientation of the device is changed. Please note that it uses throttling for non-mobile devices, or devices which do not support the native ``orientationchange`` event. In the latter instance, a detection of the viewport size change occurs. -Callback Data: --------------- + +## 5. Callback Data: Each event now features a second argument that can be passed to the specified callback function. This argument includes some basic data relating specifically to the event, and can be accessed as a standard JavaScript object. To hook into this parameter, you should use the following code: -`$(element).swipeend(function(e, touch) { });` +``` +$(element).swipeend(function(e, touch) { }); +``` Given the example above, `touch` will now contain some basic data that can be accessed through `touch.`. The first argument will represent the last *native* event that occurred (the names used for these two arguments is irrelevant). Each event provides different callback data. The following shows the numerous data that are passed back to the callback function inside the second parameter: -##`tapstart`, `tapend`, `tapmove`, `tap`, `singletap`: +### `tapstart`, `tapend`, `tapmove`, `tap`, `singletap`: `offset` - object containing the X and Y positions of the event relative to the element to which is was bound. Accessed through `offset.x` and `offset.y` respectively. @@ -92,7 +163,7 @@ Each event provides different callback data. The following shows the numerous da `time` - JavaScript timestamp the event occurred (milliseconds since the Unix Epoch) -##`taphold`: +### `taphold`: `duration`: the time in milliseconds that the user tapped for. @@ -110,7 +181,7 @@ Each event provides different callback data. The following shows the numerous da `target` - the jQuery object from which the event was triggered. -##`doubletap`: +### `doubletap`: `firstTap` - Object containing the same data as a `tap` event, but for the first tap to occur. @@ -118,7 +189,7 @@ Each event provides different callback data. The following shows the numerous da `interval` - the time in milliseconds between the two tap. -##`swipe`, `swipeup`, `swiperight`, `swipedown`, `swipeleft`, `swipeend`: +### `swipe`, `swipeup`, `swiperight`, `swipedown`, `swipeleft`, `swipeend`: `direction` - string representing the swipe direction (either `up`, `right`, `down` or `left`). @@ -132,60 +203,54 @@ Each event provides different callback data. The following shows the numerous da `endEvent` - Object containing the same data as a `tap` event, but captured when swiping is complete. -Demo: ------ -I have put together a simple demo application that shows the numerous events in action. The console on the left hand side is used to show information about the events that have been called. You can examine the code easily by viewing the page's source to lear more about how this works. Please click on the below to check out the demo: +## 6. Defining Thresholds: -http://ben-major.co.uk/jquery-mobile-events/ +You can also define custom thresholds to be used for ``swipe`` events (``swipeup``, ``swiperight``, ``swipedown`` and ``swipeleft``) to prevent interference with scrolling and other events. To do so, simply assign a `data-xthreshold` or `date-ythreshold` to the target element as follows: -Please be aware that this demonstration uses Google's hosted jQuery file, and also pulls the latest version of the events library from GitHub. It is a great place to check the status of the library. Since this demo uses the vanilla code, it is a good idea to check the library functionality here for your own reference. If you're running into problems with the library, please check this demonstration using your device in the first instance. You can scan in the QR below to go directly to the web page: +``
`` -![Demonstration QR Code](http://qrfree.kaywa.com/?l=1&s=8&d=http%3A%2F%2Fben-major.co.uk%2Fjquery-mobile-events%2F) +The value you define is the difference in pixels that the user must move before the event is triggered on the target element. If no threshold is defined, a default of `50px` will be used. -Usage: ------- -All of the events outlined above have been written using jQuery's ``event.special`` object, and so can be used in conjunction with jQuery's event handling functions, as well as shortcut wrappers. +``data-xthreshold`` defines the horizontal threshold. -**Binding a ``tap`` event to an element:** -``$('#myElement').bind('tap', function(e) { console.log('User tapped #myElement'); });`` +``data-ythreshold`` defines the vertical threshold. -**Using with ``.on()`` and ``.live()``:** -``$('#myElement').live('tap', function(e) { console.log('User tapped #myElement'); });`` -``$('#myElement').on('tap', function(e) { console.log('User tapped #myElement'); });`` +## 7. Utility Functions: -**Triggering the event:** -``$('#myElement').trigger('tap');`` +In addition to the numerous additional events that are provided, the library also includes a number of utility functions that can be used to further leverage the power of native events within your website or application. These utility functions can be used for unifying basic events, such as `tapstart` or `mousedown`. -**Removing the event with ``.off()``, ``.die()`` and ``.unbind()``:** -``$('#myElement').off('tap', hander);`` -``$('#myElement').die('tap', hander);`` -``$('#myElement').unbind('tap', hander);`` +The following utility functions are provided (each function is registered to the jQuery namespace, and should be called with `$.funcName()` (or `jQuery.funcName()` for compatibility): -**Using method wrapper:** -``$('#myElement').tap(function(e) { console.log('User tapped #myElement'); });`` ++ `isTouchCapable()`: +Returns `true` or `false` depending upon whether touch events are supported. ++ `getStartEvent()`: +Returns `touchstart` for touch-enabled devices, or `mousedown` for standard environments. ++ `getEndEvent()`: +Returns `touchend` for touch-enabled devices, or `mouseup` for standard environments. ++ `getMoveEvent()`: +Returns `touchmove` for touch-enabled devices, or `mousemove` for standard environments. ++ `getTapEvent()`: +Returns `tap` for touch-enabled devices, or `click` for standard environments. ++ `getScrollEvent()`: +Returns `touchmove` for touch-enabled devices, or `scroll` for standard environments. **Caution should be exercised when using this function, since some mobile browsers will correctly bind to `scroll` as well as `touchmove`.** -**Method chaining:** -Chaining has also been preserved, so you can easily use these events in conjuction with other jQuery functions, or attach multiple events in a single, chained LOC: -``$('#myElement').singletap(function() { console.log('singletap'); }).doubletap(function() { console.log('doubletap'); });`` +## 8. Demo: -Defining Thresholds: --------------------- -You can also define custom thresholds to be used for ``swipe`` events (``swipeup``, ``swiperight``, ``swipedown`` and ``swipeleft``) to prevent interference with scrolling and other events. To do so, simply assign a `data-xthreshold` or `date-ythreshold` to the target element as follows: +I have put together a simple demo application that shows the numerous events in action. The console on the left hand side is used to show information about the events that have been called. You can examine the code easily by viewing the page's source to lear more about how this works. Please click on the below to check out the demo: -``
`` +http://ben-major.co.uk/jquery-mobile-events/ -The value you define is the difference in pixels that the user must move before the event is triggered on the target element. If no threshold is defined, a default of `50px` will be used. +Please be aware that this demonstration uses Google's hosted jQuery file, and also pulls the latest version of the events library from GitHub. It is a great place to check the status of the library. Since this demo uses the vanilla code, it is a good idea to check the library functionality here for your own reference. If you're running into problems with the library, please check this demonstration using your device in the first instance. You can scan in the QR below to go directly to the web page: -``data-xthreshold`` defines the horizontal threshold. +![Demonstration QR Code](http://qrfree.kaywa.com/?l=1&s=8&d=http%3A%2F%2Fben-major.co.uk%2Fjquery-mobile-events%2F) -``data-ythreshold`` defines the vertical threshold. -Requirements: -------------- +## 9. Requirements: + The library works with jQuery 1.7.0+. All major browsers have been tested without problem. The library is not compatible with jQuery < 1.7. -License: --------- +## 10. License: + 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: From face453a1025a7c618db1c6da767206f3fde0b20 Mon Sep 17 00:00:00 2001 From: hachigoro Date: Wed, 26 Aug 2015 14:21:54 -0700 Subject: [PATCH 023/149] Copy version 1.0.1 to start a new version --- src/1.0.2/jquery.mobile-events.js | 875 ++++++++++++++++++++++++++++++ 1 file changed, 875 insertions(+) create mode 100644 src/1.0.2/jquery.mobile-events.js diff --git a/src/1.0.2/jquery.mobile-events.js b/src/1.0.2/jquery.mobile-events.js new file mode 100644 index 0000000..92041d0 --- /dev/null +++ b/src/1.0.2/jquery.mobile-events.js @@ -0,0 +1,875 @@ +/*! + * jQuery Mobile Events + * by Ben Major (www.ben-major.co.uk) + * + * Copyright 2011, 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. + * + */ +(function ($) { + $.attrFn = $.attrFn || {}; + + // navigator.userAgent.toLowerCase() isn't reliable for Chrome installs + // on mobile devices. As such, we will create a boolean isChromeDesktop + // The reason that we need to do this is because Chrome annoyingly + // purports support for touch events even if the underlying hardware + // does not! + var agent = navigator.userAgent.toLowerCase(), + isChromeDesktop = (agent.indexOf('chrome') > -1 && ((agent.indexOf('windows') > -1) || (agent.indexOf('macintosh') > -1) || (agent.indexOf('linux') > -1)) && agent.indexOf('mobile') < 0 && agent.indexOf('android') < 0), + + settings = { + tap_pixel_range: 5, + swipe_h_threshold: 50, + swipe_v_threshold: 50, + taphold_threshold: 750, + doubletap_int: 500, + + touch_capable: (window.navigator.msPointerEnabled) ? false : ('ontouchstart' in window && !isChromeDesktop), + orientation_support: ('orientation' in window && 'onorientationchange' in window), + + startevent: (window.navigator.msPointerEnabled) ? 'MSPointerDown' : (('ontouchstart' in window && !isChromeDesktop) ? 'touchstart' : 'mousedown'), + endevent: (window.navigator.msPointerEnabled) ? 'MSPointerUp' : (('ontouchstart' in window && !isChromeDesktop) ? 'touchend' : 'mouseup'), + moveevent: (window.navigator.msPointerEnabled) ? 'MSPointerMove' : (('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'mousemove'), + tapevent: ('ontouchstart' in window && !isChromeDesktop) ? 'tap' : 'click', + scrollevent: ('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'scroll', + + hold_timer: null, + tap_timer: null + }; + + // 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; }; + + // Add Event shortcuts: + $.each(['tapstart', 'tapend', 'tapmove', 'tap', 'tap2', 'tap3', 'tap4', 'singletap', 'doubletap', 'taphold', 'swipe', 'swipeup', 'swiperight', 'swipedown', 'swipeleft', 'swipeend', 'scrollstart', 'scrollend', 'orientationchange'], 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 (e) { + $this.data('callee', arguments.callee); + if (e.which && e.which !== 1) { + return false; + } + + var origEvent = e.originalEvent, + touchData = { + 'position': { + 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + '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 + }, + '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(e) { + $this.data('callee', arguments.callee); + + var origEvent = e.originalEvent, + touchData = { + 'position': { + 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + '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 + }, + '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 (e) { + // Touch event data: + $this.data('callee', arguments.callee); + + var origEvent = e.originalEvent; + var touchData = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].pageX - origEvent.changedTouches[0].target.offsetLeft : e.offsetX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].pageY - origEvent.changedTouches[0].target.offsetTop : e.offsetY + }, + '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, + timer, + start_pos = { + x: 0, + y: 0 + }, + end_x = 0, + end_y = 0; + + $this.on(settings.startevent, function (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].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 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; + + settings.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(), + endPosition = { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + endOffset = { + '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 + }; + duration = end_time - start_time; + + // Build the touch data: + var touchData = { + 'startTime': start_time, + 'endTime': end_time, + 'startPosition': startPosition, + 'startOffset': startOffset, + 'endPosition': endPosition, + 'endOffset': endOffset, + 'duration': duration, + 'target': e.target + } + $this.data('callee1', arguments.callee); + triggerCustomEvent(thisObject, 'taphold', e, touchData); + } + }, settings.taphold_threshold); + + return true; + } + }).on(settings.endevent, function () { + $this.data('callee2', arguments.callee); + $this.data('tapheld', false); + window.clearTimeout(settings.hold_timer); + }) + .on(settings.moveevent, function (e) { + $this.data('callee3', arguments.callee); + + 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, + origEvent, + cooloff, + cooling = false; + + $this.on(settings.startevent, function (e) { + if (e.which && e.which !== 1) { + return false; + } + $this.data('doubletapped', false); + origTarget = e.target; + $this.data('callee1', arguments.callee); + + origEvent = e.originalEvent; + firstTap = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + '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 + }, + 'time': Date.now(), + 'target': e.target + }; + + return true; + }).on(settings.endevent, function (e) { + + var now = Date.now(); + var lastTouch = $this.data('lastTouch') || now + 1; + var delta = now - lastTouch; + window.clearTimeout(action); + $this.data('callee2', arguments.callee); + + if (delta < settings.doubletap_int && (e.target == origTarget) && delta > 100) { + $this.data('doubletapped', true); + window.clearTimeout(settings.tap_timer); + + // Now get the current event: + var lastTap = { + 'position': { + 'x': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? e.originalEvent.changedTouches[0].pageX - e.originalEvent.changedTouches[0].target.offsetLeft : e.offsetX, + 'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].pageY - e.originalEvent.changedTouches[0].target.offsetTop : e.offsetY + }, + 'time': Date.now(), + 'target': e.target + } + + var touchData = { + 'firstTap': firstTap, + 'secondTap': lastTap, + 'interval': lastTap.time - firstTap.time + }; + + if (!cooling) { + triggerCustomEvent(thisObject, 'doubletap', e, touchData); + } + + cooling = true; + + cooloff = window.setTimeout(function (e) { + cooling = false; + }, settings.doubletap_int); + + } else { + $this.data('lastTouch', now); + action = window.setTimeout(function (e) { + 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 (e) { + if (e.which && e.which !== 1) { + return false; + } else { + startTime = Date.now(); + origTarget = e.target; + $this.data('callee1', arguments.callee); + + // 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 (e) { + $this.data('callee2', arguments.callee); + if (e.target == origTarget) { + // Get the end point: + 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 () { + if (!$this.data('doubletapped') && !$this.data('tapheld') && (start_pos.x == end_pos_x) && (start_pos.y == end_pos_y)) { + var origEvent = e.originalEvent; + var touchData = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].pageX - origEvent.changedTouches[0].target.offsetLeft : e.offsetX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].pageY - origEvent.changedTouches[0].target.offsetTop : e.offsetY + }, + '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 (e) { + $this.data('callee1', arguments.callee); + + 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 (e) { + $this.data('callee2', arguments.callee); + + // 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 origEvent = e.originalEvent; + var touchData = [ ]; + + for( var i = 0; i < touches.length; i++) + { + var touch = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[i].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[i].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[i].pageX - origEvent.changedTouches[i].target.offsetLeft : e.offsetX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[i].pageY - origEvent.changedTouches[i].target.offsetTop : e.offsetY + }, + 'time': Date.now(), + 'target': e.target + }; + + touchData.push( touch ); + } + + switch( touches.length ) + { + case 1: + eventName = 'tap'; + break; + + case 2: + eventName = 'tap2'; + break; + + case 3: + eventName = 'tap3'; + break; + + case 4: + eventName = 'tap4'; + break; + } + + triggerCustomEvent(thisObject, eventName, 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', arguments.callee); + 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 origEvent = e.originalEvent; + // Read event data into our startEvt: + startEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + '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 + }, + 'time': Date.now(), + 'target': e.target + }; + } + + // Store coordinates as finger is swiping + + function touchMove(e) { + $this = $(e.currentTarget); + $this.data('callee2', arguments.callee); + 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 (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 (originalCoord.x > finalCoord.x && (originalCoord.x - finalCoord.x > h_threshold)) { + swipedir = 'swipeleft'; + } + 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 origEvent = e.originalEvent; + endEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + '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 + }, + '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', arguments.callee); + 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 origEvent = e.originalEvent; + endEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].pageX - origEvent.changedTouches[0].target.offsetLeft : e.offsetX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].pageY - origEvent.changedTouches[0].target.offsetTop : e.offsetY + }, + 'time': Date.now(), + '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); + + 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 (event) { + $this.data('callee', arguments.callee); + + 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' + }, function (e, srcE, touchData) { + $.event.special[e] = { + setup: function () { + $(this).on(srcE, $.noop); + } + }; + }); + +})(jQuery); From 7dfb7d1bc29e1d7654c6d3f152611d85d3897c9d Mon Sep 17 00:00:00 2001 From: hachigoro Date: Wed, 26 Aug 2015 14:26:02 -0700 Subject: [PATCH 024/149] Made it "strict" compatible To improve performance I am using strict mode. For this I needed to remove all references to "arguments.callee" and declare some variables that were not declared. --- src/1.0.2/jquery.mobile-events.js | 85 ++++++++++++++++--------------- 1 file changed, 45 insertions(+), 40 deletions(-) diff --git a/src/1.0.2/jquery.mobile-events.js b/src/1.0.2/jquery.mobile-events.js index 92041d0..480e665 100644 --- a/src/1.0.2/jquery.mobile-events.js +++ b/src/1.0.2/jquery.mobile-events.js @@ -24,6 +24,9 @@ * THE SOFTWARE. * */ + +"use strict"; + (function ($) { $.attrFn = $.attrFn || {}; @@ -36,7 +39,7 @@ isChromeDesktop = (agent.indexOf('chrome') > -1 && ((agent.indexOf('windows') > -1) || (agent.indexOf('macintosh') > -1) || (agent.indexOf('linux') > -1)) && agent.indexOf('mobile') < 0 && agent.indexOf('android') < 0), settings = { - tap_pixel_range: 5, + tap_pixel_range: 10, swipe_h_threshold: 50, swipe_v_threshold: 50, taphold_threshold: 750, @@ -45,10 +48,10 @@ touch_capable: (window.navigator.msPointerEnabled) ? false : ('ontouchstart' in window && !isChromeDesktop), orientation_support: ('orientation' in window && 'onorientationchange' in window), - startevent: (window.navigator.msPointerEnabled) ? 'MSPointerDown' : (('ontouchstart' in window && !isChromeDesktop) ? 'touchstart' : 'mousedown'), - endevent: (window.navigator.msPointerEnabled) ? 'MSPointerUp' : (('ontouchstart' in window && !isChromeDesktop) ? 'touchend' : 'mouseup'), - moveevent: (window.navigator.msPointerEnabled) ? 'MSPointerMove' : (('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'mousemove'), - tapevent: ('ontouchstart' in window && !isChromeDesktop) ? 'tap' : 'click', + startevent: ('ontouchstart' in window && !isChromeDesktop) ? 'touchstart' : 'mousedown', + endevent: ('ontouchstart' in window && !isChromeDesktop) ? 'touchend' : 'mouseup', + moveevent: ('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'mousemove', + tapevent: ('ontouchstart' in window && !isChromeDesktop) ? 'tap' : 'click', scrollevent: ('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'scroll', hold_timer: null, @@ -62,6 +65,8 @@ $.getMoveEvent = function() { return settings.moveevent; }; $.getTapEvent = function() { return settings.tapevent; }; $.getScrollEvent = function() { return settings.scrollevent; }; + // ORIGIN.TV - We add this function to be able to change the hold threshold: + $.setHoldThreshold = function(threshold) { settings.taphold_threshold = threshold; }; // Add Event shortcuts: $.each(['tapstart', 'tapend', 'tapmove', 'tap', 'tap2', 'tap3', 'tap4', 'singletap', 'doubletap', 'taphold', 'swipe', 'swipeup', 'swiperight', 'swipedown', 'swipeleft', 'swipeend', 'scrollstart', 'scrollend', 'orientationchange'], function (i, name) { @@ -78,8 +83,8 @@ var thisObject = this, $this = $(thisObject); - $this.on(settings.startevent, function (e) { - $this.data('callee', arguments.callee); + $this.on(settings.startevent, function tapStartFunc(e) { + $this.data('callee', tapStartFunc); if (e.which && e.which !== 1) { return false; } @@ -114,8 +119,8 @@ var thisObject = this, $this = $(thisObject); - $this.on(settings.moveevent, function(e) { - $this.data('callee', arguments.callee); + $this.on(settings.moveevent, function tapMoveFunc(e) { + $this.data('callee', tapMoveFunc); var origEvent = e.originalEvent, touchData = { @@ -146,9 +151,9 @@ var thisObject = this, $this = $(thisObject); - $this.on(settings.endevent, function (e) { + $this.on(settings.endevent, function tapEndFunc(e) { // Touch event data: - $this.data('callee', arguments.callee); + $this.data('callee', tapEndFunc); var origEvent = e.originalEvent; var touchData = { @@ -186,7 +191,7 @@ end_x = 0, end_y = 0; - $this.on(settings.startevent, function (e) { + $this.on(settings.startevent, function tapHoldFunc1(e) { if (e.which && e.which !== 1) { return false; } else { @@ -227,7 +232,7 @@ '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 }; - duration = end_time - start_time; + var duration = end_time - start_time; // Build the touch data: var touchData = { @@ -240,20 +245,20 @@ 'duration': duration, 'target': e.target } - $this.data('callee1', arguments.callee); + $this.data('callee1', tapHoldFunc1); triggerCustomEvent(thisObject, 'taphold', e, touchData); } }, settings.taphold_threshold); return true; } - }).on(settings.endevent, function () { - $this.data('callee2', arguments.callee); + }).on(settings.endevent, function tapHoldFunc2() { + $this.data('callee2', tapHoldFunc2); $this.data('tapheld', false); window.clearTimeout(settings.hold_timer); }) - .on(settings.moveevent, function (e) { - $this.data('callee3', arguments.callee); + .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; @@ -277,13 +282,13 @@ cooloff, cooling = false; - $this.on(settings.startevent, function (e) { + $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', arguments.callee); + $this.data('callee1', doubleTapFunc1); origEvent = e.originalEvent; firstTap = { @@ -300,13 +305,13 @@ }; return true; - }).on(settings.endevent, function (e) { + }).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', arguments.callee); + $this.data('callee2', doubleTapFunc2); if (delta < settings.doubletap_int && (e.target == origTarget) && delta > 100) { $this.data('doubletapped', true); @@ -369,25 +374,25 @@ y: 0 }; - $this.on(settings.startevent, function (e) { + $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', arguments.callee); + $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 (e) { - $this.data('callee2', arguments.callee); + }).on(settings.endevent, function singleTapFunc2(e) { + $this.data('callee2', singleTapFunc2); if (e.target == origTarget) { // Get the end point: - 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; + var end_pos_x = (e.originalEvent.changedTouches) ? e.originalEvent.changedTouches[0].pageX : e.pageX; + var end_pos_y = (e.originalEvent.changedTouches) ? e.originalEvent.changedTouches[0].pageY : e.pageY; // We need to check if it was a taphold: @@ -437,8 +442,8 @@ }, touches; - $this.on(settings.startevent, function (e) { - $this.data('callee1', arguments.callee); + $this.on(settings.startevent, function tapFunc1(e) { + $this.data('callee1', tapFunc1); if (e.which && e.which !== 1) { return false; @@ -452,8 +457,8 @@ touches = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches : [ e ]; return true; } - }).on(settings.endevent, function (e) { - $this.data('callee2', arguments.callee); + }).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, @@ -534,7 +539,7 @@ function touchStart(e) { $this = $(e.currentTarget); - $this.data('callee1', arguments.callee); + $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; @@ -560,7 +565,7 @@ function touchMove(e) { $this = $(e.currentTarget); - $this.data('callee2', arguments.callee); + $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; @@ -593,7 +598,7 @@ // Read event data into our endEvnt: var origEvent = e.originalEvent; - endEvnt = { + var endEvnt = { 'position': { 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY @@ -617,7 +622,7 @@ 'xAmount': xAmount, 'yAmount': yAmount, 'duration': endEvnt.time - startEvnt.time - } + }; hasSwiped = true; $this.trigger('swipe', touchData).trigger(swipedir, touchData); } @@ -626,7 +631,7 @@ function touchEnd(e) { $this = $(e.currentTarget); var swipedir = ""; - $this.data('callee3', arguments.callee); + $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'), @@ -635,7 +640,7 @@ v_threshold = (typeof ele_y_threshold !== 'undefined' && ele_y_threshold !== false && parseInt(ele_y_threshold)) ? parseInt(ele_y_threshold) : settings.swipe_v_threshold; var origEvent = e.originalEvent; - endEvnt = { + var endEvnt = { 'position': { 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY @@ -705,8 +710,8 @@ } // iPhone triggers scroll after a small delay; use touchmove instead - $this.on(settings.scrollevent, function (event) { - $this.data('callee', arguments.callee); + $this.on(settings.scrollevent, function scrollFunc(event) { + $this.data('callee', scrollFunc); if (!scrolling) { trigger(event, true); From cee091d81f2f84c9e220511a273b0ca831857ad3 Mon Sep 17 00:00:00 2001 From: hachigoro Date: Wed, 26 Aug 2015 14:34:39 -0700 Subject: [PATCH 025/149] Missed a couple of lines from version 1.0.1 Fixed a couple of things that did not get transferred from version 1.0.1, like supporting Windows Mobile. --- src/1.0.2/jquery.mobile-events.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/1.0.2/jquery.mobile-events.js b/src/1.0.2/jquery.mobile-events.js index 480e665..6a6f6ff 100644 --- a/src/1.0.2/jquery.mobile-events.js +++ b/src/1.0.2/jquery.mobile-events.js @@ -39,7 +39,7 @@ isChromeDesktop = (agent.indexOf('chrome') > -1 && ((agent.indexOf('windows') > -1) || (agent.indexOf('macintosh') > -1) || (agent.indexOf('linux') > -1)) && agent.indexOf('mobile') < 0 && agent.indexOf('android') < 0), settings = { - tap_pixel_range: 10, + tap_pixel_range: 5, swipe_h_threshold: 50, swipe_v_threshold: 50, taphold_threshold: 750, @@ -65,8 +65,6 @@ $.getMoveEvent = function() { return settings.moveevent; }; $.getTapEvent = function() { return settings.tapevent; }; $.getScrollEvent = function() { return settings.scrollevent; }; - // ORIGIN.TV - We add this function to be able to change the hold threshold: - $.setHoldThreshold = function(threshold) { settings.taphold_threshold = threshold; }; // Add Event shortcuts: $.each(['tapstart', 'tapend', 'tapmove', 'tap', 'tap2', 'tap3', 'tap4', 'singletap', 'doubletap', 'taphold', 'swipe', 'swipeup', 'swiperight', 'swipedown', 'swipeleft', 'swipeend', 'scrollstart', 'scrollend', 'orientationchange'], function (i, name) { From b8228e5fa7feaf51f1dd37709bd54d68f394e5b3 Mon Sep 17 00:00:00 2001 From: hachigoro Date: Wed, 26 Aug 2015 14:36:44 -0700 Subject: [PATCH 026/149] Forgot a couple of lines from the previous commit Ok my bad. I forgot the Windows Mobile lines from the previous commit. --- src/1.0.2/jquery.mobile-events.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/1.0.2/jquery.mobile-events.js b/src/1.0.2/jquery.mobile-events.js index 6a6f6ff..daf19fe 100644 --- a/src/1.0.2/jquery.mobile-events.js +++ b/src/1.0.2/jquery.mobile-events.js @@ -48,10 +48,10 @@ touch_capable: (window.navigator.msPointerEnabled) ? false : ('ontouchstart' in window && !isChromeDesktop), orientation_support: ('orientation' in window && 'onorientationchange' in window), - startevent: ('ontouchstart' in window && !isChromeDesktop) ? 'touchstart' : 'mousedown', - endevent: ('ontouchstart' in window && !isChromeDesktop) ? 'touchend' : 'mouseup', - moveevent: ('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'mousemove', - tapevent: ('ontouchstart' in window && !isChromeDesktop) ? 'tap' : 'click', + startevent: (window.navigator.msPointerEnabled) ? 'MSPointerDown' : (('ontouchstart' in window && !isChromeDesktop) ? 'touchstart' : 'mousedown'), + endevent: (window.navigator.msPointerEnabled) ? 'MSPointerUp' : (('ontouchstart' in window && !isChromeDesktop) ? 'touchend' : 'mouseup'), + moveevent: (window.navigator.msPointerEnabled) ? 'MSPointerMove' : (('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'mousemove'), + tapevent: ('ontouchstart' in window && !isChromeDesktop) ? 'tap' : 'click', scrollevent: ('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'scroll', hold_timer: null, From 39d6c6297f0b02251a1e45d1380dc2ad007c8e21 Mon Sep 17 00:00:00 2001 From: hachigoro Date: Wed, 26 Aug 2015 15:34:01 -0700 Subject: [PATCH 027/149] Follow proper javascript conventions Small fixes so the code follows proper javascript, like adding missing semicolons and removing unused arguments and variables. --- src/1.0.2/jquery.mobile-events.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/1.0.2/jquery.mobile-events.js b/src/1.0.2/jquery.mobile-events.js index daf19fe..39ccd93 100644 --- a/src/1.0.2/jquery.mobile-events.js +++ b/src/1.0.2/jquery.mobile-events.js @@ -141,7 +141,7 @@ remove: function() { $(this).off(settings.moveevent, $(this).data.callee); } - } + }; // tapend Event: $.event.special.tapend = { @@ -181,7 +181,6 @@ var thisObject = this, $this = $(thisObject), origTarget, - timer, start_pos = { x: 0, y: 0 @@ -242,7 +241,7 @@ 'endOffset': endOffset, 'duration': duration, 'target': e.target - } + }; $this.data('callee1', tapHoldFunc1); triggerCustomEvent(thisObject, 'taphold', e, touchData); } @@ -327,7 +326,7 @@ }, 'time': Date.now(), 'target': e.target - } + }; var touchData = { 'firstTap': firstTap, @@ -341,13 +340,13 @@ cooling = true; - cooloff = window.setTimeout(function (e) { + cooloff = window.setTimeout(function () { cooling = false; }, settings.doubletap_int); } else { $this.data('lastTouch', now); - action = window.setTimeout(function (e) { + action = window.setTimeout(function () { window.clearTimeout(action); }, settings.doubletap_int, [e]); } @@ -676,7 +675,7 @@ 'xAmount': xAmount, 'yAmount': yAmount, 'duration': endEvnt.time - startEvnt.time - } + }; $this.trigger('swipeend', touchData); } @@ -866,8 +865,8 @@ swipedown: 'swipe', swipeleft: 'swipe', swipeend: 'swipe', - tap2: 'tap' - }, function (e, srcE, touchData) { + tap2: 'tap' + }, function (e, srcE) { $.event.special[e] = { setup: function () { $(this).on(srcE, $.noop); @@ -875,4 +874,4 @@ }; }); -})(jQuery); +}(jQuery)); From 4bde59608bf0b44609cbbb1c4da7ce00d8c529b7 Mon Sep 17 00:00:00 2001 From: hachigoro Date: Wed, 26 Aug 2015 15:38:21 -0700 Subject: [PATCH 028/149] Adding minified version --- src/1.0.2/jquery.mobile-events.min.js | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/1.0.2/jquery.mobile-events.min.js diff --git a/src/1.0.2/jquery.mobile-events.min.js b/src/1.0.2/jquery.mobile-events.min.js new file mode 100644 index 0000000..33242fb --- /dev/null +++ b/src/1.0.2/jquery.mobile-events.min.js @@ -0,0 +1,28 @@ +"use strict"; +/*! + * jQuery Mobile Events + * by Ben Major (www.ben-major.co.uk) + * + * Copyright 2011, 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. + * + */ +(function(n){function l(){var n=e();n!==s&&(s=n,f.trigger("orientationchange"))}function i(t,i,r,u){var f=r.type;r.type=i;n.event.dispatch.call(t,r,u);r.type=f}var f,g,e,s,h,c,o;n.attrFn=n.attrFn||{};var r=navigator.userAgent.toLowerCase(),u=r.indexOf("chrome")>-1&&(r.indexOf("windows")>-1||r.indexOf("macintosh")>-1||r.indexOf("linux")>-1)&&r.indexOf("mobile")<0&&r.indexOf("android")<0,t={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:window.navigator.msPointerEnabled?!1:"ontouchstart"in window&&!u,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:window.navigator.msPointerEnabled?"MSPointerDown":"ontouchstart"in window&&!u?"touchstart":"mousedown",endevent:window.navigator.msPointerEnabled?"MSPointerUp":"ontouchstart"in window&&!u?"touchend":"mouseup",moveevent:window.navigator.msPointerEnabled?"MSPointerMove":"ontouchstart"in window&&!u?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!u?"tap":"click",scrollevent:"ontouchstart"in window&&!u?"touchmove":"scroll",hold_timer:null,tap_timer:null};if(n.isTouchCapable=function(){return t.touch_capable},n.getStartEvent=function(){return t.startevent},n.getEndEvent=function(){return t.endevent},n.getMoveEvent=function(){return t.moveevent},n.getTapEvent=function(){return t.tapevent},n.getScrollEvent=function(){return t.scrollevent},n.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],function(t,i){n.fn[i]=function(n){return n?this.on(i,n):this.trigger(i)};n.attrFn[i]=!0}),n.event.special.tapstart={setup:function(){var r=this,u=n(r);u.on(t.startevent,function f(n){if(u.data("callee",f),n.which&&n.which!==1)return!1;var e=n.originalEvent,o={position:{x:t.touch_capable?e.touches[0].screenX:n.screenX,y:t.touch_capable?e.touches[0].screenY:n.screenY},offset:{x:t.touch_capable?e.touches[0].pageX-e.touches[0].target.offsetLeft:n.offsetX,y:t.touch_capable?e.touches[0].pageY-e.touches[0].target.offsetTop:n.offsetY},time:Date.now(),target:n.target};return i(r,"tapstart",n,o),!0})},remove:function(){n(this).off(t.startevent,n(this).data.callee)}},n.event.special.tapmove={setup:function(){var r=this,u=n(r);u.on(t.moveevent,function f(n){u.data("callee",f);var e=n.originalEvent,o={position:{x:t.touch_capable?e.touches[0].screenX:n.screenX,y:t.touch_capable?e.touches[0].screenY:n.screenY},offset:{x:t.touch_capable?e.touches[0].pageX-e.touches[0].target.offsetLeft:n.offsetX,y:t.touch_capable?e.touches[0].pageY-e.touches[0].target.offsetTop:n.offsetY},time:Date.now(),target:n.target};return i(r,"tapmove",n,o),!0})},remove:function(){n(this).off(t.moveevent,n(this).data.callee)}},n.event.special.tapend={setup:function(){var r=this,u=n(r);u.on(t.endevent,function f(n){u.data("callee",f);var e=n.originalEvent,o={position:{x:t.touch_capable?e.changedTouches[0].screenX:n.screenX,y:t.touch_capable?e.changedTouches[0].screenY:n.screenY},offset:{x:t.touch_capable?e.changedTouches[0].pageX-e.changedTouches[0].target.offsetLeft:n.offsetX,y:t.touch_capable?e.changedTouches[0].pageY-e.changedTouches[0].target.offsetTop:n.offsetY},time:Date.now(),target:n.target};return i(r,"tapend",n,o),!0})},remove:function(){n(this).off(t.endevent,n(this).data.callee)}},n.event.special.taphold={setup:function(){var o=this,u=n(o),s,r={x:0,y:0},f=0,e=0;u.on(t.startevent,function h(n){if(n.which&&n.which!==1)return!1;u.data("tapheld",!1);s=n.target;var c=n.originalEvent,l=Date.now(),a={x:t.touch_capable?c.touches[0].screenX:n.screenX,y:t.touch_capable?c.touches[0].screenY:n.screenY},v={x:t.touch_capable?c.touches[0].pageX-c.touches[0].target.offsetLeft:n.offsetX,y:t.touch_capable?c.touches[0].pageY-c.touches[0].target.offsetTop:n.offsetY};return r.x=n.originalEvent.targetTouches?n.originalEvent.targetTouches[0].pageX:n.pageX,r.y=n.originalEvent.targetTouches?n.originalEvent.targetTouches[0].pageY:n.pageY,f=r.x,e=r.y,t.hold_timer=window.setTimeout(function(){var y=r.x-f,p=r.y-e;if(n.target==s&&(r.x==f&&r.y==e||y>=-t.tap_pixel_range&&y<=t.tap_pixel_range&&p>=-t.tap_pixel_range&&p<=t.tap_pixel_range)){u.data("tapheld",!0);var w=Date.now(),b={x:t.touch_capable?c.touches[0].screenX:n.screenX,y:t.touch_capable?c.touches[0].screenY:n.screenY},k={x:t.touch_capable?c.touches[0].pageX-c.touches[0].target.offsetLeft:n.offsetX,y:t.touch_capable?c.touches[0].pageY-c.touches[0].target.offsetTop:n.offsetY},d=w-l,g={startTime:l,endTime:w,startPosition:a,startOffset:v,endPosition:b,endOffset:k,duration:d,target:n.target};u.data("callee1",h);i(o,"taphold",n,g)}},t.taphold_threshold),!0}).on(t.endevent,function c(){u.data("callee2",c);u.data("tapheld",!1);window.clearTimeout(t.hold_timer)}).on(t.moveevent,function l(n){u.data("callee3",l);f=n.originalEvent.targetTouches?n.originalEvent.targetTouches[0].pageX:n.pageX;e=n.originalEvent.targetTouches?n.originalEvent.targetTouches[0].pageY:n.pageY})},remove:function(){n(this).off(t.startevent,n(this).data.callee1).off(t.endevent,n(this).data.callee2).off(t.moveevent,n(this).data.callee3)}},n.event.special.doubletap={setup:function(){var s=this,r=n(s),h,f,e,u,c,o=!1;r.on(t.startevent,function l(n){return n.which&&n.which!==1?!1:(r.data("doubletapped",!1),h=n.target,r.data("callee1",l),u=n.originalEvent,e={position:{x:t.touch_capable?u.touches[0].screenX:n.screenX,y:t.touch_capable?u.touches[0].screenY:n.screenY},offset:{x:t.touch_capable?u.touches[0].pageX-u.touches[0].target.offsetLeft:n.offsetX,y:t.touch_capable?u.touches[0].pageY-u.touches[0].target.offsetTop:n.offsetY},time:Date.now(),target:n.target},!0)}).on(t.endevent,function a(n){var u=Date.now(),p=r.data("lastTouch")||u+1,v=u-p,l,y;window.clearTimeout(f);r.data("callee2",a);v100?(r.data("doubletapped",!0),window.clearTimeout(t.tap_timer),l={position:{x:t.touch_capable?n.originalEvent.changedTouches[0].screenX:n.screenX,y:t.touch_capable?n.originalEvent.changedTouches[0].screenY:n.screenY},offset:{x:t.touch_capable?n.originalEvent.changedTouches[0].pageX-n.originalEvent.changedTouches[0].target.offsetLeft:n.offsetX,y:t.touch_capable?n.originalEvent.changedTouches[0].pageY-n.originalEvent.changedTouches[0].target.offsetTop:n.offsetY},time:Date.now(),target:n.target},y={firstTap:e,secondTap:l,interval:l.time-e.time},o||i(s,"doubletap",n,y),o=!0,c=window.setTimeout(function(){o=!1},t.doubletap_int)):(r.data("lastTouch",u),f=window.setTimeout(function(){window.clearTimeout(f)},t.doubletap_int,[n]));r.data("lastTouch",u)})},remove:function(){n(this).off(t.startevent,n(this).data.callee1).off(t.endevent,n(this).data.callee2)}},n.event.special.singletap={setup:function(){var f=this,r=n(f),e=null,o=null,u={x:0,y:0};r.on(t.startevent,function s(n){return n.which&&n.which!==1?!1:(o=Date.now(),e=n.target,r.data("callee1",s),u.x=n.originalEvent.targetTouches?n.originalEvent.targetTouches[0].pageX:n.pageX,u.y=n.originalEvent.targetTouches?n.originalEvent.targetTouches[0].pageY:n.pageY,!0)}).on(t.endevent,function h(n){if(r.data("callee2",h),n.target==e){var s=n.originalEvent.changedTouches?n.originalEvent.changedTouches[0].pageX:n.pageX,c=n.originalEvent.changedTouches?n.originalEvent.changedTouches[0].pageY:n.pageY;t.tap_timer=window.setTimeout(function(){if(!r.data("doubletapped")&&!r.data("tapheld")&&u.x==s&&u.y==c){var e=n.originalEvent,h={position:{x:t.touch_capable?e.changedTouches[0].screenX:n.screenX,y:t.touch_capable?e.changedTouches[0].screenY:n.screenY},offset:{x:t.touch_capable?e.changedTouches[0].pageX-e.changedTouches[0].target.offsetLeft:n.offsetX,y:t.touch_capable?e.changedTouches[0].pageY-e.changedTouches[0].target.offsetTop:n.offsetY},time:Date.now(),target:n.target};h.time-o=-t.tap_pixel_range&&b<=t.tap_pixel_range&&k>=-t.tap_pixel_range&&k<=t.tap_pixel_range)){for(a=n.originalEvent,y=[],c=0;cf.y&&u.y-f.y>w&&(c="swipeup"),u.xp&&(c="swiperight"),u.yw&&(c="swipedown"),u.x>f.x&&u.x-f.x>p&&(c="swipeleft"),c!=undefined&&e){u.x=0;u.y=0;f.x=0;f.y=0;e=!1;var l=s.originalEvent,y={position:{x:t.touch_capable?l.touches[0].screenX:s.screenX,y:t.touch_capable?l.touches[0].screenY:s.screenY},offset:{x:t.touch_capable?l.touches[0].pageX-l.touches[0].target.offsetLeft:s.offsetX,y:t.touch_capable?l.touches[0].pageY-l.touches[0].target.offsetTop:s.offsetY},time:Date.now(),target:s.target},k=Math.abs(r.position.x-y.position.x),d=Math.abs(r.position.y-y.position.y),b={startEvnt:r,endEvnt:y,direction:c.replace("swipe",""),xAmount:k,yAmount:d,duration:y.time-r.time};o=!0;i.trigger("swipe",b).trigger(c,b)}}function c(u){var s;if(i=n(u.currentTarget),s="",i.data("callee3",c),o){var l=i.data("xthreshold"),a=i.data("ythreshold"),v=typeof l!="undefined"&&l!==!1&&parseInt(l)?parseInt(l):t.swipe_h_threshold,y=typeof a!="undefined"&&a!==!1&&parseInt(a)?parseInt(a):t.swipe_v_threshold,h=u.originalEvent,f={position:{x:t.touch_capable?h.changedTouches[0].screenX:u.screenX,y:t.touch_capable?h.changedTouches[0].screenY:u.screenY},offset:{x:t.touch_capable?h.changedTouches[0].pageX-h.changedTouches[0].target.offsetLeft:u.offsetX,y:t.touch_capable?h.changedTouches[0].pageY-h.changedTouches[0].target.offsetTop:u.offsetY},time:Date.now(),target:u.target};r.position.y>f.position.y&&r.position.y-f.position.y>y&&(s="swipeup");r.position.xv&&(s="swiperight");r.position.yy&&(s="swipedown");r.position.x>f.position.x&&r.position.x-f.position.x>v&&(s="swipeleft");var p=Math.abs(r.position.x-f.position.x),w=Math.abs(r.position.y-f.position.y),b={startEvnt:r,endEvnt:f,direction:s.replace("swipe",""),xAmount:p,yAmount:w,duration:f.time-r.time};i.trigger("swipeend",b)}e=!1;o=!1}var l=this,i=n(l),e=!1,o=!1,u={x:0,y:0},f={x:0,y:0},r;i.on(t.startevent,s);i.on(t.moveevent,h);i.on(t.endevent,c)},remove:function(){n(this).off(t.startevent,n(this).data.callee1).off(t.moveevent,n(this).data.callee2).off(t.endevent,n(this).data.callee3)}},n.event.special.scrollstart={setup:function(){function o(n,t){r=t;i(u,r?"scrollstart":"scrollend",n)}var u=this,f=n(u),r,e;f.on(t.scrollevent,function s(n){f.data("callee",s);r||o(n,!0);clearTimeout(e);e=setTimeout(function(){o(n,!1)},50)})},remove:function(){n(this).off(t.scrollevent,n(this).data.callee)}},f=n(window),o={"0":!0,"180":!0},t.orientation_support){var p=window.innerWidth||f.width(),w=window.innerHeight||f.height();h=p>w&&p-w>50;c=o[window.orientation];(h&&c||!h&&!c)&&(o={"-90":!0,"90":!0})}n.event.special.orientationchange=g={setup:function(){if(t.orientation_support)return!1;s=e();f.on("throttledresize",l);return!0},teardown:function(){return t.orientation_support?!1:(f.off("throttledresize",l),!0)},add:function(n){var t=n.handler;n.handler=function(n){return n.orientation=e(),t.apply(this,arguments)}}};n.event.special.orientationchange.orientation=e=function(){var i=!0,n=document.documentElement;return i=t.orientation_support?o[window.orientation]:n&&n.clientWidth/n.clientHeight<1.1,i?"portrait":"landscape"};n.event.special.throttledresize={setup:function(){n(this).on("resize",k)},teardown:function(){n(this).off("resize",k)}};var b=250,k=function(){v=Date.now();y=v-d;y>=b?(d=v,n(this).trigger("throttledresize")):(a&&window.clearTimeout(a),a=window.setTimeout(l,b-y))},d=0,a,v,y;n.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,i){n.event.special[t]={setup:function(){n(this).on(i,n.noop)}}})})(jQuery) From 124d082bc4197c47e5764031fd706c20753bce19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olle=20Br=C3=B6ms?= Date: Tue, 6 Oct 2015 16:22:17 +0200 Subject: [PATCH 029/149] Hotfix for swipe respect identifier --- src/1.0.1/jquery.mobile-events.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/1.0.1/jquery.mobile-events.js b/src/1.0.1/jquery.mobile-events.js index 92041d0..f83494c 100644 --- a/src/1.0.1/jquery.mobile-events.js +++ b/src/1.0.1/jquery.mobile-events.js @@ -552,13 +552,17 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].pageY - origEvent.touches[0].target.offsetTop : e.offsetY }, 'time': Date.now(), - 'target': e.target + 'target': e.target, + 'identifier': origEvent.touches[0].identifier }; } // Store coordinates as finger is swiping function touchMove(e) { + if (e.originalEvent.changedTouches[0].identifier !== startEvnt.identifier) { + return; + } $this = $(e.currentTarget); $this.data('callee2', arguments.callee); finalCoord.x = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageX : e.pageX; @@ -624,6 +628,9 @@ } function touchEnd(e) { + if (e.originalEvent.changedTouches[0].identifier !== startEvnt.identifier) { + return; + } $this = $(e.currentTarget); var swipedir = ""; $this.data('callee3', arguments.callee); From b8caae8a61e1e8040e94f220cc54ac687e452649 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olle=20Br=C3=B6ms?= Date: Wed, 7 Oct 2015 09:47:47 +0200 Subject: [PATCH 030/149] Fix for desktop --- src/1.0.1/jquery.mobile-events.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/1.0.1/jquery.mobile-events.js b/src/1.0.1/jquery.mobile-events.js index f83494c..ac1b00c 100644 --- a/src/1.0.1/jquery.mobile-events.js +++ b/src/1.0.1/jquery.mobile-events.js @@ -553,14 +553,14 @@ }, 'time': Date.now(), 'target': e.target, - 'identifier': origEvent.touches[0].identifier + 'identifier': origEvent.touches && origEvent.touches[0].identifier }; } // Store coordinates as finger is swiping function touchMove(e) { - if (e.originalEvent.changedTouches[0].identifier !== startEvnt.identifier) { + if (e.originalEvent.changedTouches && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0].identifier !== startEvnt.identifier) { return; } $this = $(e.currentTarget); @@ -628,7 +628,7 @@ } function touchEnd(e) { - if (e.originalEvent.changedTouches[0].identifier !== startEvnt.identifier) { + if (e.originalEvent.changedTouches && e.originalEvent.changedTouches[0].identifier !== startEvnt.identifier) { return; } $this = $(e.currentTarget); From fd5a1a990dc14cf9ccdf7bde52bc5a04e990f3b4 Mon Sep 17 00:00:00 2001 From: orthographic-pedant Date: Wed, 7 Oct 2015 14:47:03 -0400 Subject: [PATCH 031/149] Fix typographical error(s) Changed conjuction to conjunction in README. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f07e017..69fb997 100644 --- a/README.md +++ b/README.md @@ -96,7 +96,7 @@ $('#myElement').tap(function(e) { ``` **Method chaining:** -Chaining has also been preserved, so you can easily use these events in conjuction with other jQuery functions, or attach multiple events in a single, chained LOC: +Chaining has also been preserved, so you can easily use these events in conjunction with other jQuery functions, or attach multiple events in a single, chained LOC: ``` $('#myElement').singletap(function() { console.log('singletap'); From 78e0b3249bd21b49d085fe998eac871630d70de5 Mon Sep 17 00:00:00 2001 From: Kristian Kvarnsbacke Date: Mon, 2 Nov 2015 11:57:24 +0100 Subject: [PATCH 032/149] Fixed bug in callback data of firstTap in doubletap event. --- src/1.0.2/jquery.mobile-events.js | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/1.0.2/jquery.mobile-events.js b/src/1.0.2/jquery.mobile-events.js index 39ccd93..1495d33 100644 --- a/src/1.0.2/jquery.mobile-events.js +++ b/src/1.0.2/jquery.mobile-events.js @@ -274,7 +274,7 @@ $this = $(thisObject), origTarget, action, - firstTap, + firstTap = null, origEvent, cooloff, cooling = false; @@ -288,18 +288,20 @@ $this.data('callee1', doubleTapFunc1); origEvent = e.originalEvent; - firstTap = { - 'position': { - 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY - }, - 'offset': { - '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 - }, - 'time': Date.now(), - 'target': e.target - }; + if (!firstTap) { + firstTap = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + '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 + }, + 'time': Date.now(), + 'target': e.target + }; + } return true; }).on(settings.endevent, function doubleTapFunc2(e) { @@ -342,11 +344,13 @@ cooloff = window.setTimeout(function () { cooling = false; + firstTap = null; }, settings.doubletap_int); } else { $this.data('lastTouch', now); action = window.setTimeout(function () { + firstTap = null; window.clearTimeout(action); }, settings.doubletap_int, [e]); } From e9976290127104939faf9dbe15640c6aa8a81102 Mon Sep 17 00:00:00 2001 From: Kristian Kvarnsbacke Date: Mon, 2 Nov 2015 12:10:52 +0100 Subject: [PATCH 033/149] Don't wait with resetting firstTap data --- src/1.0.2/jquery.mobile-events.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/1.0.2/jquery.mobile-events.js b/src/1.0.2/jquery.mobile-events.js index 1495d33..b5e867b 100644 --- a/src/1.0.2/jquery.mobile-events.js +++ b/src/1.0.2/jquery.mobile-events.js @@ -338,13 +338,13 @@ if (!cooling) { triggerCustomEvent(thisObject, 'doubletap', e, touchData); + firstTap = null; } cooling = true; cooloff = window.setTimeout(function () { cooling = false; - firstTap = null; }, settings.doubletap_int); } else { From 8addd40043ccc71400a0b5a5f48fea49b9b4ea5d Mon Sep 17 00:00:00 2001 From: Ben Major Date: Tue, 10 Nov 2015 08:56:48 +0000 Subject: [PATCH 034/149] Creating a master file inside /src/ to allow watching. --- src/jquery.mobile-events.js | 881 ++++++++++++++++++++++++++++++++++++ 1 file changed, 881 insertions(+) create mode 100644 src/jquery.mobile-events.js diff --git a/src/jquery.mobile-events.js b/src/jquery.mobile-events.js new file mode 100644 index 0000000..b5e867b --- /dev/null +++ b/src/jquery.mobile-events.js @@ -0,0 +1,881 @@ +/*! + * jQuery Mobile Events + * by Ben Major (www.ben-major.co.uk) + * + * Copyright 2011, 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 || {}; + + // navigator.userAgent.toLowerCase() isn't reliable for Chrome installs + // on mobile devices. As such, we will create a boolean isChromeDesktop + // The reason that we need to do this is because Chrome annoyingly + // purports support for touch events even if the underlying hardware + // does not! + var agent = navigator.userAgent.toLowerCase(), + isChromeDesktop = (agent.indexOf('chrome') > -1 && ((agent.indexOf('windows') > -1) || (agent.indexOf('macintosh') > -1) || (agent.indexOf('linux') > -1)) && agent.indexOf('mobile') < 0 && agent.indexOf('android') < 0), + + settings = { + tap_pixel_range: 5, + swipe_h_threshold: 50, + swipe_v_threshold: 50, + taphold_threshold: 750, + doubletap_int: 500, + + touch_capable: (window.navigator.msPointerEnabled) ? false : ('ontouchstart' in window && !isChromeDesktop), + orientation_support: ('orientation' in window && 'onorientationchange' in window), + + startevent: (window.navigator.msPointerEnabled) ? 'MSPointerDown' : (('ontouchstart' in window && !isChromeDesktop) ? 'touchstart' : 'mousedown'), + endevent: (window.navigator.msPointerEnabled) ? 'MSPointerUp' : (('ontouchstart' in window && !isChromeDesktop) ? 'touchend' : 'mouseup'), + moveevent: (window.navigator.msPointerEnabled) ? 'MSPointerMove' : (('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'mousemove'), + tapevent: ('ontouchstart' in window && !isChromeDesktop) ? 'tap' : 'click', + scrollevent: ('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'scroll', + + hold_timer: null, + tap_timer: null + }; + + // 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; }; + + // Add Event shortcuts: + $.each(['tapstart', 'tapend', 'tapmove', 'tap', 'tap2', 'tap3', 'tap4', 'singletap', 'doubletap', 'taphold', 'swipe', 'swipeup', 'swiperight', 'swipedown', 'swipeleft', 'swipeend', 'scrollstart', 'scrollend', 'orientationchange'], 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 origEvent = e.originalEvent, + touchData = { + 'position': { + 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + '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 + }, + '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 origEvent = e.originalEvent, + touchData = { + 'position': { + 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + '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 + }, + '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 origEvent = e.originalEvent; + var touchData = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].pageX - origEvent.changedTouches[0].target.offsetLeft : e.offsetX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].pageY - origEvent.changedTouches[0].target.offsetTop : e.offsetY + }, + '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].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 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; + + settings.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(), + endPosition = { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + endOffset = { + '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 + }; + var duration = end_time - start_time; + + // Build the touch data: + var touchData = { + 'startTime': start_time, + 'endTime': end_time, + 'startPosition': startPosition, + 'startOffset': startOffset, + 'endPosition': endPosition, + 'endOffset': endOffset, + 'duration': duration, + 'target': e.target + }; + $this.data('callee1', tapHoldFunc1); + triggerCustomEvent(thisObject, 'taphold', e, touchData); + } + }, settings.taphold_threshold); + + return true; + } + }).on(settings.endevent, function tapHoldFunc2() { + $this.data('callee2', tapHoldFunc2); + $this.data('tapheld', false); + window.clearTimeout(settings.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) { + firstTap = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + '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 + }, + 'time': Date.now(), + 'target': e.target + }; + } + + 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 == origTarget) && delta > 100) { + $this.data('doubletapped', true); + window.clearTimeout(settings.tap_timer); + + // Now get the current event: + var lastTap = { + 'position': { + 'x': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? e.originalEvent.changedTouches[0].pageX - e.originalEvent.changedTouches[0].target.offsetLeft : e.offsetX, + 'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].pageY - e.originalEvent.changedTouches[0].target.offsetTop : e.offsetY + }, + 'time': Date.now(), + 'target': e.target + }; + + 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; + var 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 () { + if (!$this.data('doubletapped') && !$this.data('tapheld') && (start_pos.x == end_pos_x) && (start_pos.y == end_pos_y)) { + var origEvent = e.originalEvent; + var touchData = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].pageX - origEvent.changedTouches[0].target.offsetLeft : e.offsetX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].pageY - origEvent.changedTouches[0].target.offsetTop : e.offsetY + }, + '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 origEvent = e.originalEvent; + var touchData = [ ]; + + for( var i = 0; i < touches.length; i++) + { + var touch = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[i].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[i].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[i].pageX - origEvent.changedTouches[i].target.offsetLeft : e.offsetX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[i].pageY - origEvent.changedTouches[i].target.offsetTop : e.offsetY + }, + 'time': Date.now(), + 'target': e.target + }; + + touchData.push( touch ); + } + + switch( touches.length ) + { + case 1: + eventName = 'tap'; + break; + + case 2: + eventName = 'tap2'; + break; + + case 3: + eventName = 'tap3'; + break; + + case 4: + eventName = 'tap4'; + break; + } + + triggerCustomEvent(thisObject, eventName, 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 origEvent = e.originalEvent; + // Read event data into our startEvt: + startEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + '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 + }, + '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 (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 (originalCoord.x > finalCoord.x && (originalCoord.x - finalCoord.x > h_threshold)) { + swipedir = 'swipeleft'; + } + 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 origEvent = e.originalEvent; + var endEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + '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 + }, + '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 origEvent = e.originalEvent; + var endEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].pageX - origEvent.changedTouches[0].target.offsetLeft : e.offsetX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].pageY - origEvent.changedTouches[0].target.offsetTop : e.offsetY + }, + 'time': Date.now(), + '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); + + 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' + }, function (e, srcE) { + $.event.special[e] = { + setup: function () { + $(this).on(srcE, $.noop); + } + }; + }); + +}(jQuery)); From 34e9358443177f191c5da08313a16231fd7c7524 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Tue, 10 Nov 2015 08:57:46 +0000 Subject: [PATCH 035/149] Sync minified version --- src/1.0.2/jquery.mobile-events.min.js | 29 +-------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/src/1.0.2/jquery.mobile-events.min.js b/src/1.0.2/jquery.mobile-events.min.js index 33242fb..3d981e7 100644 --- a/src/1.0.2/jquery.mobile-events.min.js +++ b/src/1.0.2/jquery.mobile-events.min.js @@ -1,28 +1 @@ -"use strict"; -/*! - * jQuery Mobile Events - * by Ben Major (www.ben-major.co.uk) - * - * Copyright 2011, 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. - * - */ -(function(n){function l(){var n=e();n!==s&&(s=n,f.trigger("orientationchange"))}function i(t,i,r,u){var f=r.type;r.type=i;n.event.dispatch.call(t,r,u);r.type=f}var f,g,e,s,h,c,o;n.attrFn=n.attrFn||{};var r=navigator.userAgent.toLowerCase(),u=r.indexOf("chrome")>-1&&(r.indexOf("windows")>-1||r.indexOf("macintosh")>-1||r.indexOf("linux")>-1)&&r.indexOf("mobile")<0&&r.indexOf("android")<0,t={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:window.navigator.msPointerEnabled?!1:"ontouchstart"in window&&!u,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:window.navigator.msPointerEnabled?"MSPointerDown":"ontouchstart"in window&&!u?"touchstart":"mousedown",endevent:window.navigator.msPointerEnabled?"MSPointerUp":"ontouchstart"in window&&!u?"touchend":"mouseup",moveevent:window.navigator.msPointerEnabled?"MSPointerMove":"ontouchstart"in window&&!u?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!u?"tap":"click",scrollevent:"ontouchstart"in window&&!u?"touchmove":"scroll",hold_timer:null,tap_timer:null};if(n.isTouchCapable=function(){return t.touch_capable},n.getStartEvent=function(){return t.startevent},n.getEndEvent=function(){return t.endevent},n.getMoveEvent=function(){return t.moveevent},n.getTapEvent=function(){return t.tapevent},n.getScrollEvent=function(){return t.scrollevent},n.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],function(t,i){n.fn[i]=function(n){return n?this.on(i,n):this.trigger(i)};n.attrFn[i]=!0}),n.event.special.tapstart={setup:function(){var r=this,u=n(r);u.on(t.startevent,function f(n){if(u.data("callee",f),n.which&&n.which!==1)return!1;var e=n.originalEvent,o={position:{x:t.touch_capable?e.touches[0].screenX:n.screenX,y:t.touch_capable?e.touches[0].screenY:n.screenY},offset:{x:t.touch_capable?e.touches[0].pageX-e.touches[0].target.offsetLeft:n.offsetX,y:t.touch_capable?e.touches[0].pageY-e.touches[0].target.offsetTop:n.offsetY},time:Date.now(),target:n.target};return i(r,"tapstart",n,o),!0})},remove:function(){n(this).off(t.startevent,n(this).data.callee)}},n.event.special.tapmove={setup:function(){var r=this,u=n(r);u.on(t.moveevent,function f(n){u.data("callee",f);var e=n.originalEvent,o={position:{x:t.touch_capable?e.touches[0].screenX:n.screenX,y:t.touch_capable?e.touches[0].screenY:n.screenY},offset:{x:t.touch_capable?e.touches[0].pageX-e.touches[0].target.offsetLeft:n.offsetX,y:t.touch_capable?e.touches[0].pageY-e.touches[0].target.offsetTop:n.offsetY},time:Date.now(),target:n.target};return i(r,"tapmove",n,o),!0})},remove:function(){n(this).off(t.moveevent,n(this).data.callee)}},n.event.special.tapend={setup:function(){var r=this,u=n(r);u.on(t.endevent,function f(n){u.data("callee",f);var e=n.originalEvent,o={position:{x:t.touch_capable?e.changedTouches[0].screenX:n.screenX,y:t.touch_capable?e.changedTouches[0].screenY:n.screenY},offset:{x:t.touch_capable?e.changedTouches[0].pageX-e.changedTouches[0].target.offsetLeft:n.offsetX,y:t.touch_capable?e.changedTouches[0].pageY-e.changedTouches[0].target.offsetTop:n.offsetY},time:Date.now(),target:n.target};return i(r,"tapend",n,o),!0})},remove:function(){n(this).off(t.endevent,n(this).data.callee)}},n.event.special.taphold={setup:function(){var o=this,u=n(o),s,r={x:0,y:0},f=0,e=0;u.on(t.startevent,function h(n){if(n.which&&n.which!==1)return!1;u.data("tapheld",!1);s=n.target;var c=n.originalEvent,l=Date.now(),a={x:t.touch_capable?c.touches[0].screenX:n.screenX,y:t.touch_capable?c.touches[0].screenY:n.screenY},v={x:t.touch_capable?c.touches[0].pageX-c.touches[0].target.offsetLeft:n.offsetX,y:t.touch_capable?c.touches[0].pageY-c.touches[0].target.offsetTop:n.offsetY};return r.x=n.originalEvent.targetTouches?n.originalEvent.targetTouches[0].pageX:n.pageX,r.y=n.originalEvent.targetTouches?n.originalEvent.targetTouches[0].pageY:n.pageY,f=r.x,e=r.y,t.hold_timer=window.setTimeout(function(){var y=r.x-f,p=r.y-e;if(n.target==s&&(r.x==f&&r.y==e||y>=-t.tap_pixel_range&&y<=t.tap_pixel_range&&p>=-t.tap_pixel_range&&p<=t.tap_pixel_range)){u.data("tapheld",!0);var w=Date.now(),b={x:t.touch_capable?c.touches[0].screenX:n.screenX,y:t.touch_capable?c.touches[0].screenY:n.screenY},k={x:t.touch_capable?c.touches[0].pageX-c.touches[0].target.offsetLeft:n.offsetX,y:t.touch_capable?c.touches[0].pageY-c.touches[0].target.offsetTop:n.offsetY},d=w-l,g={startTime:l,endTime:w,startPosition:a,startOffset:v,endPosition:b,endOffset:k,duration:d,target:n.target};u.data("callee1",h);i(o,"taphold",n,g)}},t.taphold_threshold),!0}).on(t.endevent,function c(){u.data("callee2",c);u.data("tapheld",!1);window.clearTimeout(t.hold_timer)}).on(t.moveevent,function l(n){u.data("callee3",l);f=n.originalEvent.targetTouches?n.originalEvent.targetTouches[0].pageX:n.pageX;e=n.originalEvent.targetTouches?n.originalEvent.targetTouches[0].pageY:n.pageY})},remove:function(){n(this).off(t.startevent,n(this).data.callee1).off(t.endevent,n(this).data.callee2).off(t.moveevent,n(this).data.callee3)}},n.event.special.doubletap={setup:function(){var s=this,r=n(s),h,f,e,u,c,o=!1;r.on(t.startevent,function l(n){return n.which&&n.which!==1?!1:(r.data("doubletapped",!1),h=n.target,r.data("callee1",l),u=n.originalEvent,e={position:{x:t.touch_capable?u.touches[0].screenX:n.screenX,y:t.touch_capable?u.touches[0].screenY:n.screenY},offset:{x:t.touch_capable?u.touches[0].pageX-u.touches[0].target.offsetLeft:n.offsetX,y:t.touch_capable?u.touches[0].pageY-u.touches[0].target.offsetTop:n.offsetY},time:Date.now(),target:n.target},!0)}).on(t.endevent,function a(n){var u=Date.now(),p=r.data("lastTouch")||u+1,v=u-p,l,y;window.clearTimeout(f);r.data("callee2",a);v100?(r.data("doubletapped",!0),window.clearTimeout(t.tap_timer),l={position:{x:t.touch_capable?n.originalEvent.changedTouches[0].screenX:n.screenX,y:t.touch_capable?n.originalEvent.changedTouches[0].screenY:n.screenY},offset:{x:t.touch_capable?n.originalEvent.changedTouches[0].pageX-n.originalEvent.changedTouches[0].target.offsetLeft:n.offsetX,y:t.touch_capable?n.originalEvent.changedTouches[0].pageY-n.originalEvent.changedTouches[0].target.offsetTop:n.offsetY},time:Date.now(),target:n.target},y={firstTap:e,secondTap:l,interval:l.time-e.time},o||i(s,"doubletap",n,y),o=!0,c=window.setTimeout(function(){o=!1},t.doubletap_int)):(r.data("lastTouch",u),f=window.setTimeout(function(){window.clearTimeout(f)},t.doubletap_int,[n]));r.data("lastTouch",u)})},remove:function(){n(this).off(t.startevent,n(this).data.callee1).off(t.endevent,n(this).data.callee2)}},n.event.special.singletap={setup:function(){var f=this,r=n(f),e=null,o=null,u={x:0,y:0};r.on(t.startevent,function s(n){return n.which&&n.which!==1?!1:(o=Date.now(),e=n.target,r.data("callee1",s),u.x=n.originalEvent.targetTouches?n.originalEvent.targetTouches[0].pageX:n.pageX,u.y=n.originalEvent.targetTouches?n.originalEvent.targetTouches[0].pageY:n.pageY,!0)}).on(t.endevent,function h(n){if(r.data("callee2",h),n.target==e){var s=n.originalEvent.changedTouches?n.originalEvent.changedTouches[0].pageX:n.pageX,c=n.originalEvent.changedTouches?n.originalEvent.changedTouches[0].pageY:n.pageY;t.tap_timer=window.setTimeout(function(){if(!r.data("doubletapped")&&!r.data("tapheld")&&u.x==s&&u.y==c){var e=n.originalEvent,h={position:{x:t.touch_capable?e.changedTouches[0].screenX:n.screenX,y:t.touch_capable?e.changedTouches[0].screenY:n.screenY},offset:{x:t.touch_capable?e.changedTouches[0].pageX-e.changedTouches[0].target.offsetLeft:n.offsetX,y:t.touch_capable?e.changedTouches[0].pageY-e.changedTouches[0].target.offsetTop:n.offsetY},time:Date.now(),target:n.target};h.time-o=-t.tap_pixel_range&&b<=t.tap_pixel_range&&k>=-t.tap_pixel_range&&k<=t.tap_pixel_range)){for(a=n.originalEvent,y=[],c=0;cf.y&&u.y-f.y>w&&(c="swipeup"),u.xp&&(c="swiperight"),u.yw&&(c="swipedown"),u.x>f.x&&u.x-f.x>p&&(c="swipeleft"),c!=undefined&&e){u.x=0;u.y=0;f.x=0;f.y=0;e=!1;var l=s.originalEvent,y={position:{x:t.touch_capable?l.touches[0].screenX:s.screenX,y:t.touch_capable?l.touches[0].screenY:s.screenY},offset:{x:t.touch_capable?l.touches[0].pageX-l.touches[0].target.offsetLeft:s.offsetX,y:t.touch_capable?l.touches[0].pageY-l.touches[0].target.offsetTop:s.offsetY},time:Date.now(),target:s.target},k=Math.abs(r.position.x-y.position.x),d=Math.abs(r.position.y-y.position.y),b={startEvnt:r,endEvnt:y,direction:c.replace("swipe",""),xAmount:k,yAmount:d,duration:y.time-r.time};o=!0;i.trigger("swipe",b).trigger(c,b)}}function c(u){var s;if(i=n(u.currentTarget),s="",i.data("callee3",c),o){var l=i.data("xthreshold"),a=i.data("ythreshold"),v=typeof l!="undefined"&&l!==!1&&parseInt(l)?parseInt(l):t.swipe_h_threshold,y=typeof a!="undefined"&&a!==!1&&parseInt(a)?parseInt(a):t.swipe_v_threshold,h=u.originalEvent,f={position:{x:t.touch_capable?h.changedTouches[0].screenX:u.screenX,y:t.touch_capable?h.changedTouches[0].screenY:u.screenY},offset:{x:t.touch_capable?h.changedTouches[0].pageX-h.changedTouches[0].target.offsetLeft:u.offsetX,y:t.touch_capable?h.changedTouches[0].pageY-h.changedTouches[0].target.offsetTop:u.offsetY},time:Date.now(),target:u.target};r.position.y>f.position.y&&r.position.y-f.position.y>y&&(s="swipeup");r.position.xv&&(s="swiperight");r.position.yy&&(s="swipedown");r.position.x>f.position.x&&r.position.x-f.position.x>v&&(s="swipeleft");var p=Math.abs(r.position.x-f.position.x),w=Math.abs(r.position.y-f.position.y),b={startEvnt:r,endEvnt:f,direction:s.replace("swipe",""),xAmount:p,yAmount:w,duration:f.time-r.time};i.trigger("swipeend",b)}e=!1;o=!1}var l=this,i=n(l),e=!1,o=!1,u={x:0,y:0},f={x:0,y:0},r;i.on(t.startevent,s);i.on(t.moveevent,h);i.on(t.endevent,c)},remove:function(){n(this).off(t.startevent,n(this).data.callee1).off(t.moveevent,n(this).data.callee2).off(t.endevent,n(this).data.callee3)}},n.event.special.scrollstart={setup:function(){function o(n,t){r=t;i(u,r?"scrollstart":"scrollend",n)}var u=this,f=n(u),r,e;f.on(t.scrollevent,function s(n){f.data("callee",s);r||o(n,!0);clearTimeout(e);e=setTimeout(function(){o(n,!1)},50)})},remove:function(){n(this).off(t.scrollevent,n(this).data.callee)}},f=n(window),o={"0":!0,"180":!0},t.orientation_support){var p=window.innerWidth||f.width(),w=window.innerHeight||f.height();h=p>w&&p-w>50;c=o[window.orientation];(h&&c||!h&&!c)&&(o={"-90":!0,"90":!0})}n.event.special.orientationchange=g={setup:function(){if(t.orientation_support)return!1;s=e();f.on("throttledresize",l);return!0},teardown:function(){return t.orientation_support?!1:(f.off("throttledresize",l),!0)},add:function(n){var t=n.handler;n.handler=function(n){return n.orientation=e(),t.apply(this,arguments)}}};n.event.special.orientationchange.orientation=e=function(){var i=!0,n=document.documentElement;return i=t.orientation_support?o[window.orientation]:n&&n.clientWidth/n.clientHeight<1.1,i?"portrait":"landscape"};n.event.special.throttledresize={setup:function(){n(this).on("resize",k)},teardown:function(){n(this).off("resize",k)}};var b=250,k=function(){v=Date.now();y=v-d;y>=b?(d=v,n(this).trigger("throttledresize")):(a&&window.clearTimeout(a),a=window.setTimeout(l,b-y))},d=0,a,v,y;n.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,i){n.event.special[t]={setup:function(){n(this).on(i,n.noop)}}})})(jQuery) +"use strict";!function(e){function t(){var e=c();e!==r&&(r=e,u.trigger("orientationchange"))}function a(t,a,o,n){var i=o.type;o.type=a,e.event.dispatch.call(t,o,n),o.type=i}e.attrFn=e.attrFn||{};var o=navigator.userAgent.toLowerCase(),n=o.indexOf("chrome")>-1&&(o.indexOf("windows")>-1||o.indexOf("macintosh")>-1||o.indexOf("linux")>-1)&&o.indexOf("mobile")<0&&o.indexOf("android")<0,i={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:window.navigator.msPointerEnabled?!1:"ontouchstart"in window&&!n,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:window.navigator.msPointerEnabled?"MSPointerDown":"ontouchstart"in window&&!n?"touchstart":"mousedown",endevent:window.navigator.msPointerEnabled?"MSPointerUp":"ontouchstart"in window&&!n?"touchend":"mouseup",moveevent:window.navigator.msPointerEnabled?"MSPointerMove":"ontouchstart"in window&&!n?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!n?"tap":"click",scrollevent:"ontouchstart"in window&&!n?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.isTouchCapable=function(){return i.touch_capable},e.getStartEvent=function(){return i.startevent},e.getEndEvent=function(){return i.endevent},e.getMoveEvent=function(){return i.moveevent},e.getTapEvent=function(){return i.tapevent},e.getScrollEvent=function(){return i.scrollevent},e.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],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(i.startevent,function n(e){if(o.data("callee",n),e.which&&1!==e.which)return!1;var s=e.originalEvent,c={position:{x:i.touch_capable?s.touches[0].screenX:e.screenX,y:i.touch_capable?s.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?s.touches[0].pageX-s.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?s.touches[0].pageY-s.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapstart",e,c),!0})},remove:function(){e(this).off(i.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,o=e(t);o.on(i.moveevent,function n(e){o.data("callee",n);var s=e.originalEvent,c={position:{x:i.touch_capable?s.touches[0].screenX:e.screenX,y:i.touch_capable?s.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?s.touches[0].pageX-s.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?s.touches[0].pageY-s.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapmove",e,c),!0})},remove:function(){e(this).off(i.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,o=e(t);o.on(i.endevent,function n(e){o.data("callee",n);var s=e.originalEvent,c={position:{x:i.touch_capable?s.changedTouches[0].screenX:e.screenX,y:i.touch_capable?s.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?s.changedTouches[0].pageX-s.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?s.changedTouches[0].pageY-s.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapend",e,c),!0})},remove:function(){e(this).off(i.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,o=this,n=e(o),s={x:0,y:0},c=0,r=0;n.on(i.startevent,function h(e){if(e.which&&1!==e.which)return!1;n.data("tapheld",!1),t=e.target;var p=e.originalEvent,u=Date.now(),l={x:i.touch_capable?p.touches[0].screenX:e.screenX,y:i.touch_capable?p.touches[0].screenY:e.screenY},g={x:i.touch_capable?p.touches[0].pageX-p.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?p.touches[0].pageY-p.touches[0].target.offsetTop:e.offsetY};return s.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,s.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,c=s.x,r=s.y,i.hold_timer=window.setTimeout(function(){var f=s.x-c,d=s.y-r;if(e.target==t&&(s.x==c&&s.y==r||f>=-i.tap_pixel_range&&f<=i.tap_pixel_range&&d>=-i.tap_pixel_range&&d<=i.tap_pixel_range)){n.data("tapheld",!0);var v=Date.now(),w={x:i.touch_capable?p.touches[0].screenX:e.screenX,y:i.touch_capable?p.touches[0].screenY:e.screenY},T={x:i.touch_capable?p.touches[0].pageX-p.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?p.touches[0].pageY-p.touches[0].target.offsetTop:e.offsetY},_=v-u,x={startTime:u,endTime:v,startPosition:l,startOffset:g,endPosition:w,endOffset:T,duration:_,target:e.target};n.data("callee1",h),a(o,"taphold",e,x)}},i.taphold_threshold),!0}).on(i.endevent,function p(){n.data("callee2",p),n.data("tapheld",!1),window.clearTimeout(i.hold_timer)}).on(i.moveevent,function u(e){n.data("callee3",u),c=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,r=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2).off(i.moveevent,e(this).data.callee3)}},e.event.special.doubletap={setup:function(){var t,o,n,s,c=this,r=e(c),h=null,p=!1;r.on(i.startevent,function u(e){return e.which&&1!==e.which?!1:(r.data("doubletapped",!1),t=e.target,r.data("callee1",u),n=e.originalEvent,h||(h={position:{x:i.touch_capable?n.touches[0].screenX:e.screenX,y:i.touch_capable?n.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?n.touches[0].pageX-n.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?n.touches[0].pageY-n.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target}),!0)}).on(i.endevent,function l(e){var n=Date.now(),u=r.data("lastTouch")||n+1,g=n-u;if(window.clearTimeout(o),r.data("callee2",l),g100){r.data("doubletapped",!0),window.clearTimeout(i.tap_timer);var f={position:{x:i.touch_capable?e.originalEvent.changedTouches[0].screenX:e.screenX,y:i.touch_capable?e.originalEvent.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?e.originalEvent.changedTouches[0].pageX-e.originalEvent.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?e.originalEvent.changedTouches[0].pageY-e.originalEvent.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target},d={firstTap:h,secondTap:f,interval:f.time-h.time};p||(a(c,"doubletap",e,d),h=null),p=!0,s=window.setTimeout(function(){p=!1},i.doubletap_int)}else r.data("lastTouch",n),o=window.setTimeout(function(){h=null,window.clearTimeout(o)},i.doubletap_int,[e]);r.data("lastTouch",n)})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,o=e(t),n=null,s=null,c={x:0,y:0};o.on(i.startevent,function r(e){return e.which&&1!==e.which?!1:(s=Date.now(),n=e.target,o.data("callee1",r),c.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,c.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,!0)}).on(i.endevent,function h(e){if(o.data("callee2",h),e.target==n){var r=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageX:e.pageX,p=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageY:e.pageY;i.tap_timer=window.setTimeout(function(){if(!o.data("doubletapped")&&!o.data("tapheld")&&c.x==r&&c.y==p){var n=e.originalEvent,h={position:{x:i.touch_capable?n.changedTouches[0].screenX:e.screenX,y:i.touch_capable?n.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?n.changedTouches[0].pageX-n.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?n.changedTouches[0].pageY-n.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};h.time-s=-i.tap_pixel_range&&f<=i.tap_pixel_range&&d>=-i.tap_pixel_range&&d<=i.tap_pixel_range)){for(var v=e.originalEvent,w=[],T=0;Tu.y&&p.y-u.y>f&&(o="swipeup"),p.xg&&(o="swiperight"),p.yf&&(o="swipedown"),p.x>u.x&&p.x-u.x>g&&(o="swipeleft"),void 0!=o&&r){p.x=0,p.y=0,u.x=0,u.y=0,r=!1;var d=t.originalEvent,v={position:{x:i.touch_capable?d.touches[0].screenX:t.screenX,y:i.touch_capable?d.touches[0].screenY:t.screenY},offset:{x:i.touch_capable?d.touches[0].pageX-d.touches[0].target.offsetLeft:t.offsetX,y:i.touch_capable?d.touches[0].pageY-d.touches[0].target.offsetTop:t.offsetY},time:Date.now(),target:t.target},w=Math.abs(n.position.x-v.position.x),T=Math.abs(n.position.y-v.position.y),_={startEvnt:n,endEvnt:v,direction:o.replace("swipe",""),xAmount:w,yAmount:T,duration:v.time-n.time};h=!0,c.trigger("swipe",_).trigger(o,_)}}function o(t){c=e(t.currentTarget);var a="";if(c.data("callee3",o),h){var s=c.data("xthreshold"),p=c.data("ythreshold"),u="undefined"!=typeof s&&s!==!1&&parseInt(s)?parseInt(s):i.swipe_h_threshold,l="undefined"!=typeof p&&p!==!1&&parseInt(p)?parseInt(p):i.swipe_v_threshold,g=t.originalEvent,f={position:{x:i.touch_capable?g.changedTouches[0].screenX:t.screenX,y:i.touch_capable?g.changedTouches[0].screenY:t.screenY},offset:{x:i.touch_capable?g.changedTouches[0].pageX-g.changedTouches[0].target.offsetLeft:t.offsetX,y:i.touch_capable?g.changedTouches[0].pageY-g.changedTouches[0].target.offsetTop:t.offsetY},time:Date.now(),target:t.target};n.position.y>f.position.y&&n.position.y-f.position.y>l&&(a="swipeup"),n.position.xu&&(a="swiperight"),n.position.yl&&(a="swipedown"),n.position.x>f.position.x&&n.position.x-f.position.x>u&&(a="swipeleft");var d=Math.abs(n.position.x-f.position.x),v=Math.abs(n.position.y-f.position.y),w={startEvnt:n,endEvnt:f,direction:a.replace("swipe",""),xAmount:d,yAmount:v,duration:f.time-n.time};c.trigger("swipeend",w)}r=!1,h=!1}var n,s=this,c=e(s),r=!1,h=!1,p={x:0,y:0},u={x:0,y:0};c.on(i.startevent,t),c.on(i.moveevent,a),c.on(i.endevent,o)},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.moveevent,e(this).data.callee2).off(i.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){function t(e,t){o=t,a(s,o?"scrollstart":"scrollend",e)}var o,n,s=this,c=e(s);c.on(i.scrollevent,function r(e){c.data("callee",r),o||t(e,!0),clearTimeout(n),n=setTimeout(function(){t(e,!1)},50)})},remove:function(){e(this).off(i.scrollevent,e(this).data.callee)}};var s,c,r,h,p,u=e(window),l={0:!0,180:!0};if(i.orientation_support){var g=window.innerWidth||u.width(),f=window.innerHeight||u.height(),d=50;h=g>f&&g-f>d,p=l[window.orientation],(h&&p||!h&&!p)&&(l={"-90":!0,90:!0})}e.event.special.orientationchange=s={setup:function(){return i.orientation_support?!1:(r=c(),u.on("throttledresize",t),!0)},teardown:function(){return i.orientation_support?!1:(u.off("throttledresize",t),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=c(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=c=function(){var e=!0,t=document.documentElement;return e=i.orientation_support?l[window.orientation]:t&&t.clientWidth/t.clientHeight<1.1,e?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",x)},teardown:function(){e(this).off("resize",x)}};var v,w,T,_=250,x=function(){w=Date.now(),T=w-y,T>=_?(y=w,e(this).trigger("throttledresize")):(v&&window.clearTimeout(v),v=window.setTimeout(t,_-T))},y=0;e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); From ab2cd224e19c476d32dda0f8f20326e81228d558 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Tue, 10 Nov 2015 08:58:15 +0000 Subject: [PATCH 036/149] Creating a master file inside /src/ to allow watching. --- src/jquery.mobile-events.min.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/jquery.mobile-events.min.js diff --git a/src/jquery.mobile-events.min.js b/src/jquery.mobile-events.min.js new file mode 100644 index 0000000..3d981e7 --- /dev/null +++ b/src/jquery.mobile-events.min.js @@ -0,0 +1 @@ +"use strict";!function(e){function t(){var e=c();e!==r&&(r=e,u.trigger("orientationchange"))}function a(t,a,o,n){var i=o.type;o.type=a,e.event.dispatch.call(t,o,n),o.type=i}e.attrFn=e.attrFn||{};var o=navigator.userAgent.toLowerCase(),n=o.indexOf("chrome")>-1&&(o.indexOf("windows")>-1||o.indexOf("macintosh")>-1||o.indexOf("linux")>-1)&&o.indexOf("mobile")<0&&o.indexOf("android")<0,i={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:window.navigator.msPointerEnabled?!1:"ontouchstart"in window&&!n,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:window.navigator.msPointerEnabled?"MSPointerDown":"ontouchstart"in window&&!n?"touchstart":"mousedown",endevent:window.navigator.msPointerEnabled?"MSPointerUp":"ontouchstart"in window&&!n?"touchend":"mouseup",moveevent:window.navigator.msPointerEnabled?"MSPointerMove":"ontouchstart"in window&&!n?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!n?"tap":"click",scrollevent:"ontouchstart"in window&&!n?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.isTouchCapable=function(){return i.touch_capable},e.getStartEvent=function(){return i.startevent},e.getEndEvent=function(){return i.endevent},e.getMoveEvent=function(){return i.moveevent},e.getTapEvent=function(){return i.tapevent},e.getScrollEvent=function(){return i.scrollevent},e.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],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(i.startevent,function n(e){if(o.data("callee",n),e.which&&1!==e.which)return!1;var s=e.originalEvent,c={position:{x:i.touch_capable?s.touches[0].screenX:e.screenX,y:i.touch_capable?s.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?s.touches[0].pageX-s.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?s.touches[0].pageY-s.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapstart",e,c),!0})},remove:function(){e(this).off(i.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,o=e(t);o.on(i.moveevent,function n(e){o.data("callee",n);var s=e.originalEvent,c={position:{x:i.touch_capable?s.touches[0].screenX:e.screenX,y:i.touch_capable?s.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?s.touches[0].pageX-s.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?s.touches[0].pageY-s.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapmove",e,c),!0})},remove:function(){e(this).off(i.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,o=e(t);o.on(i.endevent,function n(e){o.data("callee",n);var s=e.originalEvent,c={position:{x:i.touch_capable?s.changedTouches[0].screenX:e.screenX,y:i.touch_capable?s.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?s.changedTouches[0].pageX-s.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?s.changedTouches[0].pageY-s.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapend",e,c),!0})},remove:function(){e(this).off(i.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,o=this,n=e(o),s={x:0,y:0},c=0,r=0;n.on(i.startevent,function h(e){if(e.which&&1!==e.which)return!1;n.data("tapheld",!1),t=e.target;var p=e.originalEvent,u=Date.now(),l={x:i.touch_capable?p.touches[0].screenX:e.screenX,y:i.touch_capable?p.touches[0].screenY:e.screenY},g={x:i.touch_capable?p.touches[0].pageX-p.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?p.touches[0].pageY-p.touches[0].target.offsetTop:e.offsetY};return s.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,s.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,c=s.x,r=s.y,i.hold_timer=window.setTimeout(function(){var f=s.x-c,d=s.y-r;if(e.target==t&&(s.x==c&&s.y==r||f>=-i.tap_pixel_range&&f<=i.tap_pixel_range&&d>=-i.tap_pixel_range&&d<=i.tap_pixel_range)){n.data("tapheld",!0);var v=Date.now(),w={x:i.touch_capable?p.touches[0].screenX:e.screenX,y:i.touch_capable?p.touches[0].screenY:e.screenY},T={x:i.touch_capable?p.touches[0].pageX-p.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?p.touches[0].pageY-p.touches[0].target.offsetTop:e.offsetY},_=v-u,x={startTime:u,endTime:v,startPosition:l,startOffset:g,endPosition:w,endOffset:T,duration:_,target:e.target};n.data("callee1",h),a(o,"taphold",e,x)}},i.taphold_threshold),!0}).on(i.endevent,function p(){n.data("callee2",p),n.data("tapheld",!1),window.clearTimeout(i.hold_timer)}).on(i.moveevent,function u(e){n.data("callee3",u),c=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,r=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2).off(i.moveevent,e(this).data.callee3)}},e.event.special.doubletap={setup:function(){var t,o,n,s,c=this,r=e(c),h=null,p=!1;r.on(i.startevent,function u(e){return e.which&&1!==e.which?!1:(r.data("doubletapped",!1),t=e.target,r.data("callee1",u),n=e.originalEvent,h||(h={position:{x:i.touch_capable?n.touches[0].screenX:e.screenX,y:i.touch_capable?n.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?n.touches[0].pageX-n.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?n.touches[0].pageY-n.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target}),!0)}).on(i.endevent,function l(e){var n=Date.now(),u=r.data("lastTouch")||n+1,g=n-u;if(window.clearTimeout(o),r.data("callee2",l),g100){r.data("doubletapped",!0),window.clearTimeout(i.tap_timer);var f={position:{x:i.touch_capable?e.originalEvent.changedTouches[0].screenX:e.screenX,y:i.touch_capable?e.originalEvent.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?e.originalEvent.changedTouches[0].pageX-e.originalEvent.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?e.originalEvent.changedTouches[0].pageY-e.originalEvent.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target},d={firstTap:h,secondTap:f,interval:f.time-h.time};p||(a(c,"doubletap",e,d),h=null),p=!0,s=window.setTimeout(function(){p=!1},i.doubletap_int)}else r.data("lastTouch",n),o=window.setTimeout(function(){h=null,window.clearTimeout(o)},i.doubletap_int,[e]);r.data("lastTouch",n)})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,o=e(t),n=null,s=null,c={x:0,y:0};o.on(i.startevent,function r(e){return e.which&&1!==e.which?!1:(s=Date.now(),n=e.target,o.data("callee1",r),c.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,c.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,!0)}).on(i.endevent,function h(e){if(o.data("callee2",h),e.target==n){var r=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageX:e.pageX,p=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageY:e.pageY;i.tap_timer=window.setTimeout(function(){if(!o.data("doubletapped")&&!o.data("tapheld")&&c.x==r&&c.y==p){var n=e.originalEvent,h={position:{x:i.touch_capable?n.changedTouches[0].screenX:e.screenX,y:i.touch_capable?n.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?n.changedTouches[0].pageX-n.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?n.changedTouches[0].pageY-n.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};h.time-s=-i.tap_pixel_range&&f<=i.tap_pixel_range&&d>=-i.tap_pixel_range&&d<=i.tap_pixel_range)){for(var v=e.originalEvent,w=[],T=0;Tu.y&&p.y-u.y>f&&(o="swipeup"),p.xg&&(o="swiperight"),p.yf&&(o="swipedown"),p.x>u.x&&p.x-u.x>g&&(o="swipeleft"),void 0!=o&&r){p.x=0,p.y=0,u.x=0,u.y=0,r=!1;var d=t.originalEvent,v={position:{x:i.touch_capable?d.touches[0].screenX:t.screenX,y:i.touch_capable?d.touches[0].screenY:t.screenY},offset:{x:i.touch_capable?d.touches[0].pageX-d.touches[0].target.offsetLeft:t.offsetX,y:i.touch_capable?d.touches[0].pageY-d.touches[0].target.offsetTop:t.offsetY},time:Date.now(),target:t.target},w=Math.abs(n.position.x-v.position.x),T=Math.abs(n.position.y-v.position.y),_={startEvnt:n,endEvnt:v,direction:o.replace("swipe",""),xAmount:w,yAmount:T,duration:v.time-n.time};h=!0,c.trigger("swipe",_).trigger(o,_)}}function o(t){c=e(t.currentTarget);var a="";if(c.data("callee3",o),h){var s=c.data("xthreshold"),p=c.data("ythreshold"),u="undefined"!=typeof s&&s!==!1&&parseInt(s)?parseInt(s):i.swipe_h_threshold,l="undefined"!=typeof p&&p!==!1&&parseInt(p)?parseInt(p):i.swipe_v_threshold,g=t.originalEvent,f={position:{x:i.touch_capable?g.changedTouches[0].screenX:t.screenX,y:i.touch_capable?g.changedTouches[0].screenY:t.screenY},offset:{x:i.touch_capable?g.changedTouches[0].pageX-g.changedTouches[0].target.offsetLeft:t.offsetX,y:i.touch_capable?g.changedTouches[0].pageY-g.changedTouches[0].target.offsetTop:t.offsetY},time:Date.now(),target:t.target};n.position.y>f.position.y&&n.position.y-f.position.y>l&&(a="swipeup"),n.position.xu&&(a="swiperight"),n.position.yl&&(a="swipedown"),n.position.x>f.position.x&&n.position.x-f.position.x>u&&(a="swipeleft");var d=Math.abs(n.position.x-f.position.x),v=Math.abs(n.position.y-f.position.y),w={startEvnt:n,endEvnt:f,direction:a.replace("swipe",""),xAmount:d,yAmount:v,duration:f.time-n.time};c.trigger("swipeend",w)}r=!1,h=!1}var n,s=this,c=e(s),r=!1,h=!1,p={x:0,y:0},u={x:0,y:0};c.on(i.startevent,t),c.on(i.moveevent,a),c.on(i.endevent,o)},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.moveevent,e(this).data.callee2).off(i.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){function t(e,t){o=t,a(s,o?"scrollstart":"scrollend",e)}var o,n,s=this,c=e(s);c.on(i.scrollevent,function r(e){c.data("callee",r),o||t(e,!0),clearTimeout(n),n=setTimeout(function(){t(e,!1)},50)})},remove:function(){e(this).off(i.scrollevent,e(this).data.callee)}};var s,c,r,h,p,u=e(window),l={0:!0,180:!0};if(i.orientation_support){var g=window.innerWidth||u.width(),f=window.innerHeight||u.height(),d=50;h=g>f&&g-f>d,p=l[window.orientation],(h&&p||!h&&!p)&&(l={"-90":!0,90:!0})}e.event.special.orientationchange=s={setup:function(){return i.orientation_support?!1:(r=c(),u.on("throttledresize",t),!0)},teardown:function(){return i.orientation_support?!1:(u.off("throttledresize",t),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=c(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=c=function(){var e=!0,t=document.documentElement;return e=i.orientation_support?l[window.orientation]:t&&t.clientWidth/t.clientHeight<1.1,e?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",x)},teardown:function(){e(this).off("resize",x)}};var v,w,T,_=250,x=function(){w=Date.now(),T=w-y,T>=_?(y=w,e(this).trigger("throttledresize")):(v&&window.clearTimeout(v),v=window.setTimeout(t,_-T))},y=0;e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); From 6fe893d76e2d198da11ec6fb41e85cea3fcfc44f Mon Sep 17 00:00:00 2001 From: Ben Major Date: Tue, 10 Nov 2015 09:14:53 +0000 Subject: [PATCH 037/149] Fixed offset bug Fixes a bug where the offset position returned by events relative to the **current target**, not the bound target. --- src/1.0.3/jquery.mobile-events.js | 884 ++++++++++++++++++++++++++++++ 1 file changed, 884 insertions(+) create mode 100644 src/1.0.3/jquery.mobile-events.js diff --git a/src/1.0.3/jquery.mobile-events.js b/src/1.0.3/jquery.mobile-events.js new file mode 100644 index 0000000..48d40be --- /dev/null +++ b/src/1.0.3/jquery.mobile-events.js @@ -0,0 +1,884 @@ +/*! + * jQuery Mobile Events + * by Ben Major (www.ben-major.co.uk) + * + * Copyright 2011, 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 || {}; + + // navigator.userAgent.toLowerCase() isn't reliable for Chrome installs + // on mobile devices. As such, we will create a boolean isChromeDesktop + // The reason that we need to do this is because Chrome annoyingly + // purports support for touch events even if the underlying hardware + // does not! + var agent = navigator.userAgent.toLowerCase(), + isChromeDesktop = (agent.indexOf('chrome') > -1 && ((agent.indexOf('windows') > -1) || (agent.indexOf('macintosh') > -1) || (agent.indexOf('linux') > -1)) && agent.indexOf('mobile') < 0 && agent.indexOf('android') < 0), + + settings = { + tap_pixel_range: 5, + swipe_h_threshold: 50, + swipe_v_threshold: 50, + taphold_threshold: 750, + doubletap_int: 500, + + touch_capable: (window.navigator.msPointerEnabled) ? false : ('ontouchstart' in window && !isChromeDesktop), + orientation_support: ('orientation' in window && 'onorientationchange' in window), + + startevent: (window.navigator.msPointerEnabled) ? 'MSPointerDown' : (('ontouchstart' in window && !isChromeDesktop) ? 'touchstart' : 'mousedown'), + endevent: (window.navigator.msPointerEnabled) ? 'MSPointerUp' : (('ontouchstart' in window && !isChromeDesktop) ? 'touchend' : 'mouseup'), + moveevent: (window.navigator.msPointerEnabled) ? 'MSPointerMove' : (('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'mousemove'), + tapevent: ('ontouchstart' in window && !isChromeDesktop) ? 'tap' : 'click', + scrollevent: ('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'scroll', + + hold_timer: null, + tap_timer: null + }; + + // 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; }; + + // Add Event shortcuts: + $.each(['tapstart', 'tapend', 'tapmove', 'tap', 'tap2', 'tap3', 'tap4', 'singletap', 'doubletap', 'taphold', 'swipe', 'swipeup', 'swiperight', 'swipedown', 'swipeleft', 'swipeend', 'scrollstart', 'scrollend', 'orientationchange'], 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 origEvent = e.originalEvent, + touchData = { + 'position': { + 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().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 origEvent = e.originalEvent, + touchData = { + 'position': { + 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().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 origEvent = e.originalEvent; + var touchData = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().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].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 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; + + settings.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(), + endPosition = { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + endOffset = { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + }; + var duration = end_time - start_time; + + // Build the touch data: + var touchData = { + 'startTime': start_time, + 'endTime': end_time, + 'startPosition': startPosition, + 'startOffset': startOffset, + 'endPosition': endPosition, + 'endOffset': endOffset, + 'duration': duration, + 'target': e.target + }; + $this.data('callee1', tapHoldFunc1); + triggerCustomEvent(thisObject, 'taphold', e, touchData); + } + }, settings.taphold_threshold); + + return true; + } + }).on(settings.endevent, function tapHoldFunc2() { + $this.data('callee2', tapHoldFunc2); + $this.data('tapheld', false); + window.clearTimeout(settings.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) { + firstTap = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + }, + 'time': Date.now(), + 'target': e.target + }; + } + + 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 == origTarget) && delta > 100) { + $this.data('doubletapped', true); + window.clearTimeout(settings.tap_timer); + + // Now get the current event: + var lastTap = { + 'position': { + 'x': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + }, + 'time': Date.now(), + 'target': e.target + }; + + 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; + var 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 () { + if (!$this.data('doubletapped') && !$this.data('tapheld') && (start_pos.x == end_pos_x) && (start_pos.y == end_pos_y)) { + var origEvent = e.originalEvent; + var touchData = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().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 origEvent = e.originalEvent; + var touchData = [ ]; + + for( var i = 0; i < touches.length; i++) + { + var touch = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[i].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[i].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + }, + 'time': Date.now(), + 'target': e.target + }; + + touchData.push( touch ); + } + + switch( touches.length ) + { + case 1: + eventName = 'tap'; + break; + + case 2: + eventName = 'tap2'; + break; + + case 3: + eventName = 'tap3'; + break; + + case 4: + eventName = 'tap4'; + break; + } + + triggerCustomEvent(thisObject, eventName, 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 origEvent = e.originalEvent; + // Read event data into our startEvt: + startEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().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 (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 (originalCoord.x > finalCoord.x && (originalCoord.x - finalCoord.x > h_threshold)) { + swipedir = 'swipeleft'; + } + 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 origEvent = e.originalEvent; + var endEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().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 origEvent = e.originalEvent; + var endEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + }, + 'time': Date.now(), + '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); + + 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' + }, function (e, srcE) { + $.event.special[e] = { + setup: function () { + $(this).on(srcE, $.noop); + } + }; + }); + +}(jQuery)); From 6b04dd336ab1e3825c506d961f29d9ce061f3267 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Tue, 10 Nov 2015 09:15:45 +0000 Subject: [PATCH 038/149] Fixed offset bug Fixes a bug where the offset position returned by events relative to the **current target**, not the bound target. --- src/1.0.3/jquery.mobile-events.min.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/1.0.3/jquery.mobile-events.min.js diff --git a/src/1.0.3/jquery.mobile-events.min.js b/src/1.0.3/jquery.mobile-events.min.js new file mode 100644 index 0000000..bf1d07e --- /dev/null +++ b/src/1.0.3/jquery.mobile-events.min.js @@ -0,0 +1 @@ +"use strict";!function(e){function t(){var e=c();e!==p&&(p=e,u.trigger("orientationchange"))}function a(t,a,n,o){var i=n.type;n.type=a,e.event.dispatch.call(t,n,o),n.type=i}e.attrFn=e.attrFn||{};var n=navigator.userAgent.toLowerCase(),o=n.indexOf("chrome")>-1&&(n.indexOf("windows")>-1||n.indexOf("macintosh")>-1||n.indexOf("linux")>-1)&&n.indexOf("mobile")<0&&n.indexOf("android")<0,r={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:window.navigator.msPointerEnabled?!1:"ontouchstart"in window&&!o,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:window.navigator.msPointerEnabled?"MSPointerDown":"ontouchstart"in window&&!o?"touchstart":"mousedown",endevent:window.navigator.msPointerEnabled?"MSPointerUp":"ontouchstart"in window&&!o?"touchend":"mouseup",moveevent:window.navigator.msPointerEnabled?"MSPointerMove":"ontouchstart"in window&&!o?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!o?"tap":"click",scrollevent:"ontouchstart"in window&&!o?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.isTouchCapable=function(){return r.touch_capable},e.getStartEvent=function(){return r.startevent},e.getEndEvent=function(){return r.endevent},e.getMoveEvent=function(){return r.moveevent},e.getTapEvent=function(){return r.tapevent},e.getScrollEvent=function(){return r.scrollevent},e.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],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,n=e(t);n.on(r.startevent,function o(e){if(n.data("callee",o),e.which&&1!==e.which)return!1;var s=e.originalEvent,c={position:{x:r.touch_capable?s.touches[0].screenX:e.screenX,y:r.touch_capable?s.touches[0].screenY:e.screenY},offset:{x:Math.round(r.touch_capable?s.changedTouches[i].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(r.touch_capable?s.changedTouches[i].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};return a(t,"tapstart",e,c),!0})},remove:function(){e(this).off(r.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,n=e(t);n.on(r.moveevent,function o(e){n.data("callee",o);var s=e.originalEvent,c={position:{x:r.touch_capable?s.touches[0].screenX:e.screenX,y:r.touch_capable?s.touches[0].screenY:e.screenY},offset:{x:Math.round(r.touch_capable?s.changedTouches[i].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(r.touch_capable?s.changedTouches[i].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};return a(t,"tapmove",e,c),!0})},remove:function(){e(this).off(r.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,n=e(t);n.on(r.endevent,function o(e){n.data("callee",o);var s=e.originalEvent,c={position:{x:r.touch_capable?s.changedTouches[0].screenX:e.screenX,y:r.touch_capable?s.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(r.touch_capable?s.changedTouches[i].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(r.touch_capable?s.changedTouches[i].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};return a(t,"tapend",e,c),!0})},remove:function(){e(this).off(r.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,n=this,o=e(n),s={x:0,y:0},c=0,p=0;o.on(r.startevent,function h(e){if(e.which&&1!==e.which)return!1;o.data("tapheld",!1),t=e.target;var l=e.originalEvent,u=Date.now(),g={x:r.touch_capable?l.touches[0].screenX:e.screenX,y:r.touch_capable?l.touches[0].screenY:e.screenY},d={x:r.touch_capable?l.touches[0].pageX-l.touches[0].target.offsetLeft:e.offsetX,y:r.touch_capable?l.touches[0].pageY-l.touches[0].target.offsetTop:e.offsetY};return s.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,s.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,c=s.x,p=s.y,r.hold_timer=window.setTimeout(function(){var f=s.x-c,v=s.y-p;if(e.target==t&&(s.x==c&&s.y==p||f>=-r.tap_pixel_range&&f<=r.tap_pixel_range&&v>=-r.tap_pixel_range&&v<=r.tap_pixel_range)){o.data("tapheld",!0);var w=Date.now(),_={x:r.touch_capable?l.touches[0].screenX:e.screenX,y:r.touch_capable?l.touches[0].screenY:e.screenY},T={x:Math.round(r.touch_capable?l.changedTouches[i].pageX-o.position().left:e.pageX-o.position().left),y:Math.round(r.touch_capable?l.changedTouches[i].pageY-o.position().top:e.pageY-o.position().top)},x=w-u,y={startTime:u,endTime:w,startPosition:g,startOffset:d,endPosition:_,endOffset:T,duration:x,target:e.target};o.data("callee1",h),a(n,"taphold",e,y)}},r.taphold_threshold),!0}).on(r.endevent,function l(){o.data("callee2",l),o.data("tapheld",!1),window.clearTimeout(r.hold_timer)}).on(r.moveevent,function u(e){o.data("callee3",u),c=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,p=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY})},remove:function(){e(this).off(r.startevent,e(this).data.callee1).off(r.endevent,e(this).data.callee2).off(r.moveevent,e(this).data.callee3)}},e.event.special.doubletap={setup:function(){var t,n,o,s,c=this,p=e(c),h=null,l=!1;p.on(r.startevent,function u(e){return e.which&&1!==e.which?!1:(p.data("doubletapped",!1),t=e.target,p.data("callee1",u),o=e.originalEvent,h||(h={position:{x:r.touch_capable?o.touches[0].screenX:e.screenX,y:r.touch_capable?o.touches[0].screenY:e.screenY},offset:{x:Math.round(r.touch_capable?o.changedTouches[i].pageX-p.position().left:e.pageX-p.position().left),y:Math.round(r.touch_capable?o.changedTouches[i].pageY-p.position().top:e.pageY-p.position().top)},time:Date.now(),target:e.target}),!0)}).on(r.endevent,function g(e){var u=Date.now(),d=p.data("lastTouch")||u+1,f=u-d;if(window.clearTimeout(n),p.data("callee2",g),f100){p.data("doubletapped",!0),window.clearTimeout(r.tap_timer);var v={position:{x:r.touch_capable?e.originalEvent.changedTouches[0].screenX:e.screenX,y:r.touch_capable?e.originalEvent.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(r.touch_capable?o.changedTouches[i].pageX-p.position().left:e.pageX-p.position().left),y:Math.round(r.touch_capable?o.changedTouches[i].pageY-p.position().top:e.pageY-p.position().top)},time:Date.now(),target:e.target},w={firstTap:h,secondTap:v,interval:v.time-h.time};l||(a(c,"doubletap",e,w),h=null),l=!0,s=window.setTimeout(function(){l=!1},r.doubletap_int)}else p.data("lastTouch",u),n=window.setTimeout(function(){h=null,window.clearTimeout(n)},r.doubletap_int,[e]);p.data("lastTouch",u)})},remove:function(){e(this).off(r.startevent,e(this).data.callee1).off(r.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,n=e(t),o=null,s=null,c={x:0,y:0};n.on(r.startevent,function p(e){return e.which&&1!==e.which?!1:(s=Date.now(),o=e.target,n.data("callee1",p),c.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,c.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,!0)}).on(r.endevent,function h(e){if(n.data("callee2",h),e.target==o){var p=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageX:e.pageX,l=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageY:e.pageY;r.tap_timer=window.setTimeout(function(){if(!n.data("doubletapped")&&!n.data("tapheld")&&c.x==p&&c.y==l){var o=e.originalEvent,h={position:{x:r.touch_capable?o.changedTouches[0].screenX:e.screenX,y:r.touch_capable?o.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(r.touch_capable?o.changedTouches[i].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(r.touch_capable?o.changedTouches[i].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};h.time-s=-r.tap_pixel_range&&d<=r.tap_pixel_range&&f>=-r.tap_pixel_range&&f<=r.tap_pixel_range)){for(var v=e.originalEvent,w=[],_=0;_u.y&&l.y-u.y>f&&(n="swipeup"),l.xd&&(n="swiperight"),l.yf&&(n="swipedown"),l.x>u.x&&l.x-u.x>d&&(n="swipeleft"),void 0!=n&&p){l.x=0,l.y=0,u.x=0,u.y=0,p=!1;var v=t.originalEvent,w={position:{x:r.touch_capable?v.touches[0].screenX:t.screenX,y:r.touch_capable?v.touches[0].screenY:t.screenY},offset:{x:Math.round(r.touch_capable?v.changedTouches[i].pageX-c.position().left:t.pageX-c.position().left),y:Math.round(r.touch_capable?v.changedTouches[i].pageY-c.position().top:t.pageY-c.position().top)},time:Date.now(),target:t.target},_=Math.abs(o.position.x-w.position.x),T=Math.abs(o.position.y-w.position.y),x={startEvnt:o,endEvnt:w,direction:n.replace("swipe",""),xAmount:_,yAmount:T,duration:w.time-o.time};h=!0,c.trigger("swipe",x).trigger(n,x)}}function n(t){c=e(t.currentTarget);var a="";if(c.data("callee3",n),h){var s=c.data("xthreshold"),l=c.data("ythreshold"),u="undefined"!=typeof s&&s!==!1&&parseInt(s)?parseInt(s):r.swipe_h_threshold,g="undefined"!=typeof l&&l!==!1&&parseInt(l)?parseInt(l):r.swipe_v_threshold,d=t.originalEvent,f={position:{x:r.touch_capable?d.changedTouches[0].screenX:t.screenX,y:r.touch_capable?d.changedTouches[0].screenY:t.screenY},offset:{x:Math.round(r.touch_capable?d.changedTouches[i].pageX-c.position().left:t.pageX-c.position().left),y:Math.round(r.touch_capable?d.changedTouches[i].pageY-c.position().top:t.pageY-c.position().top)},time:Date.now(),target:t.target};o.position.y>f.position.y&&o.position.y-f.position.y>g&&(a="swipeup"),o.position.xu&&(a="swiperight"),o.position.yg&&(a="swipedown"),o.position.x>f.position.x&&o.position.x-f.position.x>u&&(a="swipeleft");var v=Math.abs(o.position.x-f.position.x),w=Math.abs(o.position.y-f.position.y),_={startEvnt:o,endEvnt:f,direction:a.replace("swipe",""),xAmount:v,yAmount:w,duration:f.time-o.time};c.trigger("swipeend",_)}p=!1,h=!1}var o,s=this,c=e(s),p=!1,h=!1,l={x:0,y:0},u={x:0,y:0};c.on(r.startevent,t),c.on(r.moveevent,a),c.on(r.endevent,n)},remove:function(){e(this).off(r.startevent,e(this).data.callee1).off(r.moveevent,e(this).data.callee2).off(r.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){function t(e,t){n=t,a(i,n?"scrollstart":"scrollend",e)}var n,o,i=this,s=e(i);s.on(r.scrollevent,function c(e){s.data("callee",c),n||t(e,!0),clearTimeout(o),o=setTimeout(function(){t(e,!1)},50)})},remove:function(){e(this).off(r.scrollevent,e(this).data.callee)}};var s,c,p,h,l,u=e(window),g={0:!0,180:!0};if(r.orientation_support){var d=window.innerWidth||u.width(),f=window.innerHeight||u.height(),v=50;h=d>f&&d-f>v,l=g[window.orientation],(h&&l||!h&&!l)&&(g={"-90":!0,90:!0})}e.event.special.orientationchange=s={setup:function(){return r.orientation_support?!1:(p=c(),u.on("throttledresize",t),!0)},teardown:function(){return r.orientation_support?!1:(u.off("throttledresize",t),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=c(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=c=function(){var e=!0,t=document.documentElement;return e=r.orientation_support?g[window.orientation]:t&&t.clientWidth/t.clientHeight<1.1,e?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",y)},teardown:function(){e(this).off("resize",y)}};var w,_,T,x=250,y=function(){_=Date.now(),T=_-m,T>=x?(m=_,e(this).trigger("throttledresize")):(w&&window.clearTimeout(w),w=window.setTimeout(t,x-T))},m=0;e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); From fd39768a993ac2328aa2a6029cb03a7cd1652909 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Tue, 10 Nov 2015 09:16:53 +0000 Subject: [PATCH 039/149] Fixed offset bug See # 6fe893d76e2d198da11ec6fb41e85cea3fcfc44f --- src/jquery.mobile-events.js | 51 ++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/src/jquery.mobile-events.js b/src/jquery.mobile-events.js index b5e867b..48d40be 100644 --- a/src/jquery.mobile-events.js +++ b/src/jquery.mobile-events.js @@ -94,8 +94,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - '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 + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target @@ -127,8 +127,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - '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 + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target @@ -160,8 +160,8 @@ 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? origEvent.changedTouches[0].pageX - origEvent.changedTouches[0].target.offsetLeft : e.offsetX, - 'y': (settings.touch_capable) ? origEvent.changedTouches[0].pageY - origEvent.changedTouches[0].target.offsetTop : e.offsetY + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target @@ -226,8 +226,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, endOffset = { - '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 + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }; var duration = end_time - start_time; @@ -295,8 +295,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - '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 + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target @@ -323,8 +323,8 @@ 'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? e.originalEvent.changedTouches[0].pageX - e.originalEvent.changedTouches[0].target.offsetLeft : e.offsetX, - 'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].pageY - e.originalEvent.changedTouches[0].target.offsetTop : e.offsetY + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target @@ -406,8 +406,8 @@ 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? origEvent.changedTouches[0].pageX - origEvent.changedTouches[0].target.offsetLeft : e.offsetX, - 'y': (settings.touch_capable) ? origEvent.changedTouches[0].pageY - origEvent.changedTouches[0].target.offsetTop : e.offsetY + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target @@ -446,9 +446,12 @@ $this.on(settings.startevent, function tapFunc1(e) { $this.data('callee1', tapFunc1); - if (e.which && e.which !== 1) { + if( e.which && e.which !== 1 ) + { return false; - } else { + } + 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; @@ -480,8 +483,8 @@ 'y': (settings.touch_capable) ? origEvent.changedTouches[i].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? origEvent.changedTouches[i].pageX - origEvent.changedTouches[i].target.offsetLeft : e.offsetX, - 'y': (settings.touch_capable) ? origEvent.changedTouches[i].pageY - origEvent.changedTouches[i].target.offsetTop : e.offsetY + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target @@ -554,8 +557,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - '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 + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target @@ -605,8 +608,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - '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 + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target @@ -647,8 +650,8 @@ 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? origEvent.changedTouches[0].pageX - origEvent.changedTouches[0].target.offsetLeft : e.offsetX, - 'y': (settings.touch_capable) ? origEvent.changedTouches[0].pageY - origEvent.changedTouches[0].target.offsetTop : e.offsetY + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target From b165c72c074160ab3b9ceeb270028a8d9496c352 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Tue, 10 Nov 2015 09:17:38 +0000 Subject: [PATCH 040/149] Fixed offset bug See # 6b04dd336ab1e3825c506d961f29d9ce061f3267 --- src/jquery.mobile-events.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jquery.mobile-events.min.js b/src/jquery.mobile-events.min.js index 3d981e7..bf1d07e 100644 --- a/src/jquery.mobile-events.min.js +++ b/src/jquery.mobile-events.min.js @@ -1 +1 @@ -"use strict";!function(e){function t(){var e=c();e!==r&&(r=e,u.trigger("orientationchange"))}function a(t,a,o,n){var i=o.type;o.type=a,e.event.dispatch.call(t,o,n),o.type=i}e.attrFn=e.attrFn||{};var o=navigator.userAgent.toLowerCase(),n=o.indexOf("chrome")>-1&&(o.indexOf("windows")>-1||o.indexOf("macintosh")>-1||o.indexOf("linux")>-1)&&o.indexOf("mobile")<0&&o.indexOf("android")<0,i={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:window.navigator.msPointerEnabled?!1:"ontouchstart"in window&&!n,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:window.navigator.msPointerEnabled?"MSPointerDown":"ontouchstart"in window&&!n?"touchstart":"mousedown",endevent:window.navigator.msPointerEnabled?"MSPointerUp":"ontouchstart"in window&&!n?"touchend":"mouseup",moveevent:window.navigator.msPointerEnabled?"MSPointerMove":"ontouchstart"in window&&!n?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!n?"tap":"click",scrollevent:"ontouchstart"in window&&!n?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.isTouchCapable=function(){return i.touch_capable},e.getStartEvent=function(){return i.startevent},e.getEndEvent=function(){return i.endevent},e.getMoveEvent=function(){return i.moveevent},e.getTapEvent=function(){return i.tapevent},e.getScrollEvent=function(){return i.scrollevent},e.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],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(i.startevent,function n(e){if(o.data("callee",n),e.which&&1!==e.which)return!1;var s=e.originalEvent,c={position:{x:i.touch_capable?s.touches[0].screenX:e.screenX,y:i.touch_capable?s.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?s.touches[0].pageX-s.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?s.touches[0].pageY-s.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapstart",e,c),!0})},remove:function(){e(this).off(i.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,o=e(t);o.on(i.moveevent,function n(e){o.data("callee",n);var s=e.originalEvent,c={position:{x:i.touch_capable?s.touches[0].screenX:e.screenX,y:i.touch_capable?s.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?s.touches[0].pageX-s.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?s.touches[0].pageY-s.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapmove",e,c),!0})},remove:function(){e(this).off(i.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,o=e(t);o.on(i.endevent,function n(e){o.data("callee",n);var s=e.originalEvent,c={position:{x:i.touch_capable?s.changedTouches[0].screenX:e.screenX,y:i.touch_capable?s.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?s.changedTouches[0].pageX-s.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?s.changedTouches[0].pageY-s.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};return a(t,"tapend",e,c),!0})},remove:function(){e(this).off(i.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,o=this,n=e(o),s={x:0,y:0},c=0,r=0;n.on(i.startevent,function h(e){if(e.which&&1!==e.which)return!1;n.data("tapheld",!1),t=e.target;var p=e.originalEvent,u=Date.now(),l={x:i.touch_capable?p.touches[0].screenX:e.screenX,y:i.touch_capable?p.touches[0].screenY:e.screenY},g={x:i.touch_capable?p.touches[0].pageX-p.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?p.touches[0].pageY-p.touches[0].target.offsetTop:e.offsetY};return s.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,s.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,c=s.x,r=s.y,i.hold_timer=window.setTimeout(function(){var f=s.x-c,d=s.y-r;if(e.target==t&&(s.x==c&&s.y==r||f>=-i.tap_pixel_range&&f<=i.tap_pixel_range&&d>=-i.tap_pixel_range&&d<=i.tap_pixel_range)){n.data("tapheld",!0);var v=Date.now(),w={x:i.touch_capable?p.touches[0].screenX:e.screenX,y:i.touch_capable?p.touches[0].screenY:e.screenY},T={x:i.touch_capable?p.touches[0].pageX-p.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?p.touches[0].pageY-p.touches[0].target.offsetTop:e.offsetY},_=v-u,x={startTime:u,endTime:v,startPosition:l,startOffset:g,endPosition:w,endOffset:T,duration:_,target:e.target};n.data("callee1",h),a(o,"taphold",e,x)}},i.taphold_threshold),!0}).on(i.endevent,function p(){n.data("callee2",p),n.data("tapheld",!1),window.clearTimeout(i.hold_timer)}).on(i.moveevent,function u(e){n.data("callee3",u),c=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,r=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2).off(i.moveevent,e(this).data.callee3)}},e.event.special.doubletap={setup:function(){var t,o,n,s,c=this,r=e(c),h=null,p=!1;r.on(i.startevent,function u(e){return e.which&&1!==e.which?!1:(r.data("doubletapped",!1),t=e.target,r.data("callee1",u),n=e.originalEvent,h||(h={position:{x:i.touch_capable?n.touches[0].screenX:e.screenX,y:i.touch_capable?n.touches[0].screenY:e.screenY},offset:{x:i.touch_capable?n.touches[0].pageX-n.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?n.touches[0].pageY-n.touches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target}),!0)}).on(i.endevent,function l(e){var n=Date.now(),u=r.data("lastTouch")||n+1,g=n-u;if(window.clearTimeout(o),r.data("callee2",l),g100){r.data("doubletapped",!0),window.clearTimeout(i.tap_timer);var f={position:{x:i.touch_capable?e.originalEvent.changedTouches[0].screenX:e.screenX,y:i.touch_capable?e.originalEvent.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?e.originalEvent.changedTouches[0].pageX-e.originalEvent.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?e.originalEvent.changedTouches[0].pageY-e.originalEvent.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target},d={firstTap:h,secondTap:f,interval:f.time-h.time};p||(a(c,"doubletap",e,d),h=null),p=!0,s=window.setTimeout(function(){p=!1},i.doubletap_int)}else r.data("lastTouch",n),o=window.setTimeout(function(){h=null,window.clearTimeout(o)},i.doubletap_int,[e]);r.data("lastTouch",n)})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,o=e(t),n=null,s=null,c={x:0,y:0};o.on(i.startevent,function r(e){return e.which&&1!==e.which?!1:(s=Date.now(),n=e.target,o.data("callee1",r),c.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,c.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,!0)}).on(i.endevent,function h(e){if(o.data("callee2",h),e.target==n){var r=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageX:e.pageX,p=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageY:e.pageY;i.tap_timer=window.setTimeout(function(){if(!o.data("doubletapped")&&!o.data("tapheld")&&c.x==r&&c.y==p){var n=e.originalEvent,h={position:{x:i.touch_capable?n.changedTouches[0].screenX:e.screenX,y:i.touch_capable?n.changedTouches[0].screenY:e.screenY},offset:{x:i.touch_capable?n.changedTouches[0].pageX-n.changedTouches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?n.changedTouches[0].pageY-n.changedTouches[0].target.offsetTop:e.offsetY},time:Date.now(),target:e.target};h.time-s=-i.tap_pixel_range&&f<=i.tap_pixel_range&&d>=-i.tap_pixel_range&&d<=i.tap_pixel_range)){for(var v=e.originalEvent,w=[],T=0;Tu.y&&p.y-u.y>f&&(o="swipeup"),p.xg&&(o="swiperight"),p.yf&&(o="swipedown"),p.x>u.x&&p.x-u.x>g&&(o="swipeleft"),void 0!=o&&r){p.x=0,p.y=0,u.x=0,u.y=0,r=!1;var d=t.originalEvent,v={position:{x:i.touch_capable?d.touches[0].screenX:t.screenX,y:i.touch_capable?d.touches[0].screenY:t.screenY},offset:{x:i.touch_capable?d.touches[0].pageX-d.touches[0].target.offsetLeft:t.offsetX,y:i.touch_capable?d.touches[0].pageY-d.touches[0].target.offsetTop:t.offsetY},time:Date.now(),target:t.target},w=Math.abs(n.position.x-v.position.x),T=Math.abs(n.position.y-v.position.y),_={startEvnt:n,endEvnt:v,direction:o.replace("swipe",""),xAmount:w,yAmount:T,duration:v.time-n.time};h=!0,c.trigger("swipe",_).trigger(o,_)}}function o(t){c=e(t.currentTarget);var a="";if(c.data("callee3",o),h){var s=c.data("xthreshold"),p=c.data("ythreshold"),u="undefined"!=typeof s&&s!==!1&&parseInt(s)?parseInt(s):i.swipe_h_threshold,l="undefined"!=typeof p&&p!==!1&&parseInt(p)?parseInt(p):i.swipe_v_threshold,g=t.originalEvent,f={position:{x:i.touch_capable?g.changedTouches[0].screenX:t.screenX,y:i.touch_capable?g.changedTouches[0].screenY:t.screenY},offset:{x:i.touch_capable?g.changedTouches[0].pageX-g.changedTouches[0].target.offsetLeft:t.offsetX,y:i.touch_capable?g.changedTouches[0].pageY-g.changedTouches[0].target.offsetTop:t.offsetY},time:Date.now(),target:t.target};n.position.y>f.position.y&&n.position.y-f.position.y>l&&(a="swipeup"),n.position.xu&&(a="swiperight"),n.position.yl&&(a="swipedown"),n.position.x>f.position.x&&n.position.x-f.position.x>u&&(a="swipeleft");var d=Math.abs(n.position.x-f.position.x),v=Math.abs(n.position.y-f.position.y),w={startEvnt:n,endEvnt:f,direction:a.replace("swipe",""),xAmount:d,yAmount:v,duration:f.time-n.time};c.trigger("swipeend",w)}r=!1,h=!1}var n,s=this,c=e(s),r=!1,h=!1,p={x:0,y:0},u={x:0,y:0};c.on(i.startevent,t),c.on(i.moveevent,a),c.on(i.endevent,o)},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.moveevent,e(this).data.callee2).off(i.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){function t(e,t){o=t,a(s,o?"scrollstart":"scrollend",e)}var o,n,s=this,c=e(s);c.on(i.scrollevent,function r(e){c.data("callee",r),o||t(e,!0),clearTimeout(n),n=setTimeout(function(){t(e,!1)},50)})},remove:function(){e(this).off(i.scrollevent,e(this).data.callee)}};var s,c,r,h,p,u=e(window),l={0:!0,180:!0};if(i.orientation_support){var g=window.innerWidth||u.width(),f=window.innerHeight||u.height(),d=50;h=g>f&&g-f>d,p=l[window.orientation],(h&&p||!h&&!p)&&(l={"-90":!0,90:!0})}e.event.special.orientationchange=s={setup:function(){return i.orientation_support?!1:(r=c(),u.on("throttledresize",t),!0)},teardown:function(){return i.orientation_support?!1:(u.off("throttledresize",t),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=c(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=c=function(){var e=!0,t=document.documentElement;return e=i.orientation_support?l[window.orientation]:t&&t.clientWidth/t.clientHeight<1.1,e?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",x)},teardown:function(){e(this).off("resize",x)}};var v,w,T,_=250,x=function(){w=Date.now(),T=w-y,T>=_?(y=w,e(this).trigger("throttledresize")):(v&&window.clearTimeout(v),v=window.setTimeout(t,_-T))},y=0;e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); +"use strict";!function(e){function t(){var e=c();e!==p&&(p=e,u.trigger("orientationchange"))}function a(t,a,n,o){var i=n.type;n.type=a,e.event.dispatch.call(t,n,o),n.type=i}e.attrFn=e.attrFn||{};var n=navigator.userAgent.toLowerCase(),o=n.indexOf("chrome")>-1&&(n.indexOf("windows")>-1||n.indexOf("macintosh")>-1||n.indexOf("linux")>-1)&&n.indexOf("mobile")<0&&n.indexOf("android")<0,r={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:window.navigator.msPointerEnabled?!1:"ontouchstart"in window&&!o,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:window.navigator.msPointerEnabled?"MSPointerDown":"ontouchstart"in window&&!o?"touchstart":"mousedown",endevent:window.navigator.msPointerEnabled?"MSPointerUp":"ontouchstart"in window&&!o?"touchend":"mouseup",moveevent:window.navigator.msPointerEnabled?"MSPointerMove":"ontouchstart"in window&&!o?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!o?"tap":"click",scrollevent:"ontouchstart"in window&&!o?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.isTouchCapable=function(){return r.touch_capable},e.getStartEvent=function(){return r.startevent},e.getEndEvent=function(){return r.endevent},e.getMoveEvent=function(){return r.moveevent},e.getTapEvent=function(){return r.tapevent},e.getScrollEvent=function(){return r.scrollevent},e.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],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,n=e(t);n.on(r.startevent,function o(e){if(n.data("callee",o),e.which&&1!==e.which)return!1;var s=e.originalEvent,c={position:{x:r.touch_capable?s.touches[0].screenX:e.screenX,y:r.touch_capable?s.touches[0].screenY:e.screenY},offset:{x:Math.round(r.touch_capable?s.changedTouches[i].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(r.touch_capable?s.changedTouches[i].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};return a(t,"tapstart",e,c),!0})},remove:function(){e(this).off(r.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,n=e(t);n.on(r.moveevent,function o(e){n.data("callee",o);var s=e.originalEvent,c={position:{x:r.touch_capable?s.touches[0].screenX:e.screenX,y:r.touch_capable?s.touches[0].screenY:e.screenY},offset:{x:Math.round(r.touch_capable?s.changedTouches[i].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(r.touch_capable?s.changedTouches[i].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};return a(t,"tapmove",e,c),!0})},remove:function(){e(this).off(r.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,n=e(t);n.on(r.endevent,function o(e){n.data("callee",o);var s=e.originalEvent,c={position:{x:r.touch_capable?s.changedTouches[0].screenX:e.screenX,y:r.touch_capable?s.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(r.touch_capable?s.changedTouches[i].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(r.touch_capable?s.changedTouches[i].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};return a(t,"tapend",e,c),!0})},remove:function(){e(this).off(r.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,n=this,o=e(n),s={x:0,y:0},c=0,p=0;o.on(r.startevent,function h(e){if(e.which&&1!==e.which)return!1;o.data("tapheld",!1),t=e.target;var l=e.originalEvent,u=Date.now(),g={x:r.touch_capable?l.touches[0].screenX:e.screenX,y:r.touch_capable?l.touches[0].screenY:e.screenY},d={x:r.touch_capable?l.touches[0].pageX-l.touches[0].target.offsetLeft:e.offsetX,y:r.touch_capable?l.touches[0].pageY-l.touches[0].target.offsetTop:e.offsetY};return s.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,s.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,c=s.x,p=s.y,r.hold_timer=window.setTimeout(function(){var f=s.x-c,v=s.y-p;if(e.target==t&&(s.x==c&&s.y==p||f>=-r.tap_pixel_range&&f<=r.tap_pixel_range&&v>=-r.tap_pixel_range&&v<=r.tap_pixel_range)){o.data("tapheld",!0);var w=Date.now(),_={x:r.touch_capable?l.touches[0].screenX:e.screenX,y:r.touch_capable?l.touches[0].screenY:e.screenY},T={x:Math.round(r.touch_capable?l.changedTouches[i].pageX-o.position().left:e.pageX-o.position().left),y:Math.round(r.touch_capable?l.changedTouches[i].pageY-o.position().top:e.pageY-o.position().top)},x=w-u,y={startTime:u,endTime:w,startPosition:g,startOffset:d,endPosition:_,endOffset:T,duration:x,target:e.target};o.data("callee1",h),a(n,"taphold",e,y)}},r.taphold_threshold),!0}).on(r.endevent,function l(){o.data("callee2",l),o.data("tapheld",!1),window.clearTimeout(r.hold_timer)}).on(r.moveevent,function u(e){o.data("callee3",u),c=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,p=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY})},remove:function(){e(this).off(r.startevent,e(this).data.callee1).off(r.endevent,e(this).data.callee2).off(r.moveevent,e(this).data.callee3)}},e.event.special.doubletap={setup:function(){var t,n,o,s,c=this,p=e(c),h=null,l=!1;p.on(r.startevent,function u(e){return e.which&&1!==e.which?!1:(p.data("doubletapped",!1),t=e.target,p.data("callee1",u),o=e.originalEvent,h||(h={position:{x:r.touch_capable?o.touches[0].screenX:e.screenX,y:r.touch_capable?o.touches[0].screenY:e.screenY},offset:{x:Math.round(r.touch_capable?o.changedTouches[i].pageX-p.position().left:e.pageX-p.position().left),y:Math.round(r.touch_capable?o.changedTouches[i].pageY-p.position().top:e.pageY-p.position().top)},time:Date.now(),target:e.target}),!0)}).on(r.endevent,function g(e){var u=Date.now(),d=p.data("lastTouch")||u+1,f=u-d;if(window.clearTimeout(n),p.data("callee2",g),f100){p.data("doubletapped",!0),window.clearTimeout(r.tap_timer);var v={position:{x:r.touch_capable?e.originalEvent.changedTouches[0].screenX:e.screenX,y:r.touch_capable?e.originalEvent.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(r.touch_capable?o.changedTouches[i].pageX-p.position().left:e.pageX-p.position().left),y:Math.round(r.touch_capable?o.changedTouches[i].pageY-p.position().top:e.pageY-p.position().top)},time:Date.now(),target:e.target},w={firstTap:h,secondTap:v,interval:v.time-h.time};l||(a(c,"doubletap",e,w),h=null),l=!0,s=window.setTimeout(function(){l=!1},r.doubletap_int)}else p.data("lastTouch",u),n=window.setTimeout(function(){h=null,window.clearTimeout(n)},r.doubletap_int,[e]);p.data("lastTouch",u)})},remove:function(){e(this).off(r.startevent,e(this).data.callee1).off(r.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,n=e(t),o=null,s=null,c={x:0,y:0};n.on(r.startevent,function p(e){return e.which&&1!==e.which?!1:(s=Date.now(),o=e.target,n.data("callee1",p),c.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,c.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,!0)}).on(r.endevent,function h(e){if(n.data("callee2",h),e.target==o){var p=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageX:e.pageX,l=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageY:e.pageY;r.tap_timer=window.setTimeout(function(){if(!n.data("doubletapped")&&!n.data("tapheld")&&c.x==p&&c.y==l){var o=e.originalEvent,h={position:{x:r.touch_capable?o.changedTouches[0].screenX:e.screenX,y:r.touch_capable?o.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(r.touch_capable?o.changedTouches[i].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(r.touch_capable?o.changedTouches[i].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};h.time-s=-r.tap_pixel_range&&d<=r.tap_pixel_range&&f>=-r.tap_pixel_range&&f<=r.tap_pixel_range)){for(var v=e.originalEvent,w=[],_=0;_u.y&&l.y-u.y>f&&(n="swipeup"),l.xd&&(n="swiperight"),l.yf&&(n="swipedown"),l.x>u.x&&l.x-u.x>d&&(n="swipeleft"),void 0!=n&&p){l.x=0,l.y=0,u.x=0,u.y=0,p=!1;var v=t.originalEvent,w={position:{x:r.touch_capable?v.touches[0].screenX:t.screenX,y:r.touch_capable?v.touches[0].screenY:t.screenY},offset:{x:Math.round(r.touch_capable?v.changedTouches[i].pageX-c.position().left:t.pageX-c.position().left),y:Math.round(r.touch_capable?v.changedTouches[i].pageY-c.position().top:t.pageY-c.position().top)},time:Date.now(),target:t.target},_=Math.abs(o.position.x-w.position.x),T=Math.abs(o.position.y-w.position.y),x={startEvnt:o,endEvnt:w,direction:n.replace("swipe",""),xAmount:_,yAmount:T,duration:w.time-o.time};h=!0,c.trigger("swipe",x).trigger(n,x)}}function n(t){c=e(t.currentTarget);var a="";if(c.data("callee3",n),h){var s=c.data("xthreshold"),l=c.data("ythreshold"),u="undefined"!=typeof s&&s!==!1&&parseInt(s)?parseInt(s):r.swipe_h_threshold,g="undefined"!=typeof l&&l!==!1&&parseInt(l)?parseInt(l):r.swipe_v_threshold,d=t.originalEvent,f={position:{x:r.touch_capable?d.changedTouches[0].screenX:t.screenX,y:r.touch_capable?d.changedTouches[0].screenY:t.screenY},offset:{x:Math.round(r.touch_capable?d.changedTouches[i].pageX-c.position().left:t.pageX-c.position().left),y:Math.round(r.touch_capable?d.changedTouches[i].pageY-c.position().top:t.pageY-c.position().top)},time:Date.now(),target:t.target};o.position.y>f.position.y&&o.position.y-f.position.y>g&&(a="swipeup"),o.position.xu&&(a="swiperight"),o.position.yg&&(a="swipedown"),o.position.x>f.position.x&&o.position.x-f.position.x>u&&(a="swipeleft");var v=Math.abs(o.position.x-f.position.x),w=Math.abs(o.position.y-f.position.y),_={startEvnt:o,endEvnt:f,direction:a.replace("swipe",""),xAmount:v,yAmount:w,duration:f.time-o.time};c.trigger("swipeend",_)}p=!1,h=!1}var o,s=this,c=e(s),p=!1,h=!1,l={x:0,y:0},u={x:0,y:0};c.on(r.startevent,t),c.on(r.moveevent,a),c.on(r.endevent,n)},remove:function(){e(this).off(r.startevent,e(this).data.callee1).off(r.moveevent,e(this).data.callee2).off(r.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){function t(e,t){n=t,a(i,n?"scrollstart":"scrollend",e)}var n,o,i=this,s=e(i);s.on(r.scrollevent,function c(e){s.data("callee",c),n||t(e,!0),clearTimeout(o),o=setTimeout(function(){t(e,!1)},50)})},remove:function(){e(this).off(r.scrollevent,e(this).data.callee)}};var s,c,p,h,l,u=e(window),g={0:!0,180:!0};if(r.orientation_support){var d=window.innerWidth||u.width(),f=window.innerHeight||u.height(),v=50;h=d>f&&d-f>v,l=g[window.orientation],(h&&l||!h&&!l)&&(g={"-90":!0,90:!0})}e.event.special.orientationchange=s={setup:function(){return r.orientation_support?!1:(p=c(),u.on("throttledresize",t),!0)},teardown:function(){return r.orientation_support?!1:(u.off("throttledresize",t),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=c(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=c=function(){var e=!0,t=document.documentElement;return e=r.orientation_support?g[window.orientation]:t&&t.clientWidth/t.clientHeight<1.1,e?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",y)},teardown:function(){e(this).off("resize",y)}};var w,_,T,x=250,y=function(){_=Date.now(),T=_-m,T>=x?(m=_,e(this).trigger("throttledresize")):(w&&window.clearTimeout(w),w=window.setTimeout(t,x-T))},m=0;e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); From 0ebeffa734a9bde346cc620acbfb0210313e1e89 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Tue, 10 Nov 2015 09:25:37 +0000 Subject: [PATCH 041/149] Fixed typographical errors `hander` => `handler` --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 69fb997..7368e5f 100644 --- a/README.md +++ b/README.md @@ -79,13 +79,13 @@ $('#myElement').trigger('tap'); **Removing the event with ``.off()``, ``.die()`` and ``.unbind()``:** ``` -$('#myElement').off('tap', hander); +$('#myElement').off('tap', handler); ``` ``` -$('#myElement').die('tap', hander); +$('#myElement').die('tap', handler); ``` ``` -$('#myElement').unbind('tap', hander); +$('#myElement').unbind('tap', handler); ``` **Using method wrapper:** From 8813a1970a679c23906a68e69e24709e41f45e20 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Tue, 10 Nov 2015 09:42:41 +0000 Subject: [PATCH 042/149] Updated link to demo site The website link for the demo has now been updated. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7368e5f..267de82 100644 --- a/README.md +++ b/README.md @@ -238,11 +238,11 @@ Returns `touchmove` for touch-enabled devices, or `scroll` for standard environm I have put together a simple demo application that shows the numerous events in action. The console on the left hand side is used to show information about the events that have been called. You can examine the code easily by viewing the page's source to lear more about how this works. Please click on the below to check out the demo: -http://ben-major.co.uk/jquery-mobile-events/ +http://lincweb.co.uk/labs/jquery-touch-events/demo/ Please be aware that this demonstration uses Google's hosted jQuery file, and also pulls the latest version of the events library from GitHub. It is a great place to check the status of the library. Since this demo uses the vanilla code, it is a good idea to check the library functionality here for your own reference. If you're running into problems with the library, please check this demonstration using your device in the first instance. You can scan in the QR below to go directly to the web page: -![Demonstration QR Code](http://qrfree.kaywa.com/?l=1&s=8&d=http%3A%2F%2Fben-major.co.uk%2Fjquery-mobile-events%2F) +![Demonstration QR Code](http://qrfree.kaywa.com/?l=1&s=8&d=http://lincweb.co.uk/labs/jquery-touch-events/demo/) ## 9. Requirements: From 47cf8745797a7ab4e53e22ad57d8c675ba9ccfed Mon Sep 17 00:00:00 2001 From: Ben Major Date: Tue, 10 Nov 2015 09:53:38 +0000 Subject: [PATCH 043/149] Fixed 'i undefined' error --- src/jquery.mobile-events.js | 40 ++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/jquery.mobile-events.js b/src/jquery.mobile-events.js index 48d40be..1c054d8 100644 --- a/src/jquery.mobile-events.js +++ b/src/jquery.mobile-events.js @@ -94,8 +94,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target @@ -127,8 +127,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target @@ -160,8 +160,8 @@ 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target @@ -226,8 +226,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, endOffset = { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }; var duration = end_time - start_time; @@ -295,8 +295,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target @@ -323,8 +323,8 @@ 'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target @@ -406,8 +406,8 @@ 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target @@ -557,8 +557,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target @@ -608,8 +608,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target @@ -650,8 +650,8 @@ 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target From 38ffa439f35acdc76d7ad2d0d180baa50e52a764 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Tue, 10 Nov 2015 09:53:55 +0000 Subject: [PATCH 044/149] Fixed 'i undefined' error --- src/jquery.mobile-events.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jquery.mobile-events.min.js b/src/jquery.mobile-events.min.js index bf1d07e..f5f7c1f 100644 --- a/src/jquery.mobile-events.min.js +++ b/src/jquery.mobile-events.min.js @@ -1 +1 @@ -"use strict";!function(e){function t(){var e=c();e!==p&&(p=e,u.trigger("orientationchange"))}function a(t,a,n,o){var i=n.type;n.type=a,e.event.dispatch.call(t,n,o),n.type=i}e.attrFn=e.attrFn||{};var n=navigator.userAgent.toLowerCase(),o=n.indexOf("chrome")>-1&&(n.indexOf("windows")>-1||n.indexOf("macintosh")>-1||n.indexOf("linux")>-1)&&n.indexOf("mobile")<0&&n.indexOf("android")<0,r={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:window.navigator.msPointerEnabled?!1:"ontouchstart"in window&&!o,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:window.navigator.msPointerEnabled?"MSPointerDown":"ontouchstart"in window&&!o?"touchstart":"mousedown",endevent:window.navigator.msPointerEnabled?"MSPointerUp":"ontouchstart"in window&&!o?"touchend":"mouseup",moveevent:window.navigator.msPointerEnabled?"MSPointerMove":"ontouchstart"in window&&!o?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!o?"tap":"click",scrollevent:"ontouchstart"in window&&!o?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.isTouchCapable=function(){return r.touch_capable},e.getStartEvent=function(){return r.startevent},e.getEndEvent=function(){return r.endevent},e.getMoveEvent=function(){return r.moveevent},e.getTapEvent=function(){return r.tapevent},e.getScrollEvent=function(){return r.scrollevent},e.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],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,n=e(t);n.on(r.startevent,function o(e){if(n.data("callee",o),e.which&&1!==e.which)return!1;var s=e.originalEvent,c={position:{x:r.touch_capable?s.touches[0].screenX:e.screenX,y:r.touch_capable?s.touches[0].screenY:e.screenY},offset:{x:Math.round(r.touch_capable?s.changedTouches[i].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(r.touch_capable?s.changedTouches[i].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};return a(t,"tapstart",e,c),!0})},remove:function(){e(this).off(r.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,n=e(t);n.on(r.moveevent,function o(e){n.data("callee",o);var s=e.originalEvent,c={position:{x:r.touch_capable?s.touches[0].screenX:e.screenX,y:r.touch_capable?s.touches[0].screenY:e.screenY},offset:{x:Math.round(r.touch_capable?s.changedTouches[i].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(r.touch_capable?s.changedTouches[i].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};return a(t,"tapmove",e,c),!0})},remove:function(){e(this).off(r.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,n=e(t);n.on(r.endevent,function o(e){n.data("callee",o);var s=e.originalEvent,c={position:{x:r.touch_capable?s.changedTouches[0].screenX:e.screenX,y:r.touch_capable?s.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(r.touch_capable?s.changedTouches[i].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(r.touch_capable?s.changedTouches[i].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};return a(t,"tapend",e,c),!0})},remove:function(){e(this).off(r.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,n=this,o=e(n),s={x:0,y:0},c=0,p=0;o.on(r.startevent,function h(e){if(e.which&&1!==e.which)return!1;o.data("tapheld",!1),t=e.target;var l=e.originalEvent,u=Date.now(),g={x:r.touch_capable?l.touches[0].screenX:e.screenX,y:r.touch_capable?l.touches[0].screenY:e.screenY},d={x:r.touch_capable?l.touches[0].pageX-l.touches[0].target.offsetLeft:e.offsetX,y:r.touch_capable?l.touches[0].pageY-l.touches[0].target.offsetTop:e.offsetY};return s.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,s.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,c=s.x,p=s.y,r.hold_timer=window.setTimeout(function(){var f=s.x-c,v=s.y-p;if(e.target==t&&(s.x==c&&s.y==p||f>=-r.tap_pixel_range&&f<=r.tap_pixel_range&&v>=-r.tap_pixel_range&&v<=r.tap_pixel_range)){o.data("tapheld",!0);var w=Date.now(),_={x:r.touch_capable?l.touches[0].screenX:e.screenX,y:r.touch_capable?l.touches[0].screenY:e.screenY},T={x:Math.round(r.touch_capable?l.changedTouches[i].pageX-o.position().left:e.pageX-o.position().left),y:Math.round(r.touch_capable?l.changedTouches[i].pageY-o.position().top:e.pageY-o.position().top)},x=w-u,y={startTime:u,endTime:w,startPosition:g,startOffset:d,endPosition:_,endOffset:T,duration:x,target:e.target};o.data("callee1",h),a(n,"taphold",e,y)}},r.taphold_threshold),!0}).on(r.endevent,function l(){o.data("callee2",l),o.data("tapheld",!1),window.clearTimeout(r.hold_timer)}).on(r.moveevent,function u(e){o.data("callee3",u),c=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,p=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY})},remove:function(){e(this).off(r.startevent,e(this).data.callee1).off(r.endevent,e(this).data.callee2).off(r.moveevent,e(this).data.callee3)}},e.event.special.doubletap={setup:function(){var t,n,o,s,c=this,p=e(c),h=null,l=!1;p.on(r.startevent,function u(e){return e.which&&1!==e.which?!1:(p.data("doubletapped",!1),t=e.target,p.data("callee1",u),o=e.originalEvent,h||(h={position:{x:r.touch_capable?o.touches[0].screenX:e.screenX,y:r.touch_capable?o.touches[0].screenY:e.screenY},offset:{x:Math.round(r.touch_capable?o.changedTouches[i].pageX-p.position().left:e.pageX-p.position().left),y:Math.round(r.touch_capable?o.changedTouches[i].pageY-p.position().top:e.pageY-p.position().top)},time:Date.now(),target:e.target}),!0)}).on(r.endevent,function g(e){var u=Date.now(),d=p.data("lastTouch")||u+1,f=u-d;if(window.clearTimeout(n),p.data("callee2",g),f100){p.data("doubletapped",!0),window.clearTimeout(r.tap_timer);var v={position:{x:r.touch_capable?e.originalEvent.changedTouches[0].screenX:e.screenX,y:r.touch_capable?e.originalEvent.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(r.touch_capable?o.changedTouches[i].pageX-p.position().left:e.pageX-p.position().left),y:Math.round(r.touch_capable?o.changedTouches[i].pageY-p.position().top:e.pageY-p.position().top)},time:Date.now(),target:e.target},w={firstTap:h,secondTap:v,interval:v.time-h.time};l||(a(c,"doubletap",e,w),h=null),l=!0,s=window.setTimeout(function(){l=!1},r.doubletap_int)}else p.data("lastTouch",u),n=window.setTimeout(function(){h=null,window.clearTimeout(n)},r.doubletap_int,[e]);p.data("lastTouch",u)})},remove:function(){e(this).off(r.startevent,e(this).data.callee1).off(r.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,n=e(t),o=null,s=null,c={x:0,y:0};n.on(r.startevent,function p(e){return e.which&&1!==e.which?!1:(s=Date.now(),o=e.target,n.data("callee1",p),c.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,c.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,!0)}).on(r.endevent,function h(e){if(n.data("callee2",h),e.target==o){var p=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageX:e.pageX,l=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageY:e.pageY;r.tap_timer=window.setTimeout(function(){if(!n.data("doubletapped")&&!n.data("tapheld")&&c.x==p&&c.y==l){var o=e.originalEvent,h={position:{x:r.touch_capable?o.changedTouches[0].screenX:e.screenX,y:r.touch_capable?o.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(r.touch_capable?o.changedTouches[i].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(r.touch_capable?o.changedTouches[i].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};h.time-s=-r.tap_pixel_range&&d<=r.tap_pixel_range&&f>=-r.tap_pixel_range&&f<=r.tap_pixel_range)){for(var v=e.originalEvent,w=[],_=0;_u.y&&l.y-u.y>f&&(n="swipeup"),l.xd&&(n="swiperight"),l.yf&&(n="swipedown"),l.x>u.x&&l.x-u.x>d&&(n="swipeleft"),void 0!=n&&p){l.x=0,l.y=0,u.x=0,u.y=0,p=!1;var v=t.originalEvent,w={position:{x:r.touch_capable?v.touches[0].screenX:t.screenX,y:r.touch_capable?v.touches[0].screenY:t.screenY},offset:{x:Math.round(r.touch_capable?v.changedTouches[i].pageX-c.position().left:t.pageX-c.position().left),y:Math.round(r.touch_capable?v.changedTouches[i].pageY-c.position().top:t.pageY-c.position().top)},time:Date.now(),target:t.target},_=Math.abs(o.position.x-w.position.x),T=Math.abs(o.position.y-w.position.y),x={startEvnt:o,endEvnt:w,direction:n.replace("swipe",""),xAmount:_,yAmount:T,duration:w.time-o.time};h=!0,c.trigger("swipe",x).trigger(n,x)}}function n(t){c=e(t.currentTarget);var a="";if(c.data("callee3",n),h){var s=c.data("xthreshold"),l=c.data("ythreshold"),u="undefined"!=typeof s&&s!==!1&&parseInt(s)?parseInt(s):r.swipe_h_threshold,g="undefined"!=typeof l&&l!==!1&&parseInt(l)?parseInt(l):r.swipe_v_threshold,d=t.originalEvent,f={position:{x:r.touch_capable?d.changedTouches[0].screenX:t.screenX,y:r.touch_capable?d.changedTouches[0].screenY:t.screenY},offset:{x:Math.round(r.touch_capable?d.changedTouches[i].pageX-c.position().left:t.pageX-c.position().left),y:Math.round(r.touch_capable?d.changedTouches[i].pageY-c.position().top:t.pageY-c.position().top)},time:Date.now(),target:t.target};o.position.y>f.position.y&&o.position.y-f.position.y>g&&(a="swipeup"),o.position.xu&&(a="swiperight"),o.position.yg&&(a="swipedown"),o.position.x>f.position.x&&o.position.x-f.position.x>u&&(a="swipeleft");var v=Math.abs(o.position.x-f.position.x),w=Math.abs(o.position.y-f.position.y),_={startEvnt:o,endEvnt:f,direction:a.replace("swipe",""),xAmount:v,yAmount:w,duration:f.time-o.time};c.trigger("swipeend",_)}p=!1,h=!1}var o,s=this,c=e(s),p=!1,h=!1,l={x:0,y:0},u={x:0,y:0};c.on(r.startevent,t),c.on(r.moveevent,a),c.on(r.endevent,n)},remove:function(){e(this).off(r.startevent,e(this).data.callee1).off(r.moveevent,e(this).data.callee2).off(r.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){function t(e,t){n=t,a(i,n?"scrollstart":"scrollend",e)}var n,o,i=this,s=e(i);s.on(r.scrollevent,function c(e){s.data("callee",c),n||t(e,!0),clearTimeout(o),o=setTimeout(function(){t(e,!1)},50)})},remove:function(){e(this).off(r.scrollevent,e(this).data.callee)}};var s,c,p,h,l,u=e(window),g={0:!0,180:!0};if(r.orientation_support){var d=window.innerWidth||u.width(),f=window.innerHeight||u.height(),v=50;h=d>f&&d-f>v,l=g[window.orientation],(h&&l||!h&&!l)&&(g={"-90":!0,90:!0})}e.event.special.orientationchange=s={setup:function(){return r.orientation_support?!1:(p=c(),u.on("throttledresize",t),!0)},teardown:function(){return r.orientation_support?!1:(u.off("throttledresize",t),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=c(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=c=function(){var e=!0,t=document.documentElement;return e=r.orientation_support?g[window.orientation]:t&&t.clientWidth/t.clientHeight<1.1,e?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",y)},teardown:function(){e(this).off("resize",y)}};var w,_,T,x=250,y=function(){_=Date.now(),T=_-m,T>=x?(m=_,e(this).trigger("throttledresize")):(w&&window.clearTimeout(w),w=window.setTimeout(t,x-T))},m=0;e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); +"use strict";!function(e){function t(){var e=s();e!==c&&(c=e,l.trigger("orientationchange"))}function a(t,a,n,o){var i=n.type;n.type=a,e.event.dispatch.call(t,n,o),n.type=i}e.attrFn=e.attrFn||{};var n=navigator.userAgent.toLowerCase(),o=n.indexOf("chrome")>-1&&(n.indexOf("windows")>-1||n.indexOf("macintosh")>-1||n.indexOf("linux")>-1)&&n.indexOf("mobile")<0&&n.indexOf("android")<0,i={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:window.navigator.msPointerEnabled?!1:"ontouchstart"in window&&!o,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:window.navigator.msPointerEnabled?"MSPointerDown":"ontouchstart"in window&&!o?"touchstart":"mousedown",endevent:window.navigator.msPointerEnabled?"MSPointerUp":"ontouchstart"in window&&!o?"touchend":"mouseup",moveevent:window.navigator.msPointerEnabled?"MSPointerMove":"ontouchstart"in window&&!o?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!o?"tap":"click",scrollevent:"ontouchstart"in window&&!o?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.isTouchCapable=function(){return i.touch_capable},e.getStartEvent=function(){return i.startevent},e.getEndEvent=function(){return i.endevent},e.getMoveEvent=function(){return i.moveevent},e.getTapEvent=function(){return i.tapevent},e.getScrollEvent=function(){return i.scrollevent},e.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],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,n=e(t);n.on(i.startevent,function o(e){if(n.data("callee",o),e.which&&1!==e.which)return!1;var r=e.originalEvent,s={position:{x:i.touch_capable?r.touches[0].screenX:e.screenX,y:i.touch_capable?r.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?r.changedTouches[0].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(i.touch_capable?r.changedTouches[0].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};return a(t,"tapstart",e,s),!0})},remove:function(){e(this).off(i.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,n=e(t);n.on(i.moveevent,function o(e){n.data("callee",o);var r=e.originalEvent,s={position:{x:i.touch_capable?r.touches[0].screenX:e.screenX,y:i.touch_capable?r.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?r.changedTouches[0].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(i.touch_capable?r.changedTouches[0].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};return a(t,"tapmove",e,s),!0})},remove:function(){e(this).off(i.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,n=e(t);n.on(i.endevent,function o(e){n.data("callee",o);var r=e.originalEvent,s={position:{x:i.touch_capable?r.changedTouches[0].screenX:e.screenX,y:i.touch_capable?r.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?r.changedTouches[0].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(i.touch_capable?r.changedTouches[0].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};return a(t,"tapend",e,s),!0})},remove:function(){e(this).off(i.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,n=this,o=e(n),r={x:0,y:0},s=0,c=0;o.on(i.startevent,function p(e){if(e.which&&1!==e.which)return!1;o.data("tapheld",!1),t=e.target;var h=e.originalEvent,l=Date.now(),u={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},g={x:i.touch_capable?h.touches[0].pageX-h.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?h.touches[0].pageY-h.touches[0].target.offsetTop:e.offsetY};return r.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,r.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,s=r.x,c=r.y,i.hold_timer=window.setTimeout(function(){var d=r.x-s,f=r.y-c;if(e.target==t&&(r.x==s&&r.y==c||d>=-i.tap_pixel_range&&d<=i.tap_pixel_range&&f>=-i.tap_pixel_range&&f<=i.tap_pixel_range)){o.data("tapheld",!0);var v=Date.now(),w={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},_={x:Math.round(i.touch_capable?h.changedTouches[0].pageX-o.position().left:e.pageX-o.position().left),y:Math.round(i.touch_capable?h.changedTouches[0].pageY-o.position().top:e.pageY-o.position().top)},T=v-l,x={startTime:l,endTime:v,startPosition:u,startOffset:g,endPosition:w,endOffset:_,duration:T,target:e.target};o.data("callee1",p),a(n,"taphold",e,x)}},i.taphold_threshold),!0}).on(i.endevent,function h(){o.data("callee2",h),o.data("tapheld",!1),window.clearTimeout(i.hold_timer)}).on(i.moveevent,function l(e){o.data("callee3",l),s=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,c=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2).off(i.moveevent,e(this).data.callee3)}},e.event.special.doubletap={setup:function(){var t,n,o,r,s=this,c=e(s),p=null,h=!1;c.on(i.startevent,function l(e){return e.which&&1!==e.which?!1:(c.data("doubletapped",!1),t=e.target,c.data("callee1",l),o=e.originalEvent,p||(p={position:{x:i.touch_capable?o.touches[0].screenX:e.screenX,y:i.touch_capable?o.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?o.changedTouches[0].pageX-c.position().left:e.pageX-c.position().left),y:Math.round(i.touch_capable?o.changedTouches[0].pageY-c.position().top:e.pageY-c.position().top)},time:Date.now(),target:e.target}),!0)}).on(i.endevent,function u(e){var l=Date.now(),g=c.data("lastTouch")||l+1,d=l-g;if(window.clearTimeout(n),c.data("callee2",u),d100){c.data("doubletapped",!0),window.clearTimeout(i.tap_timer);var f={position:{x:i.touch_capable?e.originalEvent.changedTouches[0].screenX:e.screenX,y:i.touch_capable?e.originalEvent.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?o.changedTouches[0].pageX-c.position().left:e.pageX-c.position().left),y:Math.round(i.touch_capable?o.changedTouches[0].pageY-c.position().top:e.pageY-c.position().top)},time:Date.now(),target:e.target},v={firstTap:p,secondTap:f,interval:f.time-p.time};h||(a(s,"doubletap",e,v),p=null),h=!0,r=window.setTimeout(function(){h=!1},i.doubletap_int)}else c.data("lastTouch",l),n=window.setTimeout(function(){p=null,window.clearTimeout(n)},i.doubletap_int,[e]);c.data("lastTouch",l)})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,n=e(t),o=null,r=null,s={x:0,y:0};n.on(i.startevent,function c(e){return e.which&&1!==e.which?!1:(r=Date.now(),o=e.target,n.data("callee1",c),s.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,s.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,!0)}).on(i.endevent,function p(e){if(n.data("callee2",p),e.target==o){var c=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageX:e.pageX,h=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageY:e.pageY;i.tap_timer=window.setTimeout(function(){if(!n.data("doubletapped")&&!n.data("tapheld")&&s.x==c&&s.y==h){var o=e.originalEvent,p={position:{x:i.touch_capable?o.changedTouches[0].screenX:e.screenX,y:i.touch_capable?o.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?o.changedTouches[0].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(i.touch_capable?o.changedTouches[0].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};p.time-r=-i.tap_pixel_range&&d<=i.tap_pixel_range&&f>=-i.tap_pixel_range&&f<=i.tap_pixel_range)){for(var v=e.originalEvent,w=[],_=0;_l.y&&h.y-l.y>d&&(n="swipeup"),h.xg&&(n="swiperight"),h.yd&&(n="swipedown"),h.x>l.x&&h.x-l.x>g&&(n="swipeleft"),void 0!=n&&c){h.x=0,h.y=0,l.x=0,l.y=0,c=!1;var f=t.originalEvent,v={position:{x:i.touch_capable?f.touches[0].screenX:t.screenX,y:i.touch_capable?f.touches[0].screenY:t.screenY},offset:{x:Math.round(i.touch_capable?f.changedTouches[0].pageX-s.position().left:t.pageX-s.position().left),y:Math.round(i.touch_capable?f.changedTouches[0].pageY-s.position().top:t.pageY-s.position().top)},time:Date.now(),target:t.target},w=Math.abs(o.position.x-v.position.x),_=Math.abs(o.position.y-v.position.y),T={startEvnt:o,endEvnt:v,direction:n.replace("swipe",""),xAmount:w,yAmount:_,duration:v.time-o.time};p=!0,s.trigger("swipe",T).trigger(n,T)}}function n(t){s=e(t.currentTarget);var a="";if(s.data("callee3",n),p){var r=s.data("xthreshold"),h=s.data("ythreshold"),l="undefined"!=typeof r&&r!==!1&&parseInt(r)?parseInt(r):i.swipe_h_threshold,u="undefined"!=typeof h&&h!==!1&&parseInt(h)?parseInt(h):i.swipe_v_threshold,g=t.originalEvent,d={position:{x:i.touch_capable?g.changedTouches[0].screenX:t.screenX,y:i.touch_capable?g.changedTouches[0].screenY:t.screenY},offset:{x:Math.round(i.touch_capable?g.changedTouches[0].pageX-s.position().left:t.pageX-s.position().left),y:Math.round(i.touch_capable?g.changedTouches[0].pageY-s.position().top:t.pageY-s.position().top)},time:Date.now(),target:t.target};o.position.y>d.position.y&&o.position.y-d.position.y>u&&(a="swipeup"),o.position.xl&&(a="swiperight"),o.position.yu&&(a="swipedown"),o.position.x>d.position.x&&o.position.x-d.position.x>l&&(a="swipeleft");var f=Math.abs(o.position.x-d.position.x),v=Math.abs(o.position.y-d.position.y),w={startEvnt:o,endEvnt:d,direction:a.replace("swipe",""),xAmount:f,yAmount:v,duration:d.time-o.time};s.trigger("swipeend",w)}c=!1,p=!1}var o,r=this,s=e(r),c=!1,p=!1,h={x:0,y:0},l={x:0,y:0};s.on(i.startevent,t),s.on(i.moveevent,a),s.on(i.endevent,n)},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.moveevent,e(this).data.callee2).off(i.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){function t(e,t){n=t,a(r,n?"scrollstart":"scrollend",e)}var n,o,r=this,s=e(r);s.on(i.scrollevent,function c(e){s.data("callee",c),n||t(e,!0),clearTimeout(o),o=setTimeout(function(){t(e,!1)},50)})},remove:function(){e(this).off(i.scrollevent,e(this).data.callee)}};var r,s,c,p,h,l=e(window),u={0:!0,180:!0};if(i.orientation_support){var g=window.innerWidth||l.width(),d=window.innerHeight||l.height(),f=50;p=g>d&&g-d>f,h=u[window.orientation],(p&&h||!p&&!h)&&(u={"-90":!0,90:!0})}e.event.special.orientationchange=r={setup:function(){return i.orientation_support?!1:(c=s(),l.on("throttledresize",t),!0)},teardown:function(){return i.orientation_support?!1:(l.off("throttledresize",t),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=s(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=s=function(){var e=!0,t=document.documentElement;return e=i.orientation_support?u[window.orientation]:t&&t.clientWidth/t.clientHeight<1.1,e?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",x)},teardown:function(){e(this).off("resize",x)}};var v,w,_,T=250,x=function(){w=Date.now(),_=w-y,_>=T?(y=w,e(this).trigger("throttledresize")):(v&&window.clearTimeout(v),v=window.setTimeout(t,T-_))},y=0;e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); From 5a30075af9980fc7b7f8d9c483decba71d759726 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Tue, 10 Nov 2015 09:55:02 +0000 Subject: [PATCH 045/149] Fixed 'i undefined' error --- src/1.0.3/jquery.mobile-events.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/1.0.3/jquery.mobile-events.min.js b/src/1.0.3/jquery.mobile-events.min.js index bf1d07e..f5f7c1f 100644 --- a/src/1.0.3/jquery.mobile-events.min.js +++ b/src/1.0.3/jquery.mobile-events.min.js @@ -1 +1 @@ -"use strict";!function(e){function t(){var e=c();e!==p&&(p=e,u.trigger("orientationchange"))}function a(t,a,n,o){var i=n.type;n.type=a,e.event.dispatch.call(t,n,o),n.type=i}e.attrFn=e.attrFn||{};var n=navigator.userAgent.toLowerCase(),o=n.indexOf("chrome")>-1&&(n.indexOf("windows")>-1||n.indexOf("macintosh")>-1||n.indexOf("linux")>-1)&&n.indexOf("mobile")<0&&n.indexOf("android")<0,r={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:window.navigator.msPointerEnabled?!1:"ontouchstart"in window&&!o,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:window.navigator.msPointerEnabled?"MSPointerDown":"ontouchstart"in window&&!o?"touchstart":"mousedown",endevent:window.navigator.msPointerEnabled?"MSPointerUp":"ontouchstart"in window&&!o?"touchend":"mouseup",moveevent:window.navigator.msPointerEnabled?"MSPointerMove":"ontouchstart"in window&&!o?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!o?"tap":"click",scrollevent:"ontouchstart"in window&&!o?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.isTouchCapable=function(){return r.touch_capable},e.getStartEvent=function(){return r.startevent},e.getEndEvent=function(){return r.endevent},e.getMoveEvent=function(){return r.moveevent},e.getTapEvent=function(){return r.tapevent},e.getScrollEvent=function(){return r.scrollevent},e.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],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,n=e(t);n.on(r.startevent,function o(e){if(n.data("callee",o),e.which&&1!==e.which)return!1;var s=e.originalEvent,c={position:{x:r.touch_capable?s.touches[0].screenX:e.screenX,y:r.touch_capable?s.touches[0].screenY:e.screenY},offset:{x:Math.round(r.touch_capable?s.changedTouches[i].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(r.touch_capable?s.changedTouches[i].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};return a(t,"tapstart",e,c),!0})},remove:function(){e(this).off(r.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,n=e(t);n.on(r.moveevent,function o(e){n.data("callee",o);var s=e.originalEvent,c={position:{x:r.touch_capable?s.touches[0].screenX:e.screenX,y:r.touch_capable?s.touches[0].screenY:e.screenY},offset:{x:Math.round(r.touch_capable?s.changedTouches[i].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(r.touch_capable?s.changedTouches[i].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};return a(t,"tapmove",e,c),!0})},remove:function(){e(this).off(r.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,n=e(t);n.on(r.endevent,function o(e){n.data("callee",o);var s=e.originalEvent,c={position:{x:r.touch_capable?s.changedTouches[0].screenX:e.screenX,y:r.touch_capable?s.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(r.touch_capable?s.changedTouches[i].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(r.touch_capable?s.changedTouches[i].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};return a(t,"tapend",e,c),!0})},remove:function(){e(this).off(r.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,n=this,o=e(n),s={x:0,y:0},c=0,p=0;o.on(r.startevent,function h(e){if(e.which&&1!==e.which)return!1;o.data("tapheld",!1),t=e.target;var l=e.originalEvent,u=Date.now(),g={x:r.touch_capable?l.touches[0].screenX:e.screenX,y:r.touch_capable?l.touches[0].screenY:e.screenY},d={x:r.touch_capable?l.touches[0].pageX-l.touches[0].target.offsetLeft:e.offsetX,y:r.touch_capable?l.touches[0].pageY-l.touches[0].target.offsetTop:e.offsetY};return s.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,s.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,c=s.x,p=s.y,r.hold_timer=window.setTimeout(function(){var f=s.x-c,v=s.y-p;if(e.target==t&&(s.x==c&&s.y==p||f>=-r.tap_pixel_range&&f<=r.tap_pixel_range&&v>=-r.tap_pixel_range&&v<=r.tap_pixel_range)){o.data("tapheld",!0);var w=Date.now(),_={x:r.touch_capable?l.touches[0].screenX:e.screenX,y:r.touch_capable?l.touches[0].screenY:e.screenY},T={x:Math.round(r.touch_capable?l.changedTouches[i].pageX-o.position().left:e.pageX-o.position().left),y:Math.round(r.touch_capable?l.changedTouches[i].pageY-o.position().top:e.pageY-o.position().top)},x=w-u,y={startTime:u,endTime:w,startPosition:g,startOffset:d,endPosition:_,endOffset:T,duration:x,target:e.target};o.data("callee1",h),a(n,"taphold",e,y)}},r.taphold_threshold),!0}).on(r.endevent,function l(){o.data("callee2",l),o.data("tapheld",!1),window.clearTimeout(r.hold_timer)}).on(r.moveevent,function u(e){o.data("callee3",u),c=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,p=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY})},remove:function(){e(this).off(r.startevent,e(this).data.callee1).off(r.endevent,e(this).data.callee2).off(r.moveevent,e(this).data.callee3)}},e.event.special.doubletap={setup:function(){var t,n,o,s,c=this,p=e(c),h=null,l=!1;p.on(r.startevent,function u(e){return e.which&&1!==e.which?!1:(p.data("doubletapped",!1),t=e.target,p.data("callee1",u),o=e.originalEvent,h||(h={position:{x:r.touch_capable?o.touches[0].screenX:e.screenX,y:r.touch_capable?o.touches[0].screenY:e.screenY},offset:{x:Math.round(r.touch_capable?o.changedTouches[i].pageX-p.position().left:e.pageX-p.position().left),y:Math.round(r.touch_capable?o.changedTouches[i].pageY-p.position().top:e.pageY-p.position().top)},time:Date.now(),target:e.target}),!0)}).on(r.endevent,function g(e){var u=Date.now(),d=p.data("lastTouch")||u+1,f=u-d;if(window.clearTimeout(n),p.data("callee2",g),f100){p.data("doubletapped",!0),window.clearTimeout(r.tap_timer);var v={position:{x:r.touch_capable?e.originalEvent.changedTouches[0].screenX:e.screenX,y:r.touch_capable?e.originalEvent.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(r.touch_capable?o.changedTouches[i].pageX-p.position().left:e.pageX-p.position().left),y:Math.round(r.touch_capable?o.changedTouches[i].pageY-p.position().top:e.pageY-p.position().top)},time:Date.now(),target:e.target},w={firstTap:h,secondTap:v,interval:v.time-h.time};l||(a(c,"doubletap",e,w),h=null),l=!0,s=window.setTimeout(function(){l=!1},r.doubletap_int)}else p.data("lastTouch",u),n=window.setTimeout(function(){h=null,window.clearTimeout(n)},r.doubletap_int,[e]);p.data("lastTouch",u)})},remove:function(){e(this).off(r.startevent,e(this).data.callee1).off(r.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,n=e(t),o=null,s=null,c={x:0,y:0};n.on(r.startevent,function p(e){return e.which&&1!==e.which?!1:(s=Date.now(),o=e.target,n.data("callee1",p),c.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,c.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,!0)}).on(r.endevent,function h(e){if(n.data("callee2",h),e.target==o){var p=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageX:e.pageX,l=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageY:e.pageY;r.tap_timer=window.setTimeout(function(){if(!n.data("doubletapped")&&!n.data("tapheld")&&c.x==p&&c.y==l){var o=e.originalEvent,h={position:{x:r.touch_capable?o.changedTouches[0].screenX:e.screenX,y:r.touch_capable?o.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(r.touch_capable?o.changedTouches[i].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(r.touch_capable?o.changedTouches[i].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};h.time-s=-r.tap_pixel_range&&d<=r.tap_pixel_range&&f>=-r.tap_pixel_range&&f<=r.tap_pixel_range)){for(var v=e.originalEvent,w=[],_=0;_u.y&&l.y-u.y>f&&(n="swipeup"),l.xd&&(n="swiperight"),l.yf&&(n="swipedown"),l.x>u.x&&l.x-u.x>d&&(n="swipeleft"),void 0!=n&&p){l.x=0,l.y=0,u.x=0,u.y=0,p=!1;var v=t.originalEvent,w={position:{x:r.touch_capable?v.touches[0].screenX:t.screenX,y:r.touch_capable?v.touches[0].screenY:t.screenY},offset:{x:Math.round(r.touch_capable?v.changedTouches[i].pageX-c.position().left:t.pageX-c.position().left),y:Math.round(r.touch_capable?v.changedTouches[i].pageY-c.position().top:t.pageY-c.position().top)},time:Date.now(),target:t.target},_=Math.abs(o.position.x-w.position.x),T=Math.abs(o.position.y-w.position.y),x={startEvnt:o,endEvnt:w,direction:n.replace("swipe",""),xAmount:_,yAmount:T,duration:w.time-o.time};h=!0,c.trigger("swipe",x).trigger(n,x)}}function n(t){c=e(t.currentTarget);var a="";if(c.data("callee3",n),h){var s=c.data("xthreshold"),l=c.data("ythreshold"),u="undefined"!=typeof s&&s!==!1&&parseInt(s)?parseInt(s):r.swipe_h_threshold,g="undefined"!=typeof l&&l!==!1&&parseInt(l)?parseInt(l):r.swipe_v_threshold,d=t.originalEvent,f={position:{x:r.touch_capable?d.changedTouches[0].screenX:t.screenX,y:r.touch_capable?d.changedTouches[0].screenY:t.screenY},offset:{x:Math.round(r.touch_capable?d.changedTouches[i].pageX-c.position().left:t.pageX-c.position().left),y:Math.round(r.touch_capable?d.changedTouches[i].pageY-c.position().top:t.pageY-c.position().top)},time:Date.now(),target:t.target};o.position.y>f.position.y&&o.position.y-f.position.y>g&&(a="swipeup"),o.position.xu&&(a="swiperight"),o.position.yg&&(a="swipedown"),o.position.x>f.position.x&&o.position.x-f.position.x>u&&(a="swipeleft");var v=Math.abs(o.position.x-f.position.x),w=Math.abs(o.position.y-f.position.y),_={startEvnt:o,endEvnt:f,direction:a.replace("swipe",""),xAmount:v,yAmount:w,duration:f.time-o.time};c.trigger("swipeend",_)}p=!1,h=!1}var o,s=this,c=e(s),p=!1,h=!1,l={x:0,y:0},u={x:0,y:0};c.on(r.startevent,t),c.on(r.moveevent,a),c.on(r.endevent,n)},remove:function(){e(this).off(r.startevent,e(this).data.callee1).off(r.moveevent,e(this).data.callee2).off(r.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){function t(e,t){n=t,a(i,n?"scrollstart":"scrollend",e)}var n,o,i=this,s=e(i);s.on(r.scrollevent,function c(e){s.data("callee",c),n||t(e,!0),clearTimeout(o),o=setTimeout(function(){t(e,!1)},50)})},remove:function(){e(this).off(r.scrollevent,e(this).data.callee)}};var s,c,p,h,l,u=e(window),g={0:!0,180:!0};if(r.orientation_support){var d=window.innerWidth||u.width(),f=window.innerHeight||u.height(),v=50;h=d>f&&d-f>v,l=g[window.orientation],(h&&l||!h&&!l)&&(g={"-90":!0,90:!0})}e.event.special.orientationchange=s={setup:function(){return r.orientation_support?!1:(p=c(),u.on("throttledresize",t),!0)},teardown:function(){return r.orientation_support?!1:(u.off("throttledresize",t),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=c(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=c=function(){var e=!0,t=document.documentElement;return e=r.orientation_support?g[window.orientation]:t&&t.clientWidth/t.clientHeight<1.1,e?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",y)},teardown:function(){e(this).off("resize",y)}};var w,_,T,x=250,y=function(){_=Date.now(),T=_-m,T>=x?(m=_,e(this).trigger("throttledresize")):(w&&window.clearTimeout(w),w=window.setTimeout(t,x-T))},m=0;e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); +"use strict";!function(e){function t(){var e=s();e!==c&&(c=e,l.trigger("orientationchange"))}function a(t,a,n,o){var i=n.type;n.type=a,e.event.dispatch.call(t,n,o),n.type=i}e.attrFn=e.attrFn||{};var n=navigator.userAgent.toLowerCase(),o=n.indexOf("chrome")>-1&&(n.indexOf("windows")>-1||n.indexOf("macintosh")>-1||n.indexOf("linux")>-1)&&n.indexOf("mobile")<0&&n.indexOf("android")<0,i={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:window.navigator.msPointerEnabled?!1:"ontouchstart"in window&&!o,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:window.navigator.msPointerEnabled?"MSPointerDown":"ontouchstart"in window&&!o?"touchstart":"mousedown",endevent:window.navigator.msPointerEnabled?"MSPointerUp":"ontouchstart"in window&&!o?"touchend":"mouseup",moveevent:window.navigator.msPointerEnabled?"MSPointerMove":"ontouchstart"in window&&!o?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!o?"tap":"click",scrollevent:"ontouchstart"in window&&!o?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.isTouchCapable=function(){return i.touch_capable},e.getStartEvent=function(){return i.startevent},e.getEndEvent=function(){return i.endevent},e.getMoveEvent=function(){return i.moveevent},e.getTapEvent=function(){return i.tapevent},e.getScrollEvent=function(){return i.scrollevent},e.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],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,n=e(t);n.on(i.startevent,function o(e){if(n.data("callee",o),e.which&&1!==e.which)return!1;var r=e.originalEvent,s={position:{x:i.touch_capable?r.touches[0].screenX:e.screenX,y:i.touch_capable?r.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?r.changedTouches[0].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(i.touch_capable?r.changedTouches[0].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};return a(t,"tapstart",e,s),!0})},remove:function(){e(this).off(i.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,n=e(t);n.on(i.moveevent,function o(e){n.data("callee",o);var r=e.originalEvent,s={position:{x:i.touch_capable?r.touches[0].screenX:e.screenX,y:i.touch_capable?r.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?r.changedTouches[0].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(i.touch_capable?r.changedTouches[0].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};return a(t,"tapmove",e,s),!0})},remove:function(){e(this).off(i.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,n=e(t);n.on(i.endevent,function o(e){n.data("callee",o);var r=e.originalEvent,s={position:{x:i.touch_capable?r.changedTouches[0].screenX:e.screenX,y:i.touch_capable?r.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?r.changedTouches[0].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(i.touch_capable?r.changedTouches[0].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};return a(t,"tapend",e,s),!0})},remove:function(){e(this).off(i.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,n=this,o=e(n),r={x:0,y:0},s=0,c=0;o.on(i.startevent,function p(e){if(e.which&&1!==e.which)return!1;o.data("tapheld",!1),t=e.target;var h=e.originalEvent,l=Date.now(),u={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},g={x:i.touch_capable?h.touches[0].pageX-h.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?h.touches[0].pageY-h.touches[0].target.offsetTop:e.offsetY};return r.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,r.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,s=r.x,c=r.y,i.hold_timer=window.setTimeout(function(){var d=r.x-s,f=r.y-c;if(e.target==t&&(r.x==s&&r.y==c||d>=-i.tap_pixel_range&&d<=i.tap_pixel_range&&f>=-i.tap_pixel_range&&f<=i.tap_pixel_range)){o.data("tapheld",!0);var v=Date.now(),w={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},_={x:Math.round(i.touch_capable?h.changedTouches[0].pageX-o.position().left:e.pageX-o.position().left),y:Math.round(i.touch_capable?h.changedTouches[0].pageY-o.position().top:e.pageY-o.position().top)},T=v-l,x={startTime:l,endTime:v,startPosition:u,startOffset:g,endPosition:w,endOffset:_,duration:T,target:e.target};o.data("callee1",p),a(n,"taphold",e,x)}},i.taphold_threshold),!0}).on(i.endevent,function h(){o.data("callee2",h),o.data("tapheld",!1),window.clearTimeout(i.hold_timer)}).on(i.moveevent,function l(e){o.data("callee3",l),s=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,c=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2).off(i.moveevent,e(this).data.callee3)}},e.event.special.doubletap={setup:function(){var t,n,o,r,s=this,c=e(s),p=null,h=!1;c.on(i.startevent,function l(e){return e.which&&1!==e.which?!1:(c.data("doubletapped",!1),t=e.target,c.data("callee1",l),o=e.originalEvent,p||(p={position:{x:i.touch_capable?o.touches[0].screenX:e.screenX,y:i.touch_capable?o.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?o.changedTouches[0].pageX-c.position().left:e.pageX-c.position().left),y:Math.round(i.touch_capable?o.changedTouches[0].pageY-c.position().top:e.pageY-c.position().top)},time:Date.now(),target:e.target}),!0)}).on(i.endevent,function u(e){var l=Date.now(),g=c.data("lastTouch")||l+1,d=l-g;if(window.clearTimeout(n),c.data("callee2",u),d100){c.data("doubletapped",!0),window.clearTimeout(i.tap_timer);var f={position:{x:i.touch_capable?e.originalEvent.changedTouches[0].screenX:e.screenX,y:i.touch_capable?e.originalEvent.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?o.changedTouches[0].pageX-c.position().left:e.pageX-c.position().left),y:Math.round(i.touch_capable?o.changedTouches[0].pageY-c.position().top:e.pageY-c.position().top)},time:Date.now(),target:e.target},v={firstTap:p,secondTap:f,interval:f.time-p.time};h||(a(s,"doubletap",e,v),p=null),h=!0,r=window.setTimeout(function(){h=!1},i.doubletap_int)}else c.data("lastTouch",l),n=window.setTimeout(function(){p=null,window.clearTimeout(n)},i.doubletap_int,[e]);c.data("lastTouch",l)})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,n=e(t),o=null,r=null,s={x:0,y:0};n.on(i.startevent,function c(e){return e.which&&1!==e.which?!1:(r=Date.now(),o=e.target,n.data("callee1",c),s.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,s.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,!0)}).on(i.endevent,function p(e){if(n.data("callee2",p),e.target==o){var c=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageX:e.pageX,h=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageY:e.pageY;i.tap_timer=window.setTimeout(function(){if(!n.data("doubletapped")&&!n.data("tapheld")&&s.x==c&&s.y==h){var o=e.originalEvent,p={position:{x:i.touch_capable?o.changedTouches[0].screenX:e.screenX,y:i.touch_capable?o.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?o.changedTouches[0].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(i.touch_capable?o.changedTouches[0].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};p.time-r=-i.tap_pixel_range&&d<=i.tap_pixel_range&&f>=-i.tap_pixel_range&&f<=i.tap_pixel_range)){for(var v=e.originalEvent,w=[],_=0;_l.y&&h.y-l.y>d&&(n="swipeup"),h.xg&&(n="swiperight"),h.yd&&(n="swipedown"),h.x>l.x&&h.x-l.x>g&&(n="swipeleft"),void 0!=n&&c){h.x=0,h.y=0,l.x=0,l.y=0,c=!1;var f=t.originalEvent,v={position:{x:i.touch_capable?f.touches[0].screenX:t.screenX,y:i.touch_capable?f.touches[0].screenY:t.screenY},offset:{x:Math.round(i.touch_capable?f.changedTouches[0].pageX-s.position().left:t.pageX-s.position().left),y:Math.round(i.touch_capable?f.changedTouches[0].pageY-s.position().top:t.pageY-s.position().top)},time:Date.now(),target:t.target},w=Math.abs(o.position.x-v.position.x),_=Math.abs(o.position.y-v.position.y),T={startEvnt:o,endEvnt:v,direction:n.replace("swipe",""),xAmount:w,yAmount:_,duration:v.time-o.time};p=!0,s.trigger("swipe",T).trigger(n,T)}}function n(t){s=e(t.currentTarget);var a="";if(s.data("callee3",n),p){var r=s.data("xthreshold"),h=s.data("ythreshold"),l="undefined"!=typeof r&&r!==!1&&parseInt(r)?parseInt(r):i.swipe_h_threshold,u="undefined"!=typeof h&&h!==!1&&parseInt(h)?parseInt(h):i.swipe_v_threshold,g=t.originalEvent,d={position:{x:i.touch_capable?g.changedTouches[0].screenX:t.screenX,y:i.touch_capable?g.changedTouches[0].screenY:t.screenY},offset:{x:Math.round(i.touch_capable?g.changedTouches[0].pageX-s.position().left:t.pageX-s.position().left),y:Math.round(i.touch_capable?g.changedTouches[0].pageY-s.position().top:t.pageY-s.position().top)},time:Date.now(),target:t.target};o.position.y>d.position.y&&o.position.y-d.position.y>u&&(a="swipeup"),o.position.xl&&(a="swiperight"),o.position.yu&&(a="swipedown"),o.position.x>d.position.x&&o.position.x-d.position.x>l&&(a="swipeleft");var f=Math.abs(o.position.x-d.position.x),v=Math.abs(o.position.y-d.position.y),w={startEvnt:o,endEvnt:d,direction:a.replace("swipe",""),xAmount:f,yAmount:v,duration:d.time-o.time};s.trigger("swipeend",w)}c=!1,p=!1}var o,r=this,s=e(r),c=!1,p=!1,h={x:0,y:0},l={x:0,y:0};s.on(i.startevent,t),s.on(i.moveevent,a),s.on(i.endevent,n)},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.moveevent,e(this).data.callee2).off(i.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){function t(e,t){n=t,a(r,n?"scrollstart":"scrollend",e)}var n,o,r=this,s=e(r);s.on(i.scrollevent,function c(e){s.data("callee",c),n||t(e,!0),clearTimeout(o),o=setTimeout(function(){t(e,!1)},50)})},remove:function(){e(this).off(i.scrollevent,e(this).data.callee)}};var r,s,c,p,h,l=e(window),u={0:!0,180:!0};if(i.orientation_support){var g=window.innerWidth||l.width(),d=window.innerHeight||l.height(),f=50;p=g>d&&g-d>f,h=u[window.orientation],(p&&h||!p&&!h)&&(u={"-90":!0,90:!0})}e.event.special.orientationchange=r={setup:function(){return i.orientation_support?!1:(c=s(),l.on("throttledresize",t),!0)},teardown:function(){return i.orientation_support?!1:(l.off("throttledresize",t),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=s(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=s=function(){var e=!0,t=document.documentElement;return e=i.orientation_support?u[window.orientation]:t&&t.clientWidth/t.clientHeight<1.1,e?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",x)},teardown:function(){e(this).off("resize",x)}};var v,w,_,T=250,x=function(){w=Date.now(),_=w-y,_>=T?(y=w,e(this).trigger("throttledresize")):(v&&window.clearTimeout(v),v=window.setTimeout(t,T-_))},y=0;e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); From 377d7de4fd68f79593d9aa74a919683c28d6ef1b Mon Sep 17 00:00:00 2001 From: Ben Major Date: Tue, 10 Nov 2015 09:55:19 +0000 Subject: [PATCH 046/149] Fixed 'i undefined' error --- src/1.0.3/jquery.mobile-events.js | 40 +++++++++++++++---------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/1.0.3/jquery.mobile-events.js b/src/1.0.3/jquery.mobile-events.js index 48d40be..1c054d8 100644 --- a/src/1.0.3/jquery.mobile-events.js +++ b/src/1.0.3/jquery.mobile-events.js @@ -94,8 +94,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target @@ -127,8 +127,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target @@ -160,8 +160,8 @@ 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target @@ -226,8 +226,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, endOffset = { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }; var duration = end_time - start_time; @@ -295,8 +295,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target @@ -323,8 +323,8 @@ 'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target @@ -406,8 +406,8 @@ 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target @@ -557,8 +557,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target @@ -608,8 +608,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target @@ -650,8 +650,8 @@ 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) }, 'time': Date.now(), 'target': e.target From a51e9d4eef38680af4c68f54628bff51271e07d9 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Thu, 12 Nov 2015 16:29:08 +0000 Subject: [PATCH 047/149] Update README.md --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 267de82..0347db0 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,18 @@ 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 1.0.4** (2015-11-12) + + Regressed from `MSPointerEvent` for compatability with IE11 and Edge + + Removed multi-name event for `tap`. + ++ **Version 1.0.3** (2015-11-10) + + Numerous minor bug fixes + + Fixes a bug where the offset position returned by events relative to the **current target**, not the bound target. + ++ **Version 1.0.2** (2015-08-26) + + Numerous bug fixes + + Added support for `MSPointerEvent` + + **Version 1.0.1** (2015-08-21) + Added Bower package for easy install + Fixed a bug where Internet Explorer under Windows Mobile did not trigger certain events. From 4b833b9e09ed30cb6fa198df4a292157508212c1 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Thu, 12 Nov 2015 16:29:22 +0000 Subject: [PATCH 048/149] Fixed spacing error. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0347db0..ebfb351 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ 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 1.0.4** (2015-11-12) ++ **Version 1.0.4** (2015-11-12) + Regressed from `MSPointerEvent` for compatability with IE11 and Edge + Removed multi-name event for `tap`. From ae718de9b91c410ed5023b31f2a8a5d0811aa9a4 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Thu, 12 Nov 2015 16:30:22 +0000 Subject: [PATCH 049/149] Fixes several bugs - Regressed from MSPointerEvent for compatability with IE11 and Edge - Removed multi-name event for tap. --- src/1.0.4 | 867 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 867 insertions(+) create mode 100644 src/1.0.4 diff --git a/src/1.0.4 b/src/1.0.4 new file mode 100644 index 0000000..c60f769 --- /dev/null +++ b/src/1.0.4 @@ -0,0 +1,867 @@ +/*! + * jQuery Mobile Events + * by Ben Major (lincweb - www.lincweb.co.uk) + * + * Copyright 2011-2015, 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 || {}; + + // navigator.userAgent.toLowerCase() isn't reliable for Chrome installs + // on mobile devices. As such, we will create a boolean isChromeDesktop + // The reason that we need to do this is because Chrome annoyingly + // purports support for touch events even if the underlying hardware + // does not! + var agent = navigator.userAgent.toLowerCase(), + isChromeDesktop = (agent.indexOf('chrome') > -1 && ((agent.indexOf('windows') > -1) || (agent.indexOf('macintosh') > -1) || (agent.indexOf('linux') > -1)) && agent.indexOf('mobile') < 0 && agent.indexOf('android') < 0), + + settings = { + tap_pixel_range: 5, + swipe_h_threshold: 50, + swipe_v_threshold: 50, + taphold_threshold: 750, + doubletap_int: 500, + + touch_capable: ('ontouchstart' in window && !isChromeDesktop), + orientation_support: ('orientation' in window && 'onorientationchange' in window), + + startevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchstart' : 'mousedown'), + endevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchend' : 'mouseup'), + moveevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'mousemove'), + tapevent: ('ontouchstart' in window && !isChromeDesktop) ? 'tap' : 'click', + scrollevent: ('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'scroll', + + hold_timer: null, + tap_timer: null + }; + + // 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; }; + + // Add Event shortcuts: + $.each(['tapstart', 'tapend', 'tapmove', 'tap', 'tap2', 'tap3', 'tap4', 'singletap', 'doubletap', 'taphold', 'swipe', 'swipeup', 'swiperight', 'swipedown', 'swipeleft', 'swipeend', 'scrollstart', 'scrollend', 'orientationchange'], 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 origEvent = e.originalEvent, + touchData = { + 'position': { + 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().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 origEvent = e.originalEvent, + touchData = { + 'position': { + 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().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 origEvent = e.originalEvent; + var touchData = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().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].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 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; + + settings.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(), + endPosition = { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + endOffset = { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + }; + var duration = end_time - start_time; + + // Build the touch data: + var touchData = { + 'startTime': start_time, + 'endTime': end_time, + 'startPosition': startPosition, + 'startOffset': startOffset, + 'endPosition': endPosition, + 'endOffset': endOffset, + 'duration': duration, + 'target': e.target + }; + $this.data('callee1', tapHoldFunc1); + triggerCustomEvent(thisObject, 'taphold', e, touchData); + } + }, settings.taphold_threshold); + + return true; + } + }).on(settings.endevent, function tapHoldFunc2() { + $this.data('callee2', tapHoldFunc2); + $this.data('tapheld', false); + window.clearTimeout(settings.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) { + firstTap = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + }, + 'time': Date.now(), + 'target': e.target + }; + } + + 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 == origTarget) && delta > 100) { + $this.data('doubletapped', true); + window.clearTimeout(settings.tap_timer); + + // Now get the current event: + var lastTap = { + 'position': { + 'x': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + }, + 'time': Date.now(), + 'target': e.target + }; + + 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; + var 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 () { + if (!$this.data('doubletapped') && !$this.data('tapheld') && (start_pos.x == end_pos_x) && (start_pos.y == end_pos_y)) { + var origEvent = e.originalEvent; + var touchData = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().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 origEvent = e.originalEvent; + var touchData = [ ]; + + for( var i = 0; i < touches.length; i++) + { + var touch = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[i].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[i].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + }, + 'time': Date.now(), + 'target': e.target + }; + + touchData.push( touch ); + } + + triggerCustomEvent(thisObject, 'tap', 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 origEvent = e.originalEvent; + // Read event data into our startEvt: + startEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().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 (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 (originalCoord.x > finalCoord.x && (originalCoord.x - finalCoord.x > h_threshold)) { + swipedir = 'swipeleft'; + } + 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 origEvent = e.originalEvent; + var endEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().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 origEvent = e.originalEvent; + var endEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + }, + 'time': Date.now(), + '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); + + 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' + }, function (e, srcE) { + $.event.special[e] = { + setup: function () { + $(this).on(srcE, $.noop); + } + }; + }); + +}(jQuery)); From 741c9c4d614cc7ccd4203fb7295d10154257e1c9 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Thu, 12 Nov 2015 16:30:44 +0000 Subject: [PATCH 050/149] Delete 1.0.4 --- src/1.0.4 | 867 ------------------------------------------------------ 1 file changed, 867 deletions(-) delete mode 100644 src/1.0.4 diff --git a/src/1.0.4 b/src/1.0.4 deleted file mode 100644 index c60f769..0000000 --- a/src/1.0.4 +++ /dev/null @@ -1,867 +0,0 @@ -/*! - * jQuery Mobile Events - * by Ben Major (lincweb - www.lincweb.co.uk) - * - * Copyright 2011-2015, 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 || {}; - - // navigator.userAgent.toLowerCase() isn't reliable for Chrome installs - // on mobile devices. As such, we will create a boolean isChromeDesktop - // The reason that we need to do this is because Chrome annoyingly - // purports support for touch events even if the underlying hardware - // does not! - var agent = navigator.userAgent.toLowerCase(), - isChromeDesktop = (agent.indexOf('chrome') > -1 && ((agent.indexOf('windows') > -1) || (agent.indexOf('macintosh') > -1) || (agent.indexOf('linux') > -1)) && agent.indexOf('mobile') < 0 && agent.indexOf('android') < 0), - - settings = { - tap_pixel_range: 5, - swipe_h_threshold: 50, - swipe_v_threshold: 50, - taphold_threshold: 750, - doubletap_int: 500, - - touch_capable: ('ontouchstart' in window && !isChromeDesktop), - orientation_support: ('orientation' in window && 'onorientationchange' in window), - - startevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchstart' : 'mousedown'), - endevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchend' : 'mouseup'), - moveevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'mousemove'), - tapevent: ('ontouchstart' in window && !isChromeDesktop) ? 'tap' : 'click', - scrollevent: ('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'scroll', - - hold_timer: null, - tap_timer: null - }; - - // 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; }; - - // Add Event shortcuts: - $.each(['tapstart', 'tapend', 'tapmove', 'tap', 'tap2', 'tap3', 'tap4', 'singletap', 'doubletap', 'taphold', 'swipe', 'swipeup', 'swiperight', 'swipedown', 'swipeleft', 'swipeend', 'scrollstart', 'scrollend', 'orientationchange'], 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 origEvent = e.originalEvent, - touchData = { - 'position': { - 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), - 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY - }, - 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().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 origEvent = e.originalEvent, - touchData = { - 'position': { - 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), - 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY - }, - 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().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 origEvent = e.originalEvent; - var touchData = { - 'position': { - 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY - }, - 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().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].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY - }, - 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; - - settings.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(), - endPosition = { - 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY - }, - endOffset = { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) - }; - var duration = end_time - start_time; - - // Build the touch data: - var touchData = { - 'startTime': start_time, - 'endTime': end_time, - 'startPosition': startPosition, - 'startOffset': startOffset, - 'endPosition': endPosition, - 'endOffset': endOffset, - 'duration': duration, - 'target': e.target - }; - $this.data('callee1', tapHoldFunc1); - triggerCustomEvent(thisObject, 'taphold', e, touchData); - } - }, settings.taphold_threshold); - - return true; - } - }).on(settings.endevent, function tapHoldFunc2() { - $this.data('callee2', tapHoldFunc2); - $this.data('tapheld', false); - window.clearTimeout(settings.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) { - firstTap = { - 'position': { - 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY - }, - 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) - }, - 'time': Date.now(), - 'target': e.target - }; - } - - 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 == origTarget) && delta > 100) { - $this.data('doubletapped', true); - window.clearTimeout(settings.tap_timer); - - // Now get the current event: - var lastTap = { - 'position': { - 'x': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenX : e.screenX, - 'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenY : e.screenY - }, - 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) - }, - 'time': Date.now(), - 'target': e.target - }; - - 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; - var 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 () { - if (!$this.data('doubletapped') && !$this.data('tapheld') && (start_pos.x == end_pos_x) && (start_pos.y == end_pos_y)) { - var origEvent = e.originalEvent; - var touchData = { - 'position': { - 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY - }, - 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().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 origEvent = e.originalEvent; - var touchData = [ ]; - - for( var i = 0; i < touches.length; i++) - { - var touch = { - 'position': { - 'x': (settings.touch_capable) ? origEvent.changedTouches[i].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.changedTouches[i].screenY : e.screenY - }, - 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) - }, - 'time': Date.now(), - 'target': e.target - }; - - touchData.push( touch ); - } - - triggerCustomEvent(thisObject, 'tap', 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 origEvent = e.originalEvent; - // Read event data into our startEvt: - startEvnt = { - 'position': { - 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY - }, - 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().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 (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 (originalCoord.x > finalCoord.x && (originalCoord.x - finalCoord.x > h_threshold)) { - swipedir = 'swipeleft'; - } - 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 origEvent = e.originalEvent; - var endEvnt = { - 'position': { - 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY - }, - 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().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 origEvent = e.originalEvent; - var endEvnt = { - 'position': { - 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY - }, - 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) - }, - 'time': Date.now(), - '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); - - 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' - }, function (e, srcE) { - $.event.special[e] = { - setup: function () { - $(this).on(srcE, $.noop); - } - }; - }); - -}(jQuery)); From 6ecc44114c649e4cff52b1dc02e0db1b48ee53d9 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Thu, 12 Nov 2015 16:31:46 +0000 Subject: [PATCH 051/149] Create jquery.mobile-events.js - Regressed from MSPointerEvent for compatibility with IE11 and Edge - Removed multi-name event for tap. --- src/1.0.4/jquery.mobile-events.js | 867 ++++++++++++++++++++++++++++++ 1 file changed, 867 insertions(+) create mode 100644 src/1.0.4/jquery.mobile-events.js diff --git a/src/1.0.4/jquery.mobile-events.js b/src/1.0.4/jquery.mobile-events.js new file mode 100644 index 0000000..c60f769 --- /dev/null +++ b/src/1.0.4/jquery.mobile-events.js @@ -0,0 +1,867 @@ +/*! + * jQuery Mobile Events + * by Ben Major (lincweb - www.lincweb.co.uk) + * + * Copyright 2011-2015, 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 || {}; + + // navigator.userAgent.toLowerCase() isn't reliable for Chrome installs + // on mobile devices. As such, we will create a boolean isChromeDesktop + // The reason that we need to do this is because Chrome annoyingly + // purports support for touch events even if the underlying hardware + // does not! + var agent = navigator.userAgent.toLowerCase(), + isChromeDesktop = (agent.indexOf('chrome') > -1 && ((agent.indexOf('windows') > -1) || (agent.indexOf('macintosh') > -1) || (agent.indexOf('linux') > -1)) && agent.indexOf('mobile') < 0 && agent.indexOf('android') < 0), + + settings = { + tap_pixel_range: 5, + swipe_h_threshold: 50, + swipe_v_threshold: 50, + taphold_threshold: 750, + doubletap_int: 500, + + touch_capable: ('ontouchstart' in window && !isChromeDesktop), + orientation_support: ('orientation' in window && 'onorientationchange' in window), + + startevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchstart' : 'mousedown'), + endevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchend' : 'mouseup'), + moveevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'mousemove'), + tapevent: ('ontouchstart' in window && !isChromeDesktop) ? 'tap' : 'click', + scrollevent: ('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'scroll', + + hold_timer: null, + tap_timer: null + }; + + // 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; }; + + // Add Event shortcuts: + $.each(['tapstart', 'tapend', 'tapmove', 'tap', 'tap2', 'tap3', 'tap4', 'singletap', 'doubletap', 'taphold', 'swipe', 'swipeup', 'swiperight', 'swipedown', 'swipeleft', 'swipeend', 'scrollstart', 'scrollend', 'orientationchange'], 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 origEvent = e.originalEvent, + touchData = { + 'position': { + 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().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 origEvent = e.originalEvent, + touchData = { + 'position': { + 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().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 origEvent = e.originalEvent; + var touchData = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().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].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 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; + + settings.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(), + endPosition = { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + endOffset = { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + }; + var duration = end_time - start_time; + + // Build the touch data: + var touchData = { + 'startTime': start_time, + 'endTime': end_time, + 'startPosition': startPosition, + 'startOffset': startOffset, + 'endPosition': endPosition, + 'endOffset': endOffset, + 'duration': duration, + 'target': e.target + }; + $this.data('callee1', tapHoldFunc1); + triggerCustomEvent(thisObject, 'taphold', e, touchData); + } + }, settings.taphold_threshold); + + return true; + } + }).on(settings.endevent, function tapHoldFunc2() { + $this.data('callee2', tapHoldFunc2); + $this.data('tapheld', false); + window.clearTimeout(settings.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) { + firstTap = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + }, + 'time': Date.now(), + 'target': e.target + }; + } + + 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 == origTarget) && delta > 100) { + $this.data('doubletapped', true); + window.clearTimeout(settings.tap_timer); + + // Now get the current event: + var lastTap = { + 'position': { + 'x': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + }, + 'time': Date.now(), + 'target': e.target + }; + + 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; + var 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 () { + if (!$this.data('doubletapped') && !$this.data('tapheld') && (start_pos.x == end_pos_x) && (start_pos.y == end_pos_y)) { + var origEvent = e.originalEvent; + var touchData = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().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 origEvent = e.originalEvent; + var touchData = [ ]; + + for( var i = 0; i < touches.length; i++) + { + var touch = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[i].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[i].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + }, + 'time': Date.now(), + 'target': e.target + }; + + touchData.push( touch ); + } + + triggerCustomEvent(thisObject, 'tap', 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 origEvent = e.originalEvent; + // Read event data into our startEvt: + startEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().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 (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 (originalCoord.x > finalCoord.x && (originalCoord.x - finalCoord.x > h_threshold)) { + swipedir = 'swipeleft'; + } + 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 origEvent = e.originalEvent; + var endEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().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 origEvent = e.originalEvent; + var endEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + }, + 'time': Date.now(), + '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); + + 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' + }, function (e, srcE) { + $.event.special[e] = { + setup: function () { + $(this).on(srcE, $.noop); + } + }; + }); + +}(jQuery)); From 894975eaa7b7dea560497aeb23268bf5b37193ef Mon Sep 17 00:00:00 2001 From: Ben Major Date: Thu, 12 Nov 2015 16:32:19 +0000 Subject: [PATCH 052/149] Fixed typographical errors --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ebfb351..470613e 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ 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 1.0.4** (2015-11-12) - + Regressed from `MSPointerEvent` for compatability with IE11 and Edge + + Regressed from `MSPointerEvent` for compatibility with IE11 and Edge + Removed multi-name event for `tap`. + **Version 1.0.3** (2015-11-10) From fbeb723f0692140e639f5118712d421e95a50e68 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Thu, 12 Nov 2015 16:33:14 +0000 Subject: [PATCH 053/149] Create jquery.mobile-events.min.js - Regressed from MSPointerEvent for compatibility with IE11 and Edge - Removed multi-name event for tap. --- src/1.0.4/jquery.mobile-events.min.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/1.0.4/jquery.mobile-events.min.js diff --git a/src/1.0.4/jquery.mobile-events.min.js b/src/1.0.4/jquery.mobile-events.min.js new file mode 100644 index 0000000..5db6423 --- /dev/null +++ b/src/1.0.4/jquery.mobile-events.min.js @@ -0,0 +1 @@ +"use strict";!function(e){function t(){var e=s();e!==r&&(r=e,u.trigger("orientationchange"))}function a(t,a,o,n){var i=o.type;o.type=a,e.event.dispatch.call(t,o,n),o.type=i}e.attrFn=e.attrFn||{};var o=navigator.userAgent.toLowerCase(),n=o.indexOf("chrome")>-1&&(o.indexOf("windows")>-1||o.indexOf("macintosh")>-1||o.indexOf("linux")>-1)&&o.indexOf("mobile")<0&&o.indexOf("android")<0,i={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:"ontouchstart"in window&&!n,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:"ontouchstart"in window&&!n?"touchstart":"mousedown",endevent:"ontouchstart"in window&&!n?"touchend":"mouseup",moveevent:"ontouchstart"in window&&!n?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!n?"tap":"click",scrollevent:"ontouchstart"in window&&!n?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.isTouchCapable=function(){return i.touch_capable},e.getStartEvent=function(){return i.startevent},e.getEndEvent=function(){return i.endevent},e.getMoveEvent=function(){return i.moveevent},e.getTapEvent=function(){return i.tapevent},e.getScrollEvent=function(){return i.scrollevent},e.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],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(i.startevent,function n(e){if(o.data("callee",n),e.which&&1!==e.which)return!1;var c=e.originalEvent,s={position:{x:i.touch_capable?c.touches[0].screenX:e.screenX,y:i.touch_capable?c.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?c.changedTouches[0].pageX-o.position().left:e.pageX-o.position().left),y:Math.round(i.touch_capable?c.changedTouches[0].pageY-o.position().top:e.pageY-o.position().top)},time:Date.now(),target:e.target};return a(t,"tapstart",e,s),!0})},remove:function(){e(this).off(i.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,o=e(t);o.on(i.moveevent,function n(e){o.data("callee",n);var c=e.originalEvent,s={position:{x:i.touch_capable?c.touches[0].screenX:e.screenX,y:i.touch_capable?c.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?c.changedTouches[0].pageX-o.position().left:e.pageX-o.position().left),y:Math.round(i.touch_capable?c.changedTouches[0].pageY-o.position().top:e.pageY-o.position().top)},time:Date.now(),target:e.target};return a(t,"tapmove",e,s),!0})},remove:function(){e(this).off(i.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,o=e(t);o.on(i.endevent,function n(e){o.data("callee",n);var c=e.originalEvent,s={position:{x:i.touch_capable?c.changedTouches[0].screenX:e.screenX,y:i.touch_capable?c.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?c.changedTouches[0].pageX-o.position().left:e.pageX-o.position().left),y:Math.round(i.touch_capable?c.changedTouches[0].pageY-o.position().top:e.pageY-o.position().top)},time:Date.now(),target:e.target};return a(t,"tapend",e,s),!0})},remove:function(){e(this).off(i.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,o=this,n=e(o),c={x:0,y:0},s=0,r=0;n.on(i.startevent,function p(e){if(e.which&&1!==e.which)return!1;n.data("tapheld",!1),t=e.target;var h=e.originalEvent,u=Date.now(),l={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},g={x:i.touch_capable?h.touches[0].pageX-h.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?h.touches[0].pageY-h.touches[0].target.offsetTop:e.offsetY};return c.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,c.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,s=c.x,r=c.y,i.hold_timer=window.setTimeout(function(){var d=c.x-s,f=c.y-r;if(e.target==t&&(c.x==s&&c.y==r||d>=-i.tap_pixel_range&&d<=i.tap_pixel_range&&f>=-i.tap_pixel_range&&f<=i.tap_pixel_range)){n.data("tapheld",!0);var v=Date.now(),w={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},_={x:Math.round(i.touch_capable?h.changedTouches[0].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(i.touch_capable?h.changedTouches[0].pageY-n.position().top:e.pageY-n.position().top)},T=v-u,x={startTime:u,endTime:v,startPosition:l,startOffset:g,endPosition:w,endOffset:_,duration:T,target:e.target};n.data("callee1",p),a(o,"taphold",e,x)}},i.taphold_threshold),!0}).on(i.endevent,function h(){n.data("callee2",h),n.data("tapheld",!1),window.clearTimeout(i.hold_timer)}).on(i.moveevent,function u(e){n.data("callee3",u),s=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,r=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2).off(i.moveevent,e(this).data.callee3)}},e.event.special.doubletap={setup:function(){var t,o,n,c,s=this,r=e(s),p=null,h=!1;r.on(i.startevent,function u(e){return e.which&&1!==e.which?!1:(r.data("doubletapped",!1),t=e.target,r.data("callee1",u),n=e.originalEvent,p||(p={position:{x:i.touch_capable?n.touches[0].screenX:e.screenX,y:i.touch_capable?n.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?n.changedTouches[0].pageX-r.position().left:e.pageX-r.position().left),y:Math.round(i.touch_capable?n.changedTouches[0].pageY-r.position().top:e.pageY-r.position().top)},time:Date.now(),target:e.target}),!0)}).on(i.endevent,function l(e){var u=Date.now(),g=r.data("lastTouch")||u+1,d=u-g;if(window.clearTimeout(o),r.data("callee2",l),d100){r.data("doubletapped",!0),window.clearTimeout(i.tap_timer);var f={position:{x:i.touch_capable?e.originalEvent.changedTouches[0].screenX:e.screenX,y:i.touch_capable?e.originalEvent.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?n.changedTouches[0].pageX-r.position().left:e.pageX-r.position().left),y:Math.round(i.touch_capable?n.changedTouches[0].pageY-r.position().top:e.pageY-r.position().top)},time:Date.now(),target:e.target},v={firstTap:p,secondTap:f,interval:f.time-p.time};h||(a(s,"doubletap",e,v),p=null),h=!0,c=window.setTimeout(function(){h=!1},i.doubletap_int)}else r.data("lastTouch",u),o=window.setTimeout(function(){p=null,window.clearTimeout(o)},i.doubletap_int,[e]);r.data("lastTouch",u)})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,o=e(t),n=null,c=null,s={x:0,y:0};o.on(i.startevent,function r(e){return e.which&&1!==e.which?!1:(c=Date.now(),n=e.target,o.data("callee1",r),s.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,s.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,!0)}).on(i.endevent,function p(e){if(o.data("callee2",p),e.target==n){var r=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageX:e.pageX,h=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageY:e.pageY;i.tap_timer=window.setTimeout(function(){if(!o.data("doubletapped")&&!o.data("tapheld")&&s.x==r&&s.y==h){var n=e.originalEvent,p={position:{x:i.touch_capable?n.changedTouches[0].screenX:e.screenX,y:i.touch_capable?n.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?n.changedTouches[0].pageX-o.position().left:e.pageX-o.position().left),y:Math.round(i.touch_capable?n.changedTouches[0].pageY-o.position().top:e.pageY-o.position().top)},time:Date.now(),target:e.target};p.time-c=-i.tap_pixel_range&&g<=i.tap_pixel_range&&d>=-i.tap_pixel_range&&d<=i.tap_pixel_range)){for(var f=e.originalEvent,v=[],w=0;wu.y&&h.y-u.y>d&&(o="swipeup"),h.xg&&(o="swiperight"),h.yd&&(o="swipedown"),h.x>u.x&&h.x-u.x>g&&(o="swipeleft"),void 0!=o&&r){h.x=0,h.y=0,u.x=0,u.y=0,r=!1;var f=t.originalEvent,v={position:{x:i.touch_capable?f.touches[0].screenX:t.screenX,y:i.touch_capable?f.touches[0].screenY:t.screenY},offset:{x:Math.round(i.touch_capable?f.changedTouches[0].pageX-s.position().left:t.pageX-s.position().left),y:Math.round(i.touch_capable?f.changedTouches[0].pageY-s.position().top:t.pageY-s.position().top)},time:Date.now(),target:t.target},w=Math.abs(n.position.x-v.position.x),_=Math.abs(n.position.y-v.position.y),T={startEvnt:n,endEvnt:v,direction:o.replace("swipe",""),xAmount:w,yAmount:_,duration:v.time-n.time};p=!0,s.trigger("swipe",T).trigger(o,T)}}function o(t){s=e(t.currentTarget);var a="";if(s.data("callee3",o),p){var c=s.data("xthreshold"),h=s.data("ythreshold"),u="undefined"!=typeof c&&c!==!1&&parseInt(c)?parseInt(c):i.swipe_h_threshold,l="undefined"!=typeof h&&h!==!1&&parseInt(h)?parseInt(h):i.swipe_v_threshold,g=t.originalEvent,d={position:{x:i.touch_capable?g.changedTouches[0].screenX:t.screenX,y:i.touch_capable?g.changedTouches[0].screenY:t.screenY},offset:{x:Math.round(i.touch_capable?g.changedTouches[0].pageX-s.position().left:t.pageX-s.position().left),y:Math.round(i.touch_capable?g.changedTouches[0].pageY-s.position().top:t.pageY-s.position().top)},time:Date.now(),target:t.target};n.position.y>d.position.y&&n.position.y-d.position.y>l&&(a="swipeup"),n.position.xu&&(a="swiperight"),n.position.yl&&(a="swipedown"),n.position.x>d.position.x&&n.position.x-d.position.x>u&&(a="swipeleft");var f=Math.abs(n.position.x-d.position.x),v=Math.abs(n.position.y-d.position.y),w={startEvnt:n,endEvnt:d,direction:a.replace("swipe",""),xAmount:f,yAmount:v,duration:d.time-n.time};s.trigger("swipeend",w)}r=!1,p=!1}var n,c=this,s=e(c),r=!1,p=!1,h={x:0,y:0},u={x:0,y:0};s.on(i.startevent,t),s.on(i.moveevent,a),s.on(i.endevent,o)},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.moveevent,e(this).data.callee2).off(i.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){function t(e,t){o=t,a(c,o?"scrollstart":"scrollend",e)}var o,n,c=this,s=e(c);s.on(i.scrollevent,function r(e){s.data("callee",r),o||t(e,!0),clearTimeout(n),n=setTimeout(function(){t(e,!1)},50)})},remove:function(){e(this).off(i.scrollevent,e(this).data.callee)}};var c,s,r,p,h,u=e(window),l={0:!0,180:!0};if(i.orientation_support){var g=window.innerWidth||u.width(),d=window.innerHeight||u.height(),f=50;p=g>d&&g-d>f,h=l[window.orientation],(p&&h||!p&&!h)&&(l={"-90":!0,90:!0})}e.event.special.orientationchange=c={setup:function(){return i.orientation_support?!1:(r=s(),u.on("throttledresize",t),!0)},teardown:function(){return i.orientation_support?!1:(u.off("throttledresize",t),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=s(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=s=function(){var e=!0,t=document.documentElement;return e=i.orientation_support?l[window.orientation]:t&&t.clientWidth/t.clientHeight<1.1,e?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",x)},teardown:function(){e(this).off("resize",x)}};var v,w,_,T=250,x=function(){w=Date.now(),_=w-y,_>=T?(y=w,e(this).trigger("throttledresize")):(v&&window.clearTimeout(v),v=window.setTimeout(t,T-_))},y=0;e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); From fa9e3531d9c9e4d8a5d31e3ce474c99a9940c1d0 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Thu, 12 Nov 2015 16:33:43 +0000 Subject: [PATCH 054/149] Sync to 1.0.4 --- src/jquery.mobile-events.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jquery.mobile-events.min.js b/src/jquery.mobile-events.min.js index f5f7c1f..5db6423 100644 --- a/src/jquery.mobile-events.min.js +++ b/src/jquery.mobile-events.min.js @@ -1 +1 @@ -"use strict";!function(e){function t(){var e=s();e!==c&&(c=e,l.trigger("orientationchange"))}function a(t,a,n,o){var i=n.type;n.type=a,e.event.dispatch.call(t,n,o),n.type=i}e.attrFn=e.attrFn||{};var n=navigator.userAgent.toLowerCase(),o=n.indexOf("chrome")>-1&&(n.indexOf("windows")>-1||n.indexOf("macintosh")>-1||n.indexOf("linux")>-1)&&n.indexOf("mobile")<0&&n.indexOf("android")<0,i={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:window.navigator.msPointerEnabled?!1:"ontouchstart"in window&&!o,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:window.navigator.msPointerEnabled?"MSPointerDown":"ontouchstart"in window&&!o?"touchstart":"mousedown",endevent:window.navigator.msPointerEnabled?"MSPointerUp":"ontouchstart"in window&&!o?"touchend":"mouseup",moveevent:window.navigator.msPointerEnabled?"MSPointerMove":"ontouchstart"in window&&!o?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!o?"tap":"click",scrollevent:"ontouchstart"in window&&!o?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.isTouchCapable=function(){return i.touch_capable},e.getStartEvent=function(){return i.startevent},e.getEndEvent=function(){return i.endevent},e.getMoveEvent=function(){return i.moveevent},e.getTapEvent=function(){return i.tapevent},e.getScrollEvent=function(){return i.scrollevent},e.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],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,n=e(t);n.on(i.startevent,function o(e){if(n.data("callee",o),e.which&&1!==e.which)return!1;var r=e.originalEvent,s={position:{x:i.touch_capable?r.touches[0].screenX:e.screenX,y:i.touch_capable?r.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?r.changedTouches[0].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(i.touch_capable?r.changedTouches[0].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};return a(t,"tapstart",e,s),!0})},remove:function(){e(this).off(i.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,n=e(t);n.on(i.moveevent,function o(e){n.data("callee",o);var r=e.originalEvent,s={position:{x:i.touch_capable?r.touches[0].screenX:e.screenX,y:i.touch_capable?r.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?r.changedTouches[0].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(i.touch_capable?r.changedTouches[0].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};return a(t,"tapmove",e,s),!0})},remove:function(){e(this).off(i.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,n=e(t);n.on(i.endevent,function o(e){n.data("callee",o);var r=e.originalEvent,s={position:{x:i.touch_capable?r.changedTouches[0].screenX:e.screenX,y:i.touch_capable?r.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?r.changedTouches[0].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(i.touch_capable?r.changedTouches[0].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};return a(t,"tapend",e,s),!0})},remove:function(){e(this).off(i.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,n=this,o=e(n),r={x:0,y:0},s=0,c=0;o.on(i.startevent,function p(e){if(e.which&&1!==e.which)return!1;o.data("tapheld",!1),t=e.target;var h=e.originalEvent,l=Date.now(),u={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},g={x:i.touch_capable?h.touches[0].pageX-h.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?h.touches[0].pageY-h.touches[0].target.offsetTop:e.offsetY};return r.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,r.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,s=r.x,c=r.y,i.hold_timer=window.setTimeout(function(){var d=r.x-s,f=r.y-c;if(e.target==t&&(r.x==s&&r.y==c||d>=-i.tap_pixel_range&&d<=i.tap_pixel_range&&f>=-i.tap_pixel_range&&f<=i.tap_pixel_range)){o.data("tapheld",!0);var v=Date.now(),w={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},_={x:Math.round(i.touch_capable?h.changedTouches[0].pageX-o.position().left:e.pageX-o.position().left),y:Math.round(i.touch_capable?h.changedTouches[0].pageY-o.position().top:e.pageY-o.position().top)},T=v-l,x={startTime:l,endTime:v,startPosition:u,startOffset:g,endPosition:w,endOffset:_,duration:T,target:e.target};o.data("callee1",p),a(n,"taphold",e,x)}},i.taphold_threshold),!0}).on(i.endevent,function h(){o.data("callee2",h),o.data("tapheld",!1),window.clearTimeout(i.hold_timer)}).on(i.moveevent,function l(e){o.data("callee3",l),s=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,c=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2).off(i.moveevent,e(this).data.callee3)}},e.event.special.doubletap={setup:function(){var t,n,o,r,s=this,c=e(s),p=null,h=!1;c.on(i.startevent,function l(e){return e.which&&1!==e.which?!1:(c.data("doubletapped",!1),t=e.target,c.data("callee1",l),o=e.originalEvent,p||(p={position:{x:i.touch_capable?o.touches[0].screenX:e.screenX,y:i.touch_capable?o.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?o.changedTouches[0].pageX-c.position().left:e.pageX-c.position().left),y:Math.round(i.touch_capable?o.changedTouches[0].pageY-c.position().top:e.pageY-c.position().top)},time:Date.now(),target:e.target}),!0)}).on(i.endevent,function u(e){var l=Date.now(),g=c.data("lastTouch")||l+1,d=l-g;if(window.clearTimeout(n),c.data("callee2",u),d100){c.data("doubletapped",!0),window.clearTimeout(i.tap_timer);var f={position:{x:i.touch_capable?e.originalEvent.changedTouches[0].screenX:e.screenX,y:i.touch_capable?e.originalEvent.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?o.changedTouches[0].pageX-c.position().left:e.pageX-c.position().left),y:Math.round(i.touch_capable?o.changedTouches[0].pageY-c.position().top:e.pageY-c.position().top)},time:Date.now(),target:e.target},v={firstTap:p,secondTap:f,interval:f.time-p.time};h||(a(s,"doubletap",e,v),p=null),h=!0,r=window.setTimeout(function(){h=!1},i.doubletap_int)}else c.data("lastTouch",l),n=window.setTimeout(function(){p=null,window.clearTimeout(n)},i.doubletap_int,[e]);c.data("lastTouch",l)})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,n=e(t),o=null,r=null,s={x:0,y:0};n.on(i.startevent,function c(e){return e.which&&1!==e.which?!1:(r=Date.now(),o=e.target,n.data("callee1",c),s.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,s.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,!0)}).on(i.endevent,function p(e){if(n.data("callee2",p),e.target==o){var c=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageX:e.pageX,h=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageY:e.pageY;i.tap_timer=window.setTimeout(function(){if(!n.data("doubletapped")&&!n.data("tapheld")&&s.x==c&&s.y==h){var o=e.originalEvent,p={position:{x:i.touch_capable?o.changedTouches[0].screenX:e.screenX,y:i.touch_capable?o.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?o.changedTouches[0].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(i.touch_capable?o.changedTouches[0].pageY-n.position().top:e.pageY-n.position().top)},time:Date.now(),target:e.target};p.time-r=-i.tap_pixel_range&&d<=i.tap_pixel_range&&f>=-i.tap_pixel_range&&f<=i.tap_pixel_range)){for(var v=e.originalEvent,w=[],_=0;_l.y&&h.y-l.y>d&&(n="swipeup"),h.xg&&(n="swiperight"),h.yd&&(n="swipedown"),h.x>l.x&&h.x-l.x>g&&(n="swipeleft"),void 0!=n&&c){h.x=0,h.y=0,l.x=0,l.y=0,c=!1;var f=t.originalEvent,v={position:{x:i.touch_capable?f.touches[0].screenX:t.screenX,y:i.touch_capable?f.touches[0].screenY:t.screenY},offset:{x:Math.round(i.touch_capable?f.changedTouches[0].pageX-s.position().left:t.pageX-s.position().left),y:Math.round(i.touch_capable?f.changedTouches[0].pageY-s.position().top:t.pageY-s.position().top)},time:Date.now(),target:t.target},w=Math.abs(o.position.x-v.position.x),_=Math.abs(o.position.y-v.position.y),T={startEvnt:o,endEvnt:v,direction:n.replace("swipe",""),xAmount:w,yAmount:_,duration:v.time-o.time};p=!0,s.trigger("swipe",T).trigger(n,T)}}function n(t){s=e(t.currentTarget);var a="";if(s.data("callee3",n),p){var r=s.data("xthreshold"),h=s.data("ythreshold"),l="undefined"!=typeof r&&r!==!1&&parseInt(r)?parseInt(r):i.swipe_h_threshold,u="undefined"!=typeof h&&h!==!1&&parseInt(h)?parseInt(h):i.swipe_v_threshold,g=t.originalEvent,d={position:{x:i.touch_capable?g.changedTouches[0].screenX:t.screenX,y:i.touch_capable?g.changedTouches[0].screenY:t.screenY},offset:{x:Math.round(i.touch_capable?g.changedTouches[0].pageX-s.position().left:t.pageX-s.position().left),y:Math.round(i.touch_capable?g.changedTouches[0].pageY-s.position().top:t.pageY-s.position().top)},time:Date.now(),target:t.target};o.position.y>d.position.y&&o.position.y-d.position.y>u&&(a="swipeup"),o.position.xl&&(a="swiperight"),o.position.yu&&(a="swipedown"),o.position.x>d.position.x&&o.position.x-d.position.x>l&&(a="swipeleft");var f=Math.abs(o.position.x-d.position.x),v=Math.abs(o.position.y-d.position.y),w={startEvnt:o,endEvnt:d,direction:a.replace("swipe",""),xAmount:f,yAmount:v,duration:d.time-o.time};s.trigger("swipeend",w)}c=!1,p=!1}var o,r=this,s=e(r),c=!1,p=!1,h={x:0,y:0},l={x:0,y:0};s.on(i.startevent,t),s.on(i.moveevent,a),s.on(i.endevent,n)},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.moveevent,e(this).data.callee2).off(i.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){function t(e,t){n=t,a(r,n?"scrollstart":"scrollend",e)}var n,o,r=this,s=e(r);s.on(i.scrollevent,function c(e){s.data("callee",c),n||t(e,!0),clearTimeout(o),o=setTimeout(function(){t(e,!1)},50)})},remove:function(){e(this).off(i.scrollevent,e(this).data.callee)}};var r,s,c,p,h,l=e(window),u={0:!0,180:!0};if(i.orientation_support){var g=window.innerWidth||l.width(),d=window.innerHeight||l.height(),f=50;p=g>d&&g-d>f,h=u[window.orientation],(p&&h||!p&&!h)&&(u={"-90":!0,90:!0})}e.event.special.orientationchange=r={setup:function(){return i.orientation_support?!1:(c=s(),l.on("throttledresize",t),!0)},teardown:function(){return i.orientation_support?!1:(l.off("throttledresize",t),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=s(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=s=function(){var e=!0,t=document.documentElement;return e=i.orientation_support?u[window.orientation]:t&&t.clientWidth/t.clientHeight<1.1,e?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",x)},teardown:function(){e(this).off("resize",x)}};var v,w,_,T=250,x=function(){w=Date.now(),_=w-y,_>=T?(y=w,e(this).trigger("throttledresize")):(v&&window.clearTimeout(v),v=window.setTimeout(t,T-_))},y=0;e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); +"use strict";!function(e){function t(){var e=s();e!==r&&(r=e,u.trigger("orientationchange"))}function a(t,a,o,n){var i=o.type;o.type=a,e.event.dispatch.call(t,o,n),o.type=i}e.attrFn=e.attrFn||{};var o=navigator.userAgent.toLowerCase(),n=o.indexOf("chrome")>-1&&(o.indexOf("windows")>-1||o.indexOf("macintosh")>-1||o.indexOf("linux")>-1)&&o.indexOf("mobile")<0&&o.indexOf("android")<0,i={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:"ontouchstart"in window&&!n,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:"ontouchstart"in window&&!n?"touchstart":"mousedown",endevent:"ontouchstart"in window&&!n?"touchend":"mouseup",moveevent:"ontouchstart"in window&&!n?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!n?"tap":"click",scrollevent:"ontouchstart"in window&&!n?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.isTouchCapable=function(){return i.touch_capable},e.getStartEvent=function(){return i.startevent},e.getEndEvent=function(){return i.endevent},e.getMoveEvent=function(){return i.moveevent},e.getTapEvent=function(){return i.tapevent},e.getScrollEvent=function(){return i.scrollevent},e.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],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(i.startevent,function n(e){if(o.data("callee",n),e.which&&1!==e.which)return!1;var c=e.originalEvent,s={position:{x:i.touch_capable?c.touches[0].screenX:e.screenX,y:i.touch_capable?c.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?c.changedTouches[0].pageX-o.position().left:e.pageX-o.position().left),y:Math.round(i.touch_capable?c.changedTouches[0].pageY-o.position().top:e.pageY-o.position().top)},time:Date.now(),target:e.target};return a(t,"tapstart",e,s),!0})},remove:function(){e(this).off(i.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,o=e(t);o.on(i.moveevent,function n(e){o.data("callee",n);var c=e.originalEvent,s={position:{x:i.touch_capable?c.touches[0].screenX:e.screenX,y:i.touch_capable?c.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?c.changedTouches[0].pageX-o.position().left:e.pageX-o.position().left),y:Math.round(i.touch_capable?c.changedTouches[0].pageY-o.position().top:e.pageY-o.position().top)},time:Date.now(),target:e.target};return a(t,"tapmove",e,s),!0})},remove:function(){e(this).off(i.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,o=e(t);o.on(i.endevent,function n(e){o.data("callee",n);var c=e.originalEvent,s={position:{x:i.touch_capable?c.changedTouches[0].screenX:e.screenX,y:i.touch_capable?c.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?c.changedTouches[0].pageX-o.position().left:e.pageX-o.position().left),y:Math.round(i.touch_capable?c.changedTouches[0].pageY-o.position().top:e.pageY-o.position().top)},time:Date.now(),target:e.target};return a(t,"tapend",e,s),!0})},remove:function(){e(this).off(i.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,o=this,n=e(o),c={x:0,y:0},s=0,r=0;n.on(i.startevent,function p(e){if(e.which&&1!==e.which)return!1;n.data("tapheld",!1),t=e.target;var h=e.originalEvent,u=Date.now(),l={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},g={x:i.touch_capable?h.touches[0].pageX-h.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?h.touches[0].pageY-h.touches[0].target.offsetTop:e.offsetY};return c.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,c.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,s=c.x,r=c.y,i.hold_timer=window.setTimeout(function(){var d=c.x-s,f=c.y-r;if(e.target==t&&(c.x==s&&c.y==r||d>=-i.tap_pixel_range&&d<=i.tap_pixel_range&&f>=-i.tap_pixel_range&&f<=i.tap_pixel_range)){n.data("tapheld",!0);var v=Date.now(),w={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},_={x:Math.round(i.touch_capable?h.changedTouches[0].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(i.touch_capable?h.changedTouches[0].pageY-n.position().top:e.pageY-n.position().top)},T=v-u,x={startTime:u,endTime:v,startPosition:l,startOffset:g,endPosition:w,endOffset:_,duration:T,target:e.target};n.data("callee1",p),a(o,"taphold",e,x)}},i.taphold_threshold),!0}).on(i.endevent,function h(){n.data("callee2",h),n.data("tapheld",!1),window.clearTimeout(i.hold_timer)}).on(i.moveevent,function u(e){n.data("callee3",u),s=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,r=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2).off(i.moveevent,e(this).data.callee3)}},e.event.special.doubletap={setup:function(){var t,o,n,c,s=this,r=e(s),p=null,h=!1;r.on(i.startevent,function u(e){return e.which&&1!==e.which?!1:(r.data("doubletapped",!1),t=e.target,r.data("callee1",u),n=e.originalEvent,p||(p={position:{x:i.touch_capable?n.touches[0].screenX:e.screenX,y:i.touch_capable?n.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?n.changedTouches[0].pageX-r.position().left:e.pageX-r.position().left),y:Math.round(i.touch_capable?n.changedTouches[0].pageY-r.position().top:e.pageY-r.position().top)},time:Date.now(),target:e.target}),!0)}).on(i.endevent,function l(e){var u=Date.now(),g=r.data("lastTouch")||u+1,d=u-g;if(window.clearTimeout(o),r.data("callee2",l),d100){r.data("doubletapped",!0),window.clearTimeout(i.tap_timer);var f={position:{x:i.touch_capable?e.originalEvent.changedTouches[0].screenX:e.screenX,y:i.touch_capable?e.originalEvent.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?n.changedTouches[0].pageX-r.position().left:e.pageX-r.position().left),y:Math.round(i.touch_capable?n.changedTouches[0].pageY-r.position().top:e.pageY-r.position().top)},time:Date.now(),target:e.target},v={firstTap:p,secondTap:f,interval:f.time-p.time};h||(a(s,"doubletap",e,v),p=null),h=!0,c=window.setTimeout(function(){h=!1},i.doubletap_int)}else r.data("lastTouch",u),o=window.setTimeout(function(){p=null,window.clearTimeout(o)},i.doubletap_int,[e]);r.data("lastTouch",u)})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,o=e(t),n=null,c=null,s={x:0,y:0};o.on(i.startevent,function r(e){return e.which&&1!==e.which?!1:(c=Date.now(),n=e.target,o.data("callee1",r),s.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,s.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,!0)}).on(i.endevent,function p(e){if(o.data("callee2",p),e.target==n){var r=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageX:e.pageX,h=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageY:e.pageY;i.tap_timer=window.setTimeout(function(){if(!o.data("doubletapped")&&!o.data("tapheld")&&s.x==r&&s.y==h){var n=e.originalEvent,p={position:{x:i.touch_capable?n.changedTouches[0].screenX:e.screenX,y:i.touch_capable?n.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?n.changedTouches[0].pageX-o.position().left:e.pageX-o.position().left),y:Math.round(i.touch_capable?n.changedTouches[0].pageY-o.position().top:e.pageY-o.position().top)},time:Date.now(),target:e.target};p.time-c=-i.tap_pixel_range&&g<=i.tap_pixel_range&&d>=-i.tap_pixel_range&&d<=i.tap_pixel_range)){for(var f=e.originalEvent,v=[],w=0;wu.y&&h.y-u.y>d&&(o="swipeup"),h.xg&&(o="swiperight"),h.yd&&(o="swipedown"),h.x>u.x&&h.x-u.x>g&&(o="swipeleft"),void 0!=o&&r){h.x=0,h.y=0,u.x=0,u.y=0,r=!1;var f=t.originalEvent,v={position:{x:i.touch_capable?f.touches[0].screenX:t.screenX,y:i.touch_capable?f.touches[0].screenY:t.screenY},offset:{x:Math.round(i.touch_capable?f.changedTouches[0].pageX-s.position().left:t.pageX-s.position().left),y:Math.round(i.touch_capable?f.changedTouches[0].pageY-s.position().top:t.pageY-s.position().top)},time:Date.now(),target:t.target},w=Math.abs(n.position.x-v.position.x),_=Math.abs(n.position.y-v.position.y),T={startEvnt:n,endEvnt:v,direction:o.replace("swipe",""),xAmount:w,yAmount:_,duration:v.time-n.time};p=!0,s.trigger("swipe",T).trigger(o,T)}}function o(t){s=e(t.currentTarget);var a="";if(s.data("callee3",o),p){var c=s.data("xthreshold"),h=s.data("ythreshold"),u="undefined"!=typeof c&&c!==!1&&parseInt(c)?parseInt(c):i.swipe_h_threshold,l="undefined"!=typeof h&&h!==!1&&parseInt(h)?parseInt(h):i.swipe_v_threshold,g=t.originalEvent,d={position:{x:i.touch_capable?g.changedTouches[0].screenX:t.screenX,y:i.touch_capable?g.changedTouches[0].screenY:t.screenY},offset:{x:Math.round(i.touch_capable?g.changedTouches[0].pageX-s.position().left:t.pageX-s.position().left),y:Math.round(i.touch_capable?g.changedTouches[0].pageY-s.position().top:t.pageY-s.position().top)},time:Date.now(),target:t.target};n.position.y>d.position.y&&n.position.y-d.position.y>l&&(a="swipeup"),n.position.xu&&(a="swiperight"),n.position.yl&&(a="swipedown"),n.position.x>d.position.x&&n.position.x-d.position.x>u&&(a="swipeleft");var f=Math.abs(n.position.x-d.position.x),v=Math.abs(n.position.y-d.position.y),w={startEvnt:n,endEvnt:d,direction:a.replace("swipe",""),xAmount:f,yAmount:v,duration:d.time-n.time};s.trigger("swipeend",w)}r=!1,p=!1}var n,c=this,s=e(c),r=!1,p=!1,h={x:0,y:0},u={x:0,y:0};s.on(i.startevent,t),s.on(i.moveevent,a),s.on(i.endevent,o)},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.moveevent,e(this).data.callee2).off(i.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){function t(e,t){o=t,a(c,o?"scrollstart":"scrollend",e)}var o,n,c=this,s=e(c);s.on(i.scrollevent,function r(e){s.data("callee",r),o||t(e,!0),clearTimeout(n),n=setTimeout(function(){t(e,!1)},50)})},remove:function(){e(this).off(i.scrollevent,e(this).data.callee)}};var c,s,r,p,h,u=e(window),l={0:!0,180:!0};if(i.orientation_support){var g=window.innerWidth||u.width(),d=window.innerHeight||u.height(),f=50;p=g>d&&g-d>f,h=l[window.orientation],(p&&h||!p&&!h)&&(l={"-90":!0,90:!0})}e.event.special.orientationchange=c={setup:function(){return i.orientation_support?!1:(r=s(),u.on("throttledresize",t),!0)},teardown:function(){return i.orientation_support?!1:(u.off("throttledresize",t),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=s(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=s=function(){var e=!0,t=document.documentElement;return e=i.orientation_support?l[window.orientation]:t&&t.clientWidth/t.clientHeight<1.1,e?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",x)},teardown:function(){e(this).off("resize",x)}};var v,w,_,T=250,x=function(){w=Date.now(),_=w-y,_>=T?(y=w,e(this).trigger("throttledresize")):(v&&window.clearTimeout(v),v=window.setTimeout(t,T-_))},y=0;e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); From cc8e2d6f2eef3f46495873cbfc0b94646e166ab6 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Thu, 12 Nov 2015 16:34:04 +0000 Subject: [PATCH 055/149] Sync to 1.0.4 --- src/jquery.mobile-events.js | 39 +++++++++++-------------------------- 1 file changed, 11 insertions(+), 28 deletions(-) diff --git a/src/jquery.mobile-events.js b/src/jquery.mobile-events.js index 1c054d8..c60f769 100644 --- a/src/jquery.mobile-events.js +++ b/src/jquery.mobile-events.js @@ -1,8 +1,8 @@ /*! * jQuery Mobile Events - * by Ben Major (www.ben-major.co.uk) + * by Ben Major (lincweb - www.lincweb.co.uk) * - * Copyright 2011, Ben Major + * Copyright 2011-2015, Ben Major * Licensed under the MIT License: * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -45,12 +45,12 @@ taphold_threshold: 750, doubletap_int: 500, - touch_capable: (window.navigator.msPointerEnabled) ? false : ('ontouchstart' in window && !isChromeDesktop), + touch_capable: ('ontouchstart' in window && !isChromeDesktop), orientation_support: ('orientation' in window && 'onorientationchange' in window), - startevent: (window.navigator.msPointerEnabled) ? 'MSPointerDown' : (('ontouchstart' in window && !isChromeDesktop) ? 'touchstart' : 'mousedown'), - endevent: (window.navigator.msPointerEnabled) ? 'MSPointerUp' : (('ontouchstart' in window && !isChromeDesktop) ? 'touchend' : 'mouseup'), - moveevent: (window.navigator.msPointerEnabled) ? 'MSPointerMove' : (('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'mousemove'), + startevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchstart' : 'mousedown'), + endevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchend' : 'mouseup'), + moveevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'mousemove'), tapevent: ('ontouchstart' in window && !isChromeDesktop) ? 'tap' : 'click', scrollevent: ('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'scroll', @@ -78,10 +78,12 @@ // 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; @@ -100,7 +102,7 @@ 'time': Date.now(), 'target': e.target }; - + triggerCustomEvent(thisObject, 'tapstart', e, touchData); return true; }); @@ -493,26 +495,7 @@ touchData.push( touch ); } - switch( touches.length ) - { - case 1: - eventName = 'tap'; - break; - - case 2: - eventName = 'tap2'; - break; - - case 3: - eventName = 'tap3'; - break; - - case 4: - eventName = 'tap4'; - break; - } - - triggerCustomEvent(thisObject, eventName, e, touchData); + triggerCustomEvent(thisObject, 'tap', e, touchData); } }); }, From 3176d74fc993afcdee76942b5d6709b0d848802f Mon Sep 17 00:00:00 2001 From: Ben Major Date: Thu, 12 Nov 2015 16:37:15 +0000 Subject: [PATCH 056/149] Updated bower package for 1.0.4 --- bower.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bower.json b/bower.json index 1b5dcdc..2cc9c43 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "jquery-touch-events", - "version": "1.0.1", - "main": "src/1.0.1/jquery.mobile-events.js", + "version": "1.0.4", + "main": "src/1.0.4/jquery.mobile-events.js", "ignore": [ "bower.json" ], From 187574a6244a2537d8ca6637d5135223d12525da Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 13 Nov 2015 12:05:31 +0000 Subject: [PATCH 057/149] Update bower.json --- bower.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bower.json b/bower.json index 2cc9c43..9ef7b56 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "jquery-touch-events", "version": "1.0.4", - "main": "src/1.0.4/jquery.mobile-events.js", + "main": "src/jquery.mobile-events.js", "ignore": [ "bower.json" ], From c46d0056ccf12ed678cf4f3e91ff3b362ab75f09 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 13 Nov 2015 12:58:58 +0000 Subject: [PATCH 058/149] Fixed offset error --- src/1.0.5/jquery.mobile-events.js | 867 ++++++++++++++++++++++++++++++ 1 file changed, 867 insertions(+) create mode 100644 src/1.0.5/jquery.mobile-events.js diff --git a/src/1.0.5/jquery.mobile-events.js b/src/1.0.5/jquery.mobile-events.js new file mode 100644 index 0000000..c453f62 --- /dev/null +++ b/src/1.0.5/jquery.mobile-events.js @@ -0,0 +1,867 @@ +/*! + * jQuery Mobile Events + * by Ben Major (lincweb - www.lincweb.co.uk) + * + * Copyright 2011-2015, 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 || {}; + + // navigator.userAgent.toLowerCase() isn't reliable for Chrome installs + // on mobile devices. As such, we will create a boolean isChromeDesktop + // The reason that we need to do this is because Chrome annoyingly + // purports support for touch events even if the underlying hardware + // does not! + var agent = navigator.userAgent.toLowerCase(), + isChromeDesktop = (agent.indexOf('chrome') > -1 && ((agent.indexOf('windows') > -1) || (agent.indexOf('macintosh') > -1) || (agent.indexOf('linux') > -1)) && agent.indexOf('mobile') < 0 && agent.indexOf('android') < 0), + + settings = { + tap_pixel_range: 5, + swipe_h_threshold: 50, + swipe_v_threshold: 50, + taphold_threshold: 750, + doubletap_int: 500, + + touch_capable: ('ontouchstart' in window && !isChromeDesktop), + orientation_support: ('orientation' in window && 'onorientationchange' in window), + + startevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchstart' : 'mousedown'), + endevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchend' : 'mouseup'), + moveevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'mousemove'), + tapevent: ('ontouchstart' in window && !isChromeDesktop) ? 'tap' : 'click', + scrollevent: ('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'scroll', + + hold_timer: null, + tap_timer: null + }; + + // 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; }; + + // Add Event shortcuts: + $.each(['tapstart', 'tapend', 'tapmove', 'tap', 'tap2', 'tap3', 'tap4', 'singletap', 'doubletap', 'taphold', 'swipe', 'swipeup', 'swiperight', 'swipedown', 'swipeleft', 'swipeend', 'scrollstart', 'scrollend', 'orientationchange'], 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 origEvent = e.originalEvent, + touchData = { + 'position': { + 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.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 origEvent = e.originalEvent, + touchData = { + 'position': { + 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.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 origEvent = e.originalEvent; + var touchData = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.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].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 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; + + settings.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(), + endPosition = { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + endOffset = { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) + }; + var duration = end_time - start_time; + + // Build the touch data: + var touchData = { + 'startTime': start_time, + 'endTime': end_time, + 'startPosition': startPosition, + 'startOffset': startOffset, + 'endPosition': endPosition, + 'endOffset': endOffset, + 'duration': duration, + 'target': e.target + }; + $this.data('callee1', tapHoldFunc1); + triggerCustomEvent(thisObject, 'taphold', e, touchData); + } + }, settings.taphold_threshold); + + return true; + } + }).on(settings.endevent, function tapHoldFunc2() { + $this.data('callee2', tapHoldFunc2); + $this.data('tapheld', false); + window.clearTimeout(settings.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) { + firstTap = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) + }, + 'time': Date.now(), + 'target': e.target + }; + } + + 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 == origTarget) && delta > 100) { + $this.data('doubletapped', true); + window.clearTimeout(settings.tap_timer); + + // Now get the current event: + var lastTap = { + 'position': { + 'x': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) + }, + 'time': Date.now(), + 'target': e.target + }; + + 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; + var 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 () { + if (!$this.data('doubletapped') && !$this.data('tapheld') && (start_pos.x == end_pos_x) && (start_pos.y == end_pos_y)) { + var origEvent = e.originalEvent; + var touchData = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.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 origEvent = e.originalEvent; + var touchData = [ ]; + + for( var i = 0; i < touches.length; i++) + { + var touch = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[i].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[i].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) + }, + 'time': Date.now(), + 'target': e.target + }; + + touchData.push( touch ); + } + + triggerCustomEvent(thisObject, 'tap', 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 origEvent = e.originalEvent; + // Read event data into our startEvt: + startEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.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 (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 (originalCoord.x > finalCoord.x && (originalCoord.x - finalCoord.x > h_threshold)) { + swipedir = 'swipeleft'; + } + 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 origEvent = e.originalEvent; + var endEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.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 origEvent = e.originalEvent; + var endEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) + }, + 'time': Date.now(), + '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); + + 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' + }, function (e, srcE) { + $.event.special[e] = { + setup: function () { + $(this).on(srcE, $.noop); + } + }; + }); + +}(jQuery)); From a4a446beed27143fa78bb5e06a0d191327fa8964 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 13 Nov 2015 13:00:12 +0000 Subject: [PATCH 059/149] Fixed offset error --- src/1.0.5/jquery.mobile-events.min.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/1.0.5/jquery.mobile-events.min.js diff --git a/src/1.0.5/jquery.mobile-events.min.js b/src/1.0.5/jquery.mobile-events.min.js new file mode 100644 index 0000000..6176530 --- /dev/null +++ b/src/1.0.5/jquery.mobile-events.min.js @@ -0,0 +1 @@ +"use strict";!function(e){function t(){var e=s();e!==r&&(r=e,u.trigger("orientationchange"))}function a(t,a,o,n){var i=o.type;o.type=a,e.event.dispatch.call(t,o,n),o.type=i}e.attrFn=e.attrFn||{};var o=navigator.userAgent.toLowerCase(),n=o.indexOf("chrome")>-1&&(o.indexOf("windows")>-1||o.indexOf("macintosh")>-1||o.indexOf("linux")>-1)&&o.indexOf("mobile")<0&&o.indexOf("android")<0,i={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:"ontouchstart"in window&&!n,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:"ontouchstart"in window&&!n?"touchstart":"mousedown",endevent:"ontouchstart"in window&&!n?"touchend":"mouseup",moveevent:"ontouchstart"in window&&!n?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!n?"tap":"click",scrollevent:"ontouchstart"in window&&!n?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.isTouchCapable=function(){return i.touch_capable},e.getStartEvent=function(){return i.startevent},e.getEndEvent=function(){return i.endevent},e.getMoveEvent=function(){return i.moveevent},e.getTapEvent=function(){return i.tapevent},e.getScrollEvent=function(){return i.scrollevent},e.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],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(i.startevent,function n(e){if(o.data("callee",n),e.which&&1!==e.which)return!1;var c=e.originalEvent,s={position:{x:i.touch_capable?c.touches[0].screenX:e.screenX,y:i.touch_capable?c.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?c.changedTouches[0].pageX-o.offset().left:e.pageX-o.offset().left),y:Math.round(i.touch_capable?c.changedTouches[0].pageY-o.offset().top:e.pageY-o.offset().top)},time:Date.now(),target:e.target};return a(t,"tapstart",e,s),!0})},remove:function(){e(this).off(i.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,o=e(t);o.on(i.moveevent,function n(e){o.data("callee",n);var c=e.originalEvent,s={position:{x:i.touch_capable?c.touches[0].screenX:e.screenX,y:i.touch_capable?c.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?c.changedTouches[0].pageX-o.offset().left:e.pageX-o.offset().left),y:Math.round(i.touch_capable?c.changedTouches[0].pageY-o.offset().top:e.pageY-o.offset().top)},time:Date.now(),target:e.target};return a(t,"tapmove",e,s),!0})},remove:function(){e(this).off(i.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,o=e(t);o.on(i.endevent,function n(e){o.data("callee",n);var c=e.originalEvent,s={position:{x:i.touch_capable?c.changedTouches[0].screenX:e.screenX,y:i.touch_capable?c.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?c.changedTouches[0].pageX-o.offset().left:e.pageX-o.offset().left),y:Math.round(i.touch_capable?c.changedTouches[0].pageY-o.offset().top:e.pageY-o.offset().top)},time:Date.now(),target:e.target};return a(t,"tapend",e,s),!0})},remove:function(){e(this).off(i.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,o=this,n=e(o),c={x:0,y:0},s=0,r=0;n.on(i.startevent,function p(e){if(e.which&&1!==e.which)return!1;n.data("tapheld",!1),t=e.target;var h=e.originalEvent,u=Date.now(),l={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},f={x:i.touch_capable?h.touches[0].pageX-h.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?h.touches[0].pageY-h.touches[0].target.offsetTop:e.offsetY};return c.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,c.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,s=c.x,r=c.y,i.hold_timer=window.setTimeout(function(){var g=c.x-s,d=c.y-r;if(e.target==t&&(c.x==s&&c.y==r||g>=-i.tap_pixel_range&&g<=i.tap_pixel_range&&d>=-i.tap_pixel_range&&d<=i.tap_pixel_range)){n.data("tapheld",!0);var v=Date.now(),w={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},_={x:Math.round(i.touch_capable?h.changedTouches[0].pageX-n.offset().left:e.pageX-n.offset().left),y:Math.round(i.touch_capable?h.changedTouches[0].pageY-n.offset().top:e.pageY-n.offset().top)},T=v-u,x={startTime:u,endTime:v,startPosition:l,startOffset:f,endPosition:w,endOffset:_,duration:T,target:e.target};n.data("callee1",p),a(o,"taphold",e,x)}},i.taphold_threshold),!0}).on(i.endevent,function h(){n.data("callee2",h),n.data("tapheld",!1),window.clearTimeout(i.hold_timer)}).on(i.moveevent,function u(e){n.data("callee3",u),s=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,r=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2).off(i.moveevent,e(this).data.callee3)}},e.event.special.doubletap={setup:function(){var t,o,n,c,s=this,r=e(s),p=null,h=!1;r.on(i.startevent,function u(e){return e.which&&1!==e.which?!1:(r.data("doubletapped",!1),t=e.target,r.data("callee1",u),n=e.originalEvent,p||(p={position:{x:i.touch_capable?n.touches[0].screenX:e.screenX,y:i.touch_capable?n.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?n.changedTouches[0].pageX-r.offset().left:e.pageX-r.offset().left),y:Math.round(i.touch_capable?n.changedTouches[0].pageY-r.offset().top:e.pageY-r.offset().top)},time:Date.now(),target:e.target}),!0)}).on(i.endevent,function l(e){var u=Date.now(),f=r.data("lastTouch")||u+1,g=u-f;if(window.clearTimeout(o),r.data("callee2",l),g100){r.data("doubletapped",!0),window.clearTimeout(i.tap_timer);var d={position:{x:i.touch_capable?e.originalEvent.changedTouches[0].screenX:e.screenX,y:i.touch_capable?e.originalEvent.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?n.changedTouches[0].pageX-r.offset().left:e.pageX-r.offset().left),y:Math.round(i.touch_capable?n.changedTouches[0].pageY-r.offset().top:e.pageY-r.offset().top)},time:Date.now(),target:e.target},v={firstTap:p,secondTap:d,interval:d.time-p.time};h||(a(s,"doubletap",e,v),p=null),h=!0,c=window.setTimeout(function(){h=!1},i.doubletap_int)}else r.data("lastTouch",u),o=window.setTimeout(function(){p=null,window.clearTimeout(o)},i.doubletap_int,[e]);r.data("lastTouch",u)})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,o=e(t),n=null,c=null,s={x:0,y:0};o.on(i.startevent,function r(e){return e.which&&1!==e.which?!1:(c=Date.now(),n=e.target,o.data("callee1",r),s.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,s.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,!0)}).on(i.endevent,function p(e){if(o.data("callee2",p),e.target==n){var r=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageX:e.pageX,h=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageY:e.pageY;i.tap_timer=window.setTimeout(function(){if(!o.data("doubletapped")&&!o.data("tapheld")&&s.x==r&&s.y==h){var n=e.originalEvent,p={position:{x:i.touch_capable?n.changedTouches[0].screenX:e.screenX,y:i.touch_capable?n.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?n.changedTouches[0].pageX-o.offset().left:e.pageX-o.offset().left),y:Math.round(i.touch_capable?n.changedTouches[0].pageY-o.offset().top:e.pageY-o.offset().top)},time:Date.now(),target:e.target};p.time-c=-i.tap_pixel_range&&f<=i.tap_pixel_range&&g>=-i.tap_pixel_range&&g<=i.tap_pixel_range)){for(var d=e.originalEvent,v=[],w=0;wu.y&&h.y-u.y>g&&(o="swipeup"),h.xf&&(o="swiperight"),h.yg&&(o="swipedown"),h.x>u.x&&h.x-u.x>f&&(o="swipeleft"),void 0!=o&&r){h.x=0,h.y=0,u.x=0,u.y=0,r=!1;var d=t.originalEvent,v={position:{x:i.touch_capable?d.touches[0].screenX:t.screenX,y:i.touch_capable?d.touches[0].screenY:t.screenY},offset:{x:Math.round(i.touch_capable?d.changedTouches[0].pageX-s.offset().left:t.pageX-s.offset().left),y:Math.round(i.touch_capable?d.changedTouches[0].pageY-s.offset().top:t.pageY-s.offset().top)},time:Date.now(),target:t.target},w=Math.abs(n.position.x-v.position.x),_=Math.abs(n.position.y-v.position.y),T={startEvnt:n,endEvnt:v,direction:o.replace("swipe",""),xAmount:w,yAmount:_,duration:v.time-n.time};p=!0,s.trigger("swipe",T).trigger(o,T)}}function o(t){s=e(t.currentTarget);var a="";if(s.data("callee3",o),p){var c=s.data("xthreshold"),h=s.data("ythreshold"),u="undefined"!=typeof c&&c!==!1&&parseInt(c)?parseInt(c):i.swipe_h_threshold,l="undefined"!=typeof h&&h!==!1&&parseInt(h)?parseInt(h):i.swipe_v_threshold,f=t.originalEvent,g={position:{x:i.touch_capable?f.changedTouches[0].screenX:t.screenX,y:i.touch_capable?f.changedTouches[0].screenY:t.screenY},offset:{x:Math.round(i.touch_capable?f.changedTouches[0].pageX-s.offset().left:t.pageX-s.offset().left),y:Math.round(i.touch_capable?f.changedTouches[0].pageY-s.offset().top:t.pageY-s.offset().top)},time:Date.now(),target:t.target};n.position.y>g.position.y&&n.position.y-g.position.y>l&&(a="swipeup"),n.position.xu&&(a="swiperight"),n.position.yl&&(a="swipedown"),n.position.x>g.position.x&&n.position.x-g.position.x>u&&(a="swipeleft");var d=Math.abs(n.position.x-g.position.x),v=Math.abs(n.position.y-g.position.y),w={startEvnt:n,endEvnt:g,direction:a.replace("swipe",""),xAmount:d,yAmount:v,duration:g.time-n.time};s.trigger("swipeend",w)}r=!1,p=!1}var n,c=this,s=e(c),r=!1,p=!1,h={x:0,y:0},u={x:0,y:0};s.on(i.startevent,t),s.on(i.moveevent,a),s.on(i.endevent,o)},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.moveevent,e(this).data.callee2).off(i.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){function t(e,t){o=t,a(c,o?"scrollstart":"scrollend",e)}var o,n,c=this,s=e(c);s.on(i.scrollevent,function r(e){s.data("callee",r),o||t(e,!0),clearTimeout(n),n=setTimeout(function(){t(e,!1)},50)})},remove:function(){e(this).off(i.scrollevent,e(this).data.callee)}};var c,s,r,p,h,u=e(window),l={0:!0,180:!0};if(i.orientation_support){var f=window.innerWidth||u.width(),g=window.innerHeight||u.height(),d=50;p=f>g&&f-g>d,h=l[window.orientation],(p&&h||!p&&!h)&&(l={"-90":!0,90:!0})}e.event.special.orientationchange=c={setup:function(){return i.orientation_support?!1:(r=s(),u.on("throttledresize",t),!0)},teardown:function(){return i.orientation_support?!1:(u.off("throttledresize",t),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=s(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=s=function(){var e=!0,t=document.documentElement;return e=i.orientation_support?l[window.orientation]:t&&t.clientWidth/t.clientHeight<1.1,e?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",x)},teardown:function(){e(this).off("resize",x)}};var v,w,_,T=250,x=function(){w=Date.now(),_=w-y,_>=T?(y=w,e(this).trigger("throttledresize")):(v&&window.clearTimeout(v),v=window.setTimeout(t,T-_))},y=0;e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); From 1d18e4252ba89691e3730e44116fa56a8fd028d0 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 13 Nov 2015 13:01:05 +0000 Subject: [PATCH 060/149] Sync to 1.0.5 --- src/jquery.mobile-events.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jquery.mobile-events.min.js b/src/jquery.mobile-events.min.js index 5db6423..6176530 100644 --- a/src/jquery.mobile-events.min.js +++ b/src/jquery.mobile-events.min.js @@ -1 +1 @@ -"use strict";!function(e){function t(){var e=s();e!==r&&(r=e,u.trigger("orientationchange"))}function a(t,a,o,n){var i=o.type;o.type=a,e.event.dispatch.call(t,o,n),o.type=i}e.attrFn=e.attrFn||{};var o=navigator.userAgent.toLowerCase(),n=o.indexOf("chrome")>-1&&(o.indexOf("windows")>-1||o.indexOf("macintosh")>-1||o.indexOf("linux")>-1)&&o.indexOf("mobile")<0&&o.indexOf("android")<0,i={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:"ontouchstart"in window&&!n,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:"ontouchstart"in window&&!n?"touchstart":"mousedown",endevent:"ontouchstart"in window&&!n?"touchend":"mouseup",moveevent:"ontouchstart"in window&&!n?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!n?"tap":"click",scrollevent:"ontouchstart"in window&&!n?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.isTouchCapable=function(){return i.touch_capable},e.getStartEvent=function(){return i.startevent},e.getEndEvent=function(){return i.endevent},e.getMoveEvent=function(){return i.moveevent},e.getTapEvent=function(){return i.tapevent},e.getScrollEvent=function(){return i.scrollevent},e.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],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(i.startevent,function n(e){if(o.data("callee",n),e.which&&1!==e.which)return!1;var c=e.originalEvent,s={position:{x:i.touch_capable?c.touches[0].screenX:e.screenX,y:i.touch_capable?c.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?c.changedTouches[0].pageX-o.position().left:e.pageX-o.position().left),y:Math.round(i.touch_capable?c.changedTouches[0].pageY-o.position().top:e.pageY-o.position().top)},time:Date.now(),target:e.target};return a(t,"tapstart",e,s),!0})},remove:function(){e(this).off(i.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,o=e(t);o.on(i.moveevent,function n(e){o.data("callee",n);var c=e.originalEvent,s={position:{x:i.touch_capable?c.touches[0].screenX:e.screenX,y:i.touch_capable?c.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?c.changedTouches[0].pageX-o.position().left:e.pageX-o.position().left),y:Math.round(i.touch_capable?c.changedTouches[0].pageY-o.position().top:e.pageY-o.position().top)},time:Date.now(),target:e.target};return a(t,"tapmove",e,s),!0})},remove:function(){e(this).off(i.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,o=e(t);o.on(i.endevent,function n(e){o.data("callee",n);var c=e.originalEvent,s={position:{x:i.touch_capable?c.changedTouches[0].screenX:e.screenX,y:i.touch_capable?c.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?c.changedTouches[0].pageX-o.position().left:e.pageX-o.position().left),y:Math.round(i.touch_capable?c.changedTouches[0].pageY-o.position().top:e.pageY-o.position().top)},time:Date.now(),target:e.target};return a(t,"tapend",e,s),!0})},remove:function(){e(this).off(i.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,o=this,n=e(o),c={x:0,y:0},s=0,r=0;n.on(i.startevent,function p(e){if(e.which&&1!==e.which)return!1;n.data("tapheld",!1),t=e.target;var h=e.originalEvent,u=Date.now(),l={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},g={x:i.touch_capable?h.touches[0].pageX-h.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?h.touches[0].pageY-h.touches[0].target.offsetTop:e.offsetY};return c.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,c.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,s=c.x,r=c.y,i.hold_timer=window.setTimeout(function(){var d=c.x-s,f=c.y-r;if(e.target==t&&(c.x==s&&c.y==r||d>=-i.tap_pixel_range&&d<=i.tap_pixel_range&&f>=-i.tap_pixel_range&&f<=i.tap_pixel_range)){n.data("tapheld",!0);var v=Date.now(),w={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},_={x:Math.round(i.touch_capable?h.changedTouches[0].pageX-n.position().left:e.pageX-n.position().left),y:Math.round(i.touch_capable?h.changedTouches[0].pageY-n.position().top:e.pageY-n.position().top)},T=v-u,x={startTime:u,endTime:v,startPosition:l,startOffset:g,endPosition:w,endOffset:_,duration:T,target:e.target};n.data("callee1",p),a(o,"taphold",e,x)}},i.taphold_threshold),!0}).on(i.endevent,function h(){n.data("callee2",h),n.data("tapheld",!1),window.clearTimeout(i.hold_timer)}).on(i.moveevent,function u(e){n.data("callee3",u),s=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,r=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2).off(i.moveevent,e(this).data.callee3)}},e.event.special.doubletap={setup:function(){var t,o,n,c,s=this,r=e(s),p=null,h=!1;r.on(i.startevent,function u(e){return e.which&&1!==e.which?!1:(r.data("doubletapped",!1),t=e.target,r.data("callee1",u),n=e.originalEvent,p||(p={position:{x:i.touch_capable?n.touches[0].screenX:e.screenX,y:i.touch_capable?n.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?n.changedTouches[0].pageX-r.position().left:e.pageX-r.position().left),y:Math.round(i.touch_capable?n.changedTouches[0].pageY-r.position().top:e.pageY-r.position().top)},time:Date.now(),target:e.target}),!0)}).on(i.endevent,function l(e){var u=Date.now(),g=r.data("lastTouch")||u+1,d=u-g;if(window.clearTimeout(o),r.data("callee2",l),d100){r.data("doubletapped",!0),window.clearTimeout(i.tap_timer);var f={position:{x:i.touch_capable?e.originalEvent.changedTouches[0].screenX:e.screenX,y:i.touch_capable?e.originalEvent.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?n.changedTouches[0].pageX-r.position().left:e.pageX-r.position().left),y:Math.round(i.touch_capable?n.changedTouches[0].pageY-r.position().top:e.pageY-r.position().top)},time:Date.now(),target:e.target},v={firstTap:p,secondTap:f,interval:f.time-p.time};h||(a(s,"doubletap",e,v),p=null),h=!0,c=window.setTimeout(function(){h=!1},i.doubletap_int)}else r.data("lastTouch",u),o=window.setTimeout(function(){p=null,window.clearTimeout(o)},i.doubletap_int,[e]);r.data("lastTouch",u)})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,o=e(t),n=null,c=null,s={x:0,y:0};o.on(i.startevent,function r(e){return e.which&&1!==e.which?!1:(c=Date.now(),n=e.target,o.data("callee1",r),s.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,s.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,!0)}).on(i.endevent,function p(e){if(o.data("callee2",p),e.target==n){var r=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageX:e.pageX,h=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageY:e.pageY;i.tap_timer=window.setTimeout(function(){if(!o.data("doubletapped")&&!o.data("tapheld")&&s.x==r&&s.y==h){var n=e.originalEvent,p={position:{x:i.touch_capable?n.changedTouches[0].screenX:e.screenX,y:i.touch_capable?n.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?n.changedTouches[0].pageX-o.position().left:e.pageX-o.position().left),y:Math.round(i.touch_capable?n.changedTouches[0].pageY-o.position().top:e.pageY-o.position().top)},time:Date.now(),target:e.target};p.time-c=-i.tap_pixel_range&&g<=i.tap_pixel_range&&d>=-i.tap_pixel_range&&d<=i.tap_pixel_range)){for(var f=e.originalEvent,v=[],w=0;wu.y&&h.y-u.y>d&&(o="swipeup"),h.xg&&(o="swiperight"),h.yd&&(o="swipedown"),h.x>u.x&&h.x-u.x>g&&(o="swipeleft"),void 0!=o&&r){h.x=0,h.y=0,u.x=0,u.y=0,r=!1;var f=t.originalEvent,v={position:{x:i.touch_capable?f.touches[0].screenX:t.screenX,y:i.touch_capable?f.touches[0].screenY:t.screenY},offset:{x:Math.round(i.touch_capable?f.changedTouches[0].pageX-s.position().left:t.pageX-s.position().left),y:Math.round(i.touch_capable?f.changedTouches[0].pageY-s.position().top:t.pageY-s.position().top)},time:Date.now(),target:t.target},w=Math.abs(n.position.x-v.position.x),_=Math.abs(n.position.y-v.position.y),T={startEvnt:n,endEvnt:v,direction:o.replace("swipe",""),xAmount:w,yAmount:_,duration:v.time-n.time};p=!0,s.trigger("swipe",T).trigger(o,T)}}function o(t){s=e(t.currentTarget);var a="";if(s.data("callee3",o),p){var c=s.data("xthreshold"),h=s.data("ythreshold"),u="undefined"!=typeof c&&c!==!1&&parseInt(c)?parseInt(c):i.swipe_h_threshold,l="undefined"!=typeof h&&h!==!1&&parseInt(h)?parseInt(h):i.swipe_v_threshold,g=t.originalEvent,d={position:{x:i.touch_capable?g.changedTouches[0].screenX:t.screenX,y:i.touch_capable?g.changedTouches[0].screenY:t.screenY},offset:{x:Math.round(i.touch_capable?g.changedTouches[0].pageX-s.position().left:t.pageX-s.position().left),y:Math.round(i.touch_capable?g.changedTouches[0].pageY-s.position().top:t.pageY-s.position().top)},time:Date.now(),target:t.target};n.position.y>d.position.y&&n.position.y-d.position.y>l&&(a="swipeup"),n.position.xu&&(a="swiperight"),n.position.yl&&(a="swipedown"),n.position.x>d.position.x&&n.position.x-d.position.x>u&&(a="swipeleft");var f=Math.abs(n.position.x-d.position.x),v=Math.abs(n.position.y-d.position.y),w={startEvnt:n,endEvnt:d,direction:a.replace("swipe",""),xAmount:f,yAmount:v,duration:d.time-n.time};s.trigger("swipeend",w)}r=!1,p=!1}var n,c=this,s=e(c),r=!1,p=!1,h={x:0,y:0},u={x:0,y:0};s.on(i.startevent,t),s.on(i.moveevent,a),s.on(i.endevent,o)},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.moveevent,e(this).data.callee2).off(i.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){function t(e,t){o=t,a(c,o?"scrollstart":"scrollend",e)}var o,n,c=this,s=e(c);s.on(i.scrollevent,function r(e){s.data("callee",r),o||t(e,!0),clearTimeout(n),n=setTimeout(function(){t(e,!1)},50)})},remove:function(){e(this).off(i.scrollevent,e(this).data.callee)}};var c,s,r,p,h,u=e(window),l={0:!0,180:!0};if(i.orientation_support){var g=window.innerWidth||u.width(),d=window.innerHeight||u.height(),f=50;p=g>d&&g-d>f,h=l[window.orientation],(p&&h||!p&&!h)&&(l={"-90":!0,90:!0})}e.event.special.orientationchange=c={setup:function(){return i.orientation_support?!1:(r=s(),u.on("throttledresize",t),!0)},teardown:function(){return i.orientation_support?!1:(u.off("throttledresize",t),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=s(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=s=function(){var e=!0,t=document.documentElement;return e=i.orientation_support?l[window.orientation]:t&&t.clientWidth/t.clientHeight<1.1,e?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",x)},teardown:function(){e(this).off("resize",x)}};var v,w,_,T=250,x=function(){w=Date.now(),_=w-y,_>=T?(y=w,e(this).trigger("throttledresize")):(v&&window.clearTimeout(v),v=window.setTimeout(t,T-_))},y=0;e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); +"use strict";!function(e){function t(){var e=s();e!==r&&(r=e,u.trigger("orientationchange"))}function a(t,a,o,n){var i=o.type;o.type=a,e.event.dispatch.call(t,o,n),o.type=i}e.attrFn=e.attrFn||{};var o=navigator.userAgent.toLowerCase(),n=o.indexOf("chrome")>-1&&(o.indexOf("windows")>-1||o.indexOf("macintosh")>-1||o.indexOf("linux")>-1)&&o.indexOf("mobile")<0&&o.indexOf("android")<0,i={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:"ontouchstart"in window&&!n,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:"ontouchstart"in window&&!n?"touchstart":"mousedown",endevent:"ontouchstart"in window&&!n?"touchend":"mouseup",moveevent:"ontouchstart"in window&&!n?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!n?"tap":"click",scrollevent:"ontouchstart"in window&&!n?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.isTouchCapable=function(){return i.touch_capable},e.getStartEvent=function(){return i.startevent},e.getEndEvent=function(){return i.endevent},e.getMoveEvent=function(){return i.moveevent},e.getTapEvent=function(){return i.tapevent},e.getScrollEvent=function(){return i.scrollevent},e.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],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(i.startevent,function n(e){if(o.data("callee",n),e.which&&1!==e.which)return!1;var c=e.originalEvent,s={position:{x:i.touch_capable?c.touches[0].screenX:e.screenX,y:i.touch_capable?c.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?c.changedTouches[0].pageX-o.offset().left:e.pageX-o.offset().left),y:Math.round(i.touch_capable?c.changedTouches[0].pageY-o.offset().top:e.pageY-o.offset().top)},time:Date.now(),target:e.target};return a(t,"tapstart",e,s),!0})},remove:function(){e(this).off(i.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,o=e(t);o.on(i.moveevent,function n(e){o.data("callee",n);var c=e.originalEvent,s={position:{x:i.touch_capable?c.touches[0].screenX:e.screenX,y:i.touch_capable?c.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?c.changedTouches[0].pageX-o.offset().left:e.pageX-o.offset().left),y:Math.round(i.touch_capable?c.changedTouches[0].pageY-o.offset().top:e.pageY-o.offset().top)},time:Date.now(),target:e.target};return a(t,"tapmove",e,s),!0})},remove:function(){e(this).off(i.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,o=e(t);o.on(i.endevent,function n(e){o.data("callee",n);var c=e.originalEvent,s={position:{x:i.touch_capable?c.changedTouches[0].screenX:e.screenX,y:i.touch_capable?c.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?c.changedTouches[0].pageX-o.offset().left:e.pageX-o.offset().left),y:Math.round(i.touch_capable?c.changedTouches[0].pageY-o.offset().top:e.pageY-o.offset().top)},time:Date.now(),target:e.target};return a(t,"tapend",e,s),!0})},remove:function(){e(this).off(i.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,o=this,n=e(o),c={x:0,y:0},s=0,r=0;n.on(i.startevent,function p(e){if(e.which&&1!==e.which)return!1;n.data("tapheld",!1),t=e.target;var h=e.originalEvent,u=Date.now(),l={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},f={x:i.touch_capable?h.touches[0].pageX-h.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?h.touches[0].pageY-h.touches[0].target.offsetTop:e.offsetY};return c.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,c.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,s=c.x,r=c.y,i.hold_timer=window.setTimeout(function(){var g=c.x-s,d=c.y-r;if(e.target==t&&(c.x==s&&c.y==r||g>=-i.tap_pixel_range&&g<=i.tap_pixel_range&&d>=-i.tap_pixel_range&&d<=i.tap_pixel_range)){n.data("tapheld",!0);var v=Date.now(),w={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},_={x:Math.round(i.touch_capable?h.changedTouches[0].pageX-n.offset().left:e.pageX-n.offset().left),y:Math.round(i.touch_capable?h.changedTouches[0].pageY-n.offset().top:e.pageY-n.offset().top)},T=v-u,x={startTime:u,endTime:v,startPosition:l,startOffset:f,endPosition:w,endOffset:_,duration:T,target:e.target};n.data("callee1",p),a(o,"taphold",e,x)}},i.taphold_threshold),!0}).on(i.endevent,function h(){n.data("callee2",h),n.data("tapheld",!1),window.clearTimeout(i.hold_timer)}).on(i.moveevent,function u(e){n.data("callee3",u),s=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,r=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2).off(i.moveevent,e(this).data.callee3)}},e.event.special.doubletap={setup:function(){var t,o,n,c,s=this,r=e(s),p=null,h=!1;r.on(i.startevent,function u(e){return e.which&&1!==e.which?!1:(r.data("doubletapped",!1),t=e.target,r.data("callee1",u),n=e.originalEvent,p||(p={position:{x:i.touch_capable?n.touches[0].screenX:e.screenX,y:i.touch_capable?n.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?n.changedTouches[0].pageX-r.offset().left:e.pageX-r.offset().left),y:Math.round(i.touch_capable?n.changedTouches[0].pageY-r.offset().top:e.pageY-r.offset().top)},time:Date.now(),target:e.target}),!0)}).on(i.endevent,function l(e){var u=Date.now(),f=r.data("lastTouch")||u+1,g=u-f;if(window.clearTimeout(o),r.data("callee2",l),g100){r.data("doubletapped",!0),window.clearTimeout(i.tap_timer);var d={position:{x:i.touch_capable?e.originalEvent.changedTouches[0].screenX:e.screenX,y:i.touch_capable?e.originalEvent.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?n.changedTouches[0].pageX-r.offset().left:e.pageX-r.offset().left),y:Math.round(i.touch_capable?n.changedTouches[0].pageY-r.offset().top:e.pageY-r.offset().top)},time:Date.now(),target:e.target},v={firstTap:p,secondTap:d,interval:d.time-p.time};h||(a(s,"doubletap",e,v),p=null),h=!0,c=window.setTimeout(function(){h=!1},i.doubletap_int)}else r.data("lastTouch",u),o=window.setTimeout(function(){p=null,window.clearTimeout(o)},i.doubletap_int,[e]);r.data("lastTouch",u)})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,o=e(t),n=null,c=null,s={x:0,y:0};o.on(i.startevent,function r(e){return e.which&&1!==e.which?!1:(c=Date.now(),n=e.target,o.data("callee1",r),s.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,s.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,!0)}).on(i.endevent,function p(e){if(o.data("callee2",p),e.target==n){var r=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageX:e.pageX,h=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageY:e.pageY;i.tap_timer=window.setTimeout(function(){if(!o.data("doubletapped")&&!o.data("tapheld")&&s.x==r&&s.y==h){var n=e.originalEvent,p={position:{x:i.touch_capable?n.changedTouches[0].screenX:e.screenX,y:i.touch_capable?n.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?n.changedTouches[0].pageX-o.offset().left:e.pageX-o.offset().left),y:Math.round(i.touch_capable?n.changedTouches[0].pageY-o.offset().top:e.pageY-o.offset().top)},time:Date.now(),target:e.target};p.time-c=-i.tap_pixel_range&&f<=i.tap_pixel_range&&g>=-i.tap_pixel_range&&g<=i.tap_pixel_range)){for(var d=e.originalEvent,v=[],w=0;wu.y&&h.y-u.y>g&&(o="swipeup"),h.xf&&(o="swiperight"),h.yg&&(o="swipedown"),h.x>u.x&&h.x-u.x>f&&(o="swipeleft"),void 0!=o&&r){h.x=0,h.y=0,u.x=0,u.y=0,r=!1;var d=t.originalEvent,v={position:{x:i.touch_capable?d.touches[0].screenX:t.screenX,y:i.touch_capable?d.touches[0].screenY:t.screenY},offset:{x:Math.round(i.touch_capable?d.changedTouches[0].pageX-s.offset().left:t.pageX-s.offset().left),y:Math.round(i.touch_capable?d.changedTouches[0].pageY-s.offset().top:t.pageY-s.offset().top)},time:Date.now(),target:t.target},w=Math.abs(n.position.x-v.position.x),_=Math.abs(n.position.y-v.position.y),T={startEvnt:n,endEvnt:v,direction:o.replace("swipe",""),xAmount:w,yAmount:_,duration:v.time-n.time};p=!0,s.trigger("swipe",T).trigger(o,T)}}function o(t){s=e(t.currentTarget);var a="";if(s.data("callee3",o),p){var c=s.data("xthreshold"),h=s.data("ythreshold"),u="undefined"!=typeof c&&c!==!1&&parseInt(c)?parseInt(c):i.swipe_h_threshold,l="undefined"!=typeof h&&h!==!1&&parseInt(h)?parseInt(h):i.swipe_v_threshold,f=t.originalEvent,g={position:{x:i.touch_capable?f.changedTouches[0].screenX:t.screenX,y:i.touch_capable?f.changedTouches[0].screenY:t.screenY},offset:{x:Math.round(i.touch_capable?f.changedTouches[0].pageX-s.offset().left:t.pageX-s.offset().left),y:Math.round(i.touch_capable?f.changedTouches[0].pageY-s.offset().top:t.pageY-s.offset().top)},time:Date.now(),target:t.target};n.position.y>g.position.y&&n.position.y-g.position.y>l&&(a="swipeup"),n.position.xu&&(a="swiperight"),n.position.yl&&(a="swipedown"),n.position.x>g.position.x&&n.position.x-g.position.x>u&&(a="swipeleft");var d=Math.abs(n.position.x-g.position.x),v=Math.abs(n.position.y-g.position.y),w={startEvnt:n,endEvnt:g,direction:a.replace("swipe",""),xAmount:d,yAmount:v,duration:g.time-n.time};s.trigger("swipeend",w)}r=!1,p=!1}var n,c=this,s=e(c),r=!1,p=!1,h={x:0,y:0},u={x:0,y:0};s.on(i.startevent,t),s.on(i.moveevent,a),s.on(i.endevent,o)},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.moveevent,e(this).data.callee2).off(i.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){function t(e,t){o=t,a(c,o?"scrollstart":"scrollend",e)}var o,n,c=this,s=e(c);s.on(i.scrollevent,function r(e){s.data("callee",r),o||t(e,!0),clearTimeout(n),n=setTimeout(function(){t(e,!1)},50)})},remove:function(){e(this).off(i.scrollevent,e(this).data.callee)}};var c,s,r,p,h,u=e(window),l={0:!0,180:!0};if(i.orientation_support){var f=window.innerWidth||u.width(),g=window.innerHeight||u.height(),d=50;p=f>g&&f-g>d,h=l[window.orientation],(p&&h||!p&&!h)&&(l={"-90":!0,90:!0})}e.event.special.orientationchange=c={setup:function(){return i.orientation_support?!1:(r=s(),u.on("throttledresize",t),!0)},teardown:function(){return i.orientation_support?!1:(u.off("throttledresize",t),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=s(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=s=function(){var e=!0,t=document.documentElement;return e=i.orientation_support?l[window.orientation]:t&&t.clientWidth/t.clientHeight<1.1,e?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",x)},teardown:function(){e(this).off("resize",x)}};var v,w,_,T=250,x=function(){w=Date.now(),_=w-y,_>=T?(y=w,e(this).trigger("throttledresize")):(v&&window.clearTimeout(v),v=window.setTimeout(t,T-_))},y=0;e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); From 079ec0892a55c81f4bd75c79512e4d0ed4e8d36e Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 13 Nov 2015 13:01:34 +0000 Subject: [PATCH 061/149] Sync to 1.0.5 --- src/jquery.mobile-events.js | 44 ++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/jquery.mobile-events.js b/src/jquery.mobile-events.js index c60f769..c453f62 100644 --- a/src/jquery.mobile-events.js +++ b/src/jquery.mobile-events.js @@ -96,8 +96,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) }, 'time': Date.now(), 'target': e.target @@ -129,8 +129,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) }, 'time': Date.now(), 'target': e.target @@ -162,8 +162,8 @@ 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) }, 'time': Date.now(), 'target': e.target @@ -228,8 +228,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, endOffset = { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) }; var duration = end_time - start_time; @@ -297,8 +297,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) }, 'time': Date.now(), 'target': e.target @@ -325,8 +325,8 @@ 'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) }, 'time': Date.now(), 'target': e.target @@ -408,8 +408,8 @@ 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) }, 'time': Date.now(), 'target': e.target @@ -485,8 +485,8 @@ 'y': (settings.touch_capable) ? origEvent.changedTouches[i].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) }, 'time': Date.now(), 'target': e.target @@ -540,8 +540,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) }, 'time': Date.now(), 'target': e.target @@ -591,8 +591,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) }, 'time': Date.now(), 'target': e.target @@ -633,8 +633,8 @@ 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.position().left) : Math.round(e.pageX - $this.position().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.position().top) : Math.round(e.pageY - $this.position().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) }, 'time': Date.now(), 'target': e.target From 3a9210e421a6c3d05b40f49252c627571405d253 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 13 Nov 2015 13:01:44 +0000 Subject: [PATCH 062/149] Update bower.json --- bower.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bower.json b/bower.json index 9ef7b56..f2a9ff7 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jquery-touch-events", - "version": "1.0.4", + "version": "1.0.5", "main": "src/jquery.mobile-events.js", "ignore": [ "bower.json" From 94e58a9c769143f8a3d999d36880e394d9e1856d Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 13 Nov 2015 13:02:45 +0000 Subject: [PATCH 063/149] Version info for 1.0.5 --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 470613e..8b841ed 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,9 @@ 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 1.0.5** (2015-11-13 + + Fixed a major bug where the reproted `offset` position of events was incorrect when inside of a parent element. + + **Version 1.0.4** (2015-11-12) + Regressed from `MSPointerEvent` for compatibility with IE11 and Edge + Removed multi-name event for `tap`. From 63ab6588e675dea234fd3daa302e07645b977168 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Thu, 19 Nov 2015 20:43:59 +0000 Subject: [PATCH 064/149] Fixed a minor typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8b841ed..a377639 100644 --- a/README.md +++ b/README.md @@ -130,7 +130,7 @@ Fired after the user releases their finger from the target element (or releases + **`tapmove`** Fired as soon as the user begins moving their finger on an element (or moving their mouse, for desktop environments). + **`tap`** -This event is fired whenever the user taps and releases their finger on the target element. Caution should be observed when using this event in conjunction without tap events, especially ``doubletap``. This event will be fired twice when ``doubletap`` is used, so it is recommended to use ``singletap`` in this case. +This event is fired whenever the user taps and releases their finger on the target element. Caution should be observed when using this event in conjunction with tap events, especially ``doubletap``. This event will be fired twice when ``doubletap`` is used, so it is recommended to use ``singletap`` in this case. + **`singletap`** Unlike ``tap`` this event is only triggered once we are certain the user has only tapped the target element a single time. This will not be triggered by ``doubletap`` or ``taphold``, unlike ``tap``. Since we need to run some tests to make sure the user isn't double tapping or holding a tap on the target element, this event is fired with a short delay (currently of 500 milliseconds). + **`doubletap`** From 5ed32a47e2f25bcb2e34e90f6eaadd80e4f2e26f Mon Sep 17 00:00:00 2001 From: "Adriano Leal (alga)" Date: Tue, 24 Nov 2015 15:19:38 -0200 Subject: [PATCH 065/149] added npm.js support, now you can download directly using npm install --- package.json | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 package.json diff --git a/package.json b/package.json new file mode 100644 index 0000000..834e6e5 --- /dev/null +++ b/package.json @@ -0,0 +1,31 @@ +{ + "name": "jquery-touch-events", + "version": "1.0.5", + "description": "Polyfill to remove click delays on browsers with touch UIs.", + "maintainers": [ + { + "name": "Ben Major", + "email": "ben.major88@gmail.com" + } + ], + "author": { + "name": "Ben Major", + "email": "ben.major88@gmail.com" + }, + "main": "src/jquery.mobile-events.js", + "repository": { + "type": "git", + "url": "git://github.com/benmajor/jQuery-Touch-Events.git" + }, + "keywords": [ + "jquery-touch-events", + "jquery-mobile", + "mobile", + "touch" + ], + "licenses": [ + { + "type": "MIT", + "url": "http://opensource.org/licenses/MIT" + } + ] From 5f39ed275f1326cf081c6ea5dad14e176223ebe2 Mon Sep 17 00:00:00 2001 From: "Adriano Leal (alga)" Date: Tue, 24 Nov 2015 15:22:29 -0200 Subject: [PATCH 066/149] fixed broken json --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 834e6e5..b36c053 100644 --- a/package.json +++ b/package.json @@ -29,3 +29,4 @@ "url": "http://opensource.org/licenses/MIT" } ] +} From e53f3b3b833d36401ef3ee38b5482fac2286839d Mon Sep 17 00:00:00 2001 From: "Adriano Leal (alga)" Date: Fri, 27 Nov 2015 12:51:52 -0200 Subject: [PATCH 067/149] Updated npm installation instruction on README --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index a377639..cbf3c1d 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,12 @@ Alternatively, you can also install jQuery-touch-events using Bower as follows: $ bower install jquery-touch-events ``` +Alternatively, you can also install jQuery-touch-events using NPM as follows: + +``` +$ npm install git+https://github.com/benmajor/jQuery-Touch-Events.git +``` + ### 3. Usage: All of the events outlined above have been written using jQuery's ``event.special`` object, and so can be used in conjunction with jQuery's event handling functions, as well as shortcut wrappers. As a result, all of the events that are supported by this library may be handled using any of jQuery's own event-specific methods, such as `bind()`, `on()`, `live()` (for legacy) and `one()`. From 943c06ab11add5178b3d96f32a8a8d778b7becfb Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 27 May 2016 15:42:31 +0100 Subject: [PATCH 068/149] Create bower.json --- src/1.0.0/bower.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/1.0.0/bower.json diff --git a/src/1.0.0/bower.json b/src/1.0.0/bower.json new file mode 100644 index 0000000..3f46efb --- /dev/null +++ b/src/1.0.0/bower.json @@ -0,0 +1,11 @@ +{ + "name": "jquery-touch-events-1.0.0", + "version": "1.0.0", + "main": "src/jquery.mobile-events.js", + "ignore": [ + "bower.json" + ], + "dependencies": { + "jquery": ">=1.7.0" + } +} From edb4fdfd2ff8368837c43882801788db88f69b0c Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 27 May 2016 15:42:48 +0100 Subject: [PATCH 069/149] Create bower.json --- src/1.0.1/bower.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/1.0.1/bower.json diff --git a/src/1.0.1/bower.json b/src/1.0.1/bower.json new file mode 100644 index 0000000..adc355f --- /dev/null +++ b/src/1.0.1/bower.json @@ -0,0 +1,11 @@ +{ + "name": "jquery-touch-events-1.0.1", + "version": "1.0.1", + "main": "src/jquery.mobile-events.js", + "ignore": [ + "bower.json" + ], + "dependencies": { + "jquery": ">=1.7.0" + } +} From 37f2bede28cc2d0ff8a7bf67be4536c0d47dc8ac Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 27 May 2016 15:43:07 +0100 Subject: [PATCH 070/149] Create bower.json --- src/1.0.2/bower.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/1.0.2/bower.json diff --git a/src/1.0.2/bower.json b/src/1.0.2/bower.json new file mode 100644 index 0000000..74b2c67 --- /dev/null +++ b/src/1.0.2/bower.json @@ -0,0 +1,11 @@ +{ + "name": "jquery-touch-events-1.0.2", + "version": "1.0.2", + "main": "src/jquery.mobile-events.js", + "ignore": [ + "bower.json" + ], + "dependencies": { + "jquery": ">=1.7.0" + } +} From 8adce3df574e99f93aafc1d01bc5fd57e862cf42 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 27 May 2016 15:43:23 +0100 Subject: [PATCH 071/149] Create bower.json --- src/1.0.3/bower.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/1.0.3/bower.json diff --git a/src/1.0.3/bower.json b/src/1.0.3/bower.json new file mode 100644 index 0000000..5986df8 --- /dev/null +++ b/src/1.0.3/bower.json @@ -0,0 +1,11 @@ +{ + "name": "jquery-touch-events", + "version": "1.0.3", + "main": "src/jquery.mobile-events.js", + "ignore": [ + "bower.json" + ], + "dependencies": { + "jquery": ">=1.7.0" + } +} From aac308403d8d567c4200eb4654a55a8e058b4c9a Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 27 May 2016 15:43:36 +0100 Subject: [PATCH 072/149] Update bower.json --- src/1.0.0/bower.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/1.0.0/bower.json b/src/1.0.0/bower.json index 3f46efb..48b95cb 100644 --- a/src/1.0.0/bower.json +++ b/src/1.0.0/bower.json @@ -1,5 +1,5 @@ { - "name": "jquery-touch-events-1.0.0", + "name": "jquery-touch-events", "version": "1.0.0", "main": "src/jquery.mobile-events.js", "ignore": [ From a66eadc6c00e038366d641678dbb0934b5c64c1d Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 27 May 2016 15:43:48 +0100 Subject: [PATCH 073/149] Update bower.json --- src/1.0.1/bower.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/1.0.1/bower.json b/src/1.0.1/bower.json index adc355f..bfd2e4d 100644 --- a/src/1.0.1/bower.json +++ b/src/1.0.1/bower.json @@ -1,5 +1,5 @@ { - "name": "jquery-touch-events-1.0.1", + "name": "jquery-touch-events", "version": "1.0.1", "main": "src/jquery.mobile-events.js", "ignore": [ From 7d0fe4724f2ade9001335c2df4d89907511ef0e9 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 27 May 2016 15:43:59 +0100 Subject: [PATCH 074/149] Update bower.json --- src/1.0.2/bower.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/1.0.2/bower.json b/src/1.0.2/bower.json index 74b2c67..5cea401 100644 --- a/src/1.0.2/bower.json +++ b/src/1.0.2/bower.json @@ -1,5 +1,5 @@ { - "name": "jquery-touch-events-1.0.2", + "name": "jquery-touch-events", "version": "1.0.2", "main": "src/jquery.mobile-events.js", "ignore": [ From 287e767951ecea9f996197f6a56d4fcf99f3cf9c Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 27 May 2016 15:44:18 +0100 Subject: [PATCH 075/149] Create bower.json --- src/1.0.4/bower.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/1.0.4/bower.json diff --git a/src/1.0.4/bower.json b/src/1.0.4/bower.json new file mode 100644 index 0000000..9ef7b56 --- /dev/null +++ b/src/1.0.4/bower.json @@ -0,0 +1,11 @@ +{ + "name": "jquery-touch-events", + "version": "1.0.4", + "main": "src/jquery.mobile-events.js", + "ignore": [ + "bower.json" + ], + "dependencies": { + "jquery": ">=1.7.0" + } +} From fe565a47b4b25bd0d6255a6ddfd3f2961819a091 Mon Sep 17 00:00:00 2001 From: Ben McMaster Date: Sat, 28 May 2016 16:45:10 -0700 Subject: [PATCH 076/149] adds fix for local timers. Multiple listeners confused the scope of the timers --- src/jquery.mobile-events.js | 69 ++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/src/jquery.mobile-events.js b/src/jquery.mobile-events.js index c453f62..2178018 100644 --- a/src/jquery.mobile-events.js +++ b/src/jquery.mobile-events.js @@ -52,10 +52,7 @@ endevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchend' : 'mouseup'), moveevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'mousemove'), tapevent: ('ontouchstart' in window && !isChromeDesktop) ? 'tap' : 'click', - scrollevent: ('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'scroll', - - hold_timer: null, - tap_timer: null + scrollevent: ('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'scroll' }; // Convenience functions: @@ -78,12 +75,12 @@ // 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; @@ -102,7 +99,7 @@ 'time': Date.now(), 'target': e.target }; - + triggerCustomEvent(thisObject, 'tapstart', e, touchData); return true; }); @@ -112,16 +109,16 @@ $(this).off(settings.startevent, $(this).data.callee); } }; - + // tapmove Event: $.event.special.tapmove = { - setup: function() { + setup: function() { var thisObject = this, $this = $(thisObject); - + $this.on(settings.moveevent, function tapMoveFunc(e) { $this.data('callee', tapMoveFunc); - + var origEvent = e.originalEvent, touchData = { 'position': { @@ -130,12 +127,12 @@ }, 'offset': { 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) }, 'time': Date.now(), 'target': e.target }; - + triggerCustomEvent(thisObject, 'tapmove', e, touchData); return true; }); @@ -188,7 +185,8 @@ y: 0 }, end_x = 0, - end_y = 0; + end_y = 0, + tapHoldTimer; $this.on(settings.startevent, function tapHoldFunc1(e) { if (e.which && e.which !== 1) { @@ -214,7 +212,7 @@ end_x = start_pos.x; end_y = start_pos.y; - settings.hold_timer = window.setTimeout(function () { + tapHoldTimer = window.setTimeout(function () { var diff_x = (start_pos.x - end_x), diff_y = (start_pos.y - end_y); @@ -229,7 +227,7 @@ }, endOffset = { 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) }; var duration = end_time - start_time; @@ -254,11 +252,11 @@ }).on(settings.endevent, function tapHoldFunc2() { $this.data('callee2', tapHoldFunc2); $this.data('tapheld', false); - window.clearTimeout(settings.hold_timer); + window.clearTimeout(tapHoldTimer); }) .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; }); @@ -278,8 +276,9 @@ action, firstTap = null, origEvent, - cooloff, - cooling = false; + cooloff, + cooling = false, + tapTimer; $this.on(settings.startevent, function doubleTapFunc1(e) { if (e.which && e.which !== 1) { @@ -307,7 +306,7 @@ return true; }).on(settings.endevent, function doubleTapFunc2(e) { - + var now = Date.now(); var lastTouch = $this.data('lastTouch') || now + 1; var delta = now - lastTouch; @@ -316,7 +315,7 @@ if (delta < settings.doubletap_int && (e.target == origTarget) && delta > 100) { $this.data('doubletapped', true); - window.clearTimeout(settings.tap_timer); + window.clearTimeout(tapTimer); // Now get the current event: var lastTap = { @@ -339,16 +338,16 @@ }; if (!cooling) { - triggerCustomEvent(thisObject, 'doubletap', e, touchData); + triggerCustomEvent(thisObject, 'doubletap', e, touchData); firstTap = null; } cooling = true; cooloff = window.setTimeout(function () { - cooling = false; + cooling = false; }, settings.doubletap_int); - + } else { $this.data('lastTouch', now); action = window.setTimeout(function () { @@ -399,7 +398,7 @@ // We need to check if it was a taphold: - settings.tap_timer = window.setTimeout(function () { + tapTimer = window.setTimeout(function () { if (!$this.data('doubletapped') && !$this.data('tapheld') && (start_pos.x == end_pos_x) && (start_pos.y == end_pos_y)) { var origEvent = e.originalEvent; var touchData = { @@ -409,7 +408,7 @@ }, 'offset': { 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) }, 'time': Date.now(), 'target': e.target @@ -449,17 +448,17 @@ $this.data('callee1', tapFunc1); if( e.which && e.which !== 1 ) - { + { return false; } - else - { + 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; } @@ -472,11 +471,11 @@ 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 origEvent = e.originalEvent; var touchData = [ ]; - + for( var i = 0; i < touches.length; i++) { var touch = { @@ -491,7 +490,7 @@ 'time': Date.now(), 'target': e.target }; - + touchData.push( touch ); } From d5a7d09b6f3fae4b815cb5527891c56ec8462d46 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Mon, 26 Sep 2016 12:15:23 +0100 Subject: [PATCH 077/149] Update README.md - Fixed minor typos - Added information about cdnjs installation. --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cbf3c1d..efe2aba 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ 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 1.0.5** (2015-11-13 - + Fixed a major bug where the reproted `offset` position of events was incorrect when inside of a parent element. + + Fixed a major bug where the reported `offset` position of events was incorrect when inside of a parent element. + **Version 1.0.4** (2015-11-12) + Regressed from `MSPointerEvent` for compatibility with IE11 and Edge @@ -57,13 +57,19 @@ Once you have downloaded the JS files from the master branch, you should include ``` +The awesome guys over at cdnjs have kindly added the library to their CDN so you can include it as follows directly into your application: + +``` + +``` + Alternatively, you can also install jQuery-touch-events using Bower as follows: ``` $ bower install jquery-touch-events ``` -Alternatively, you can also install jQuery-touch-events using NPM as follows: +jQuery Touch Events can also be installed using NPM as follows: ``` $ npm install git+https://github.com/benmajor/jQuery-Touch-Events.git From 2c5a5c272969889b90abde829c08c279c9463ed0 Mon Sep 17 00:00:00 2001 From: Daniel Trostli Date: Sat, 1 Oct 2016 17:09:44 -0300 Subject: [PATCH 078/149] Fix for issue 94 'Offset error when target is document' * sets offset to 0 when $(this).offset returns nil * https://github.com/benmajor/jQuery-Touch-Events/issues/94 --- src/jquery.mobile-events.js | 59 +++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/src/jquery.mobile-events.js b/src/jquery.mobile-events.js index 2178018..600077f 100644 --- a/src/jquery.mobile-events.js +++ b/src/jquery.mobile-events.js @@ -62,7 +62,10 @@ $.getMoveEvent = function() { return settings.moveevent; }; $.getTapEvent = function() { return settings.tapevent; }; $.getScrollEvent = function() { return settings.scrollevent; }; - + var offsetTop = function() { return $(this).offset() ? $this.offset().top : 0; }; + var offsetLeft = function() { return $(this).offset() ? $this.offset().left : 0; }; + var offsetRight = function() { return $(this).offset() ? $this.offset().right : 0; }; + // Add Event shortcuts: $.each(['tapstart', 'tapend', 'tapmove', 'tap', 'tap2', 'tap3', 'tap4', 'singletap', 'doubletap', 'taphold', 'swipe', 'swipeup', 'swiperight', 'swipedown', 'swipeleft', 'swipeend', 'scrollstart', 'scrollend', 'orientationchange'], function (i, name) { $.fn[name] = function (fn) { @@ -93,13 +96,13 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offsetLeft()) : Math.round(e.pageX - offsetLeft()), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offsetTop()) : Math.round(e.pageY - offsetTop()) }, 'time': Date.now(), 'target': e.target }; - + triggerCustomEvent(thisObject, 'tapstart', e, touchData); return true; }); @@ -126,13 +129,13 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offsetLeft()) : Math.round(e.pageX - offsetLeft()), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offsetTop()) : Math.round(e.pageY - offsetTop()) }, 'time': Date.now(), 'target': e.target }; - + triggerCustomEvent(thisObject, 'tapmove', e, touchData); return true; }); @@ -159,8 +162,8 @@ 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offsetLeft()) : Math.round(e.pageX - offsetLeft()), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offsetTop()) : Math.round(e.pageY - offsetTop()) }, 'time': Date.now(), 'target': e.target @@ -226,8 +229,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, endOffset = { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offsetLeft()) : Math.round(e.pageX - offsetLeft()), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offsetTop()) : Math.round(e.pageY - offsetTop()) }; var duration = end_time - start_time; @@ -296,8 +299,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offsetLeft()) : Math.round(e.pageX - offsetLeft()), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offsetTop()) : Math.round(e.pageY - offsetTop()) }, 'time': Date.now(), 'target': e.target @@ -324,8 +327,8 @@ 'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offsetLeft()) : Math.round(e.pageX - offsetLeft()), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offsetTop()) : Math.round(e.pageY - offsetTop()) }, 'time': Date.now(), 'target': e.target @@ -407,13 +410,13 @@ 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offsetLeft()) : Math.round(e.pageX - offsetLeft()), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offsetTop()) : Math.round(e.pageY - offsetTop()) }, 'time': Date.now(), 'target': e.target }; - + // Was it a taphold? if((touchData.time - startTime) < settings.taphold_threshold) { @@ -484,16 +487,16 @@ 'y': (settings.touch_capable) ? origEvent.changedTouches[i].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - offsetLeft()) : Math.round(e.pageX - offsetLeft()), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - offsetTop()) : Math.round(e.pageY - offsetTop()) }, 'time': Date.now(), 'target': e.target }; - + touchData.push( touch ); } - + triggerCustomEvent(thisObject, 'tap', e, touchData); } }); @@ -539,8 +542,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offsetLeft()) : Math.round(e.pageX - offsetLeft()), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offsetTop()) : Math.round(e.pageY - offsetTop()) }, 'time': Date.now(), 'target': e.target @@ -590,8 +593,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offsetLeft()) : Math.round(e.pageX - offsetLeft()), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offsetTop()) : Math.round(e.pageY - offsetTop()) }, 'time': Date.now(), 'target': e.target @@ -632,8 +635,8 @@ 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - $this.offset().left) : Math.round(e.pageX - $this.offset().left), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - $this.offset().top) : Math.round(e.pageY - $this.offset().top) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offsetLeft()) : Math.round(e.pageX - offsetLeft()), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offsetTop()) : Math.round(e.pageY - offsetTop()) }, 'time': Date.now(), 'target': e.target From 6ccdb94ecebded7622af02ed3f00b0519bbaf4a0 Mon Sep 17 00:00:00 2001 From: Daniel Trostli Date: Sat, 1 Oct 2016 17:20:21 -0300 Subject: [PATCH 079/149] add missing tapTimer var decleration in singleTap Event --- src/jquery.mobile-events.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/jquery.mobile-events.js b/src/jquery.mobile-events.js index 600077f..84e0dcb 100644 --- a/src/jquery.mobile-events.js +++ b/src/jquery.mobile-events.js @@ -377,7 +377,8 @@ start_pos = { x: 0, y: 0 - }; + }, + tapTimer; $this.on(settings.startevent, function singleTapFunc1(e) { if (e.which && e.which !== 1) { From 473a42efcb4c4004830dddac6f7466dce2fa610c Mon Sep 17 00:00:00 2001 From: Daniel Trostli Date: Sun, 2 Oct 2016 17:03:58 -0300 Subject: [PATCH 080/149] Move setting the original target of a double tap to the end of the Touch Up event listener. This lets the next tap see the actual original target of the previous tap. Ensures double tap is only activated on the same target. --- src/jquery.mobile-events.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jquery.mobile-events.js b/src/jquery.mobile-events.js index 84e0dcb..51e3134 100644 --- a/src/jquery.mobile-events.js +++ b/src/jquery.mobile-events.js @@ -288,7 +288,6 @@ return false; } $this.data('doubletapped', false); - origTarget = e.target; $this.data('callee1', doubleTapFunc1); origEvent = e.originalEvent; @@ -358,6 +357,7 @@ window.clearTimeout(action); }, settings.doubletap_int, [e]); } + origTarget = e.target; $this.data('lastTouch', now); }); }, From c3580bc5d5b416ac9538fc16aefcbc331782e2dc Mon Sep 17 00:00:00 2001 From: Ben Major Date: Tue, 15 Nov 2016 12:24:13 +0000 Subject: [PATCH 081/149] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index efe2aba..e03b90f 100644 --- a/README.md +++ b/README.md @@ -226,7 +226,7 @@ Each event provides different callback data. The following shows the numerous da `yAmount` - number of pixels the swipe occupied on the Y-axis (returned regardless of direction). -`startEvent` - Object containing the same data as a `tap` event, but captured when swiping begins. +`startEvnt` - Object containing the same data as a `tap` event, but captured when swiping begins. `endEvent` - Object containing the same data as a `tap` event, but captured when swiping is complete. From 72719010ac3650c255f2a227209821b1025e23a2 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 16 Nov 2016 19:16:02 +0000 Subject: [PATCH 082/149] Various Bug Fixes - Added slop factor for `singletap` (issue #104 and #112) - Fixed an issue where `offset()` was being called on `null`; now defaults to 0. --- src/1.0.6/jquery.mobile-events.js | 873 ++++++++++++++++++++++++++++++ 1 file changed, 873 insertions(+) create mode 100644 src/1.0.6/jquery.mobile-events.js diff --git a/src/1.0.6/jquery.mobile-events.js b/src/1.0.6/jquery.mobile-events.js new file mode 100644 index 0000000..21143ff --- /dev/null +++ b/src/1.0.6/jquery.mobile-events.js @@ -0,0 +1,873 @@ +/*! + * jQuery Mobile Events + * by Ben Major + * + * Copyright 2011-2015, 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 || {}; + + // navigator.userAgent.toLowerCase() isn't reliable for Chrome installs + // on mobile devices. As such, we will create a boolean isChromeDesktop + // The reason that we need to do this is because Chrome annoyingly + // purports support for touch events even if the underlying hardware + // does not! + var agent = navigator.userAgent.toLowerCase(), + isChromeDesktop = (agent.indexOf('chrome') > -1 && ((agent.indexOf('windows') > -1) || (agent.indexOf('macintosh') > -1) || (agent.indexOf('linux') > -1)) && agent.indexOf('mobile') < 0 && agent.indexOf('android') < 0), + + settings = { + tap_pixel_range: 5, + swipe_h_threshold: 50, + swipe_v_threshold: 50, + taphold_threshold: 750, + doubletap_int: 500, + + touch_capable: ('ontouchstart' in window && !isChromeDesktop), + orientation_support: ('orientation' in window && 'onorientationchange' in window), + + startevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchstart' : 'mousedown'), + endevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchend' : 'mouseup'), + moveevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'mousemove'), + tapevent: ('ontouchstart' in window && !isChromeDesktop) ? 'tap' : 'click', + scrollevent: ('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'scroll', + + hold_timer: null, + tap_timer: null + }; + + // 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; }; + + // Add Event shortcuts: + $.each(['tapstart', 'tapend', 'tapmove', 'tap', 'tap2', 'tap3', 'tap4', 'singletap', 'doubletap', 'taphold', 'swipe', 'swipeup', 'swiperight', 'swipedown', 'swipeleft', 'swipeend', 'scrollstart', 'scrollend', 'orientationchange'], 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 origEvent = e.originalEvent, + touchData = { + 'position': { + 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 origEvent = e.originalEvent, + touchData = { + 'position': { + 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 origEvent = e.originalEvent; + var touchData = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 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; + + settings.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(), + endPosition = { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + endOffset = { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }; + var duration = end_time - start_time; + + // Build the touch data: + var touchData = { + 'startTime': start_time, + 'endTime': end_time, + 'startPosition': startPosition, + 'startOffset': startOffset, + 'endPosition': endPosition, + 'endOffset': endOffset, + 'duration': duration, + 'target': e.target + }; + $this.data('callee1', tapHoldFunc1); + triggerCustomEvent(thisObject, 'taphold', e, touchData); + } + }, settings.taphold_threshold); + + return true; + } + }).on(settings.endevent, function tapHoldFunc2() { + $this.data('callee2', tapHoldFunc2); + $this.data('tapheld', false); + window.clearTimeout(settings.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) { + firstTap = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + 'time': Date.now(), + 'target': e.target + }; + } + + 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 == origTarget) && delta > 100) { + $this.data('doubletapped', true); + window.clearTimeout(settings.tap_timer); + + // Now get the current event: + var lastTap = { + 'position': { + 'x': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + 'time': Date.now(), + 'target': e.target + }; + + 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 origEvent = e.originalEvent; + var touchData = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 origEvent = e.originalEvent; + var touchData = [ ]; + + for( var i = 0; i < touches.length; i++) + { + var touch = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[i].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[i].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + 'time': Date.now(), + 'target': e.target + }; + + touchData.push( touch ); + } + + triggerCustomEvent(thisObject, 'tap', 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 origEvent = e.originalEvent; + // Read event data into our startEvt: + startEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 (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 (originalCoord.x > finalCoord.x && (originalCoord.x - finalCoord.x > h_threshold)) { + swipedir = 'swipeleft'; + } + 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 origEvent = e.originalEvent; + var endEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 origEvent = e.originalEvent; + var endEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + 'time': Date.now(), + '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); + + 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' + }, function (e, srcE) { + $.event.special[e] = { + setup: function () { + $(this).on(srcE, $.noop); + } + }; + }); + +}(jQuery)); From 9b52ac103195d9e83656e7d91c26f7de97d98078 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 16 Nov 2016 19:16:50 +0000 Subject: [PATCH 083/149] Various Bug Fixes - Added slop factor for `singletap` (issue #104 and #112) - Fixed an issue where `offset()` was being called on `null`; now defaults to 0. --- src/1.0.6/jquery.mobile-events.min.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/1.0.6/jquery.mobile-events.min.js diff --git a/src/1.0.6/jquery.mobile-events.min.js b/src/1.0.6/jquery.mobile-events.min.js new file mode 100644 index 0000000..0e19f41 --- /dev/null +++ b/src/1.0.6/jquery.mobile-events.min.js @@ -0,0 +1 @@ +"use strict";!function(a){function o(){var a=g();a!==h&&(h=a,e.trigger("orientationchange"))}function v(b,c,d,e){var f=d.type;d.type=c,a.event.dispatch.call(b,d,e),d.type=f}a.attrFn=a.attrFn||{};var b=navigator.userAgent.toLowerCase(),c=b.indexOf("chrome")>-1&&(b.indexOf("windows")>-1||b.indexOf("macintosh")>-1||b.indexOf("linux")>-1)&&b.indexOf("mobile")<0&&b.indexOf("android")<0,d={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:"ontouchstart"in window&&!c,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:"ontouchstart"in window&&!c?"touchstart":"mousedown",endevent:"ontouchstart"in window&&!c?"touchend":"mouseup",moveevent:"ontouchstart"in window&&!c?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!c?"tap":"click",scrollevent:"ontouchstart"in window&&!c?"touchmove":"scroll",hold_timer:null,tap_timer:null};a.isTouchCapable=function(){return d.touch_capable},a.getStartEvent=function(){return d.startevent},a.getEndEvent=function(){return d.endevent},a.getMoveEvent=function(){return d.moveevent},a.getTapEvent=function(){return d.tapevent},a.getScrollEvent=function(){return d.scrollevent},a.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],function(b,c){a.fn[c]=function(a){return a?this.on(c,a):this.trigger(c)},a.attrFn[c]=!0}),a.event.special.tapstart={setup:function(){var b=this,c=a(b);c.on(d.startevent,function a(e){if(c.data("callee",a),e.which&&1!==e.which)return!1;var f=e.originalEvent,g={position:{x:d.touch_capable?f.touches[0].screenX:e.screenX,y:d.touch_capable?f.touches[0].screenY:e.screenY},offset:{x:d.touch_capable?Math.round(f.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(e.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(f.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(e.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:e.target};return v(b,"tapstart",e,g),!0})},remove:function(){a(this).off(d.startevent,a(this).data.callee)}},a.event.special.tapmove={setup:function(){var b=this,c=a(b);c.on(d.moveevent,function a(e){c.data("callee",a);var f=e.originalEvent,g={position:{x:d.touch_capable?f.touches[0].screenX:e.screenX,y:d.touch_capable?f.touches[0].screenY:e.screenY},offset:{x:d.touch_capable?Math.round(f.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(e.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(f.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(e.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:e.target};return v(b,"tapmove",e,g),!0})},remove:function(){a(this).off(d.moveevent,a(this).data.callee)}},a.event.special.tapend={setup:function(){var b=this,c=a(b);c.on(d.endevent,function a(e){c.data("callee",a);var f=e.originalEvent,g={position:{x:d.touch_capable?f.changedTouches[0].screenX:e.screenX,y:d.touch_capable?f.changedTouches[0].screenY:e.screenY},offset:{x:d.touch_capable?Math.round(f.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(e.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(f.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(e.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:e.target};return v(b,"tapend",e,g),!0})},remove:function(){a(this).off(d.endevent,a(this).data.callee)}},a.event.special.taphold={setup:function(){var e,b=this,c=a(b),f={x:0,y:0},g=0,h=0;c.on(d.startevent,function a(i){if(i.which&&1!==i.which)return!1;c.data("tapheld",!1),e=i.target;var j=i.originalEvent,k=Date.now(),l={x:d.touch_capable?j.touches[0].screenX:i.screenX,y:d.touch_capable?j.touches[0].screenY:i.screenY},m={x:d.touch_capable?j.touches[0].pageX-j.touches[0].target.offsetLeft:i.offsetX,y:d.touch_capable?j.touches[0].pageY-j.touches[0].target.offsetTop:i.offsetY};return f.x=i.originalEvent.targetTouches?i.originalEvent.targetTouches[0].pageX:i.pageX,f.y=i.originalEvent.targetTouches?i.originalEvent.targetTouches[0].pageY:i.pageY,g=f.x,h=f.y,d.hold_timer=window.setTimeout(function(){var n=f.x-g,o=f.y-h;if(i.target==e&&(f.x==g&&f.y==h||n>=-d.tap_pixel_range&&n<=d.tap_pixel_range&&o>=-d.tap_pixel_range&&o<=d.tap_pixel_range)){c.data("tapheld",!0);var p=Date.now(),q={x:d.touch_capable?j.touches[0].screenX:i.screenX,y:d.touch_capable?j.touches[0].screenY:i.screenY},r={x:d.touch_capable?Math.round(j.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(i.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(j.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(i.pageY-(c.offset()?c.offset().top:0))},s=p-k,t={startTime:k,endTime:p,startPosition:l,startOffset:m,endPosition:q,endOffset:r,duration:s,target:i.target};c.data("callee1",a),v(b,"taphold",i,t)}},d.taphold_threshold),!0}).on(d.endevent,function a(){c.data("callee2",a),c.data("tapheld",!1),window.clearTimeout(d.hold_timer)}).on(d.moveevent,function a(b){c.data("callee3",a),g=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageX:b.pageX,h=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageY:b.pageY})},remove:function(){a(this).off(d.startevent,a(this).data.callee1).off(d.endevent,a(this).data.callee2).off(d.moveevent,a(this).data.callee3)}},a.event.special.doubletap={setup:function(){var e,f,h,i,b=this,c=a(b),g=null,j=!1;c.on(d.startevent,function a(b){return(!b.which||1===b.which)&&(c.data("doubletapped",!1),e=b.target,c.data("callee1",a),h=b.originalEvent,g||(g={position:{x:d.touch_capable?h.touches[0].screenX:b.screenX,y:d.touch_capable?h.touches[0].screenY:b.screenY},offset:{x:d.touch_capable?Math.round(h.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(b.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(h.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(b.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:b.target}),!0)}).on(d.endevent,function a(k){var l=Date.now(),m=c.data("lastTouch")||l+1,n=l-m;if(window.clearTimeout(f),c.data("callee2",a),n100){c.data("doubletapped",!0),window.clearTimeout(d.tap_timer);var o={position:{x:d.touch_capable?k.originalEvent.changedTouches[0].screenX:k.screenX,y:d.touch_capable?k.originalEvent.changedTouches[0].screenY:k.screenY},offset:{x:d.touch_capable?Math.round(h.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(k.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(h.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(k.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:k.target},p={firstTap:g,secondTap:o,interval:o.time-g.time};j||(v(b,"doubletap",k,p),g=null),j=!0,i=window.setTimeout(function(){j=!1},d.doubletap_int)}else c.data("lastTouch",l),f=window.setTimeout(function(){g=null,window.clearTimeout(f)},d.doubletap_int,[k]);c.data("lastTouch",l)})},remove:function(){a(this).off(d.startevent,a(this).data.callee1).off(d.endevent,a(this).data.callee2)}},a.event.special.singletap={setup:function(){var b=this,c=a(b),e=null,f=null,g={x:0,y:0};c.on(d.startevent,function a(b){return(!b.which||1===b.which)&&(f=Date.now(),e=b.target,c.data("callee1",a),g.x=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageX:b.pageX,g.y=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageY:b.pageY,!0)}).on(d.endevent,function a(h){if(c.data("callee2",a),h.target==e){var i=h.originalEvent.changedTouches?h.originalEvent.changedTouches[0].pageX:h.pageX,j=h.originalEvent.changedTouches?h.originalEvent.changedTouches[0].pageY:h.pageY;d.tap_timer=window.setTimeout(function(){var a=g.x-i,e=g.y-j;if(!c.data("doubletapped")&&!c.data("tapheld")&&(g.x==i&&g.y==j||a>=-d.tap_pixel_range&&a<=d.tap_pixel_range&&e>=-d.tap_pixel_range&&e<=d.tap_pixel_range)){var k=h.originalEvent,l={position:{x:d.touch_capable?k.changedTouches[0].screenX:h.screenX,y:d.touch_capable?k.changedTouches[0].screenY:h.screenY},offset:{x:d.touch_capable?Math.round(k.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(h.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(k.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(h.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:h.target};l.time-f=-d.tap_pixel_range&&m<=d.tap_pixel_range&&n>=-d.tap_pixel_range&&n<=d.tap_pixel_range)){for(var p=j.originalEvent,q=[],r=0;rh.y&&g.y-h.y>o&&(j="swipeup"),g.xn&&(j="swiperight"),g.yo&&(j="swipedown"),g.x>h.x&&g.x-h.x>n&&(j="swipeleft"),void 0!=j&&e){g.x=0,g.y=0,h.x=0,h.y=0,e=!1;var p=b.originalEvent,q={position:{x:d.touch_capable?p.touches[0].screenX:b.screenX,y:d.touch_capable?p.touches[0].screenY:b.screenY},offset:{x:d.touch_capable?Math.round(p.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(b.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(p.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(b.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:b.target},r=Math.abs(i.position.x-q.position.x),s=Math.abs(i.position.y-q.position.y),t={startEvnt:i,endEvnt:q,direction:j.replace("swipe",""),xAmount:r,yAmount:s,duration:q.time-i.time};f=!0,c.trigger("swipe",t).trigger(j,t)}}function l(b){c=a(b.currentTarget);var g="";if(c.data("callee3",l),f){var h=c.data("xthreshold"),j=c.data("ythreshold"),k="undefined"!=typeof h&&h!==!1&&parseInt(h)?parseInt(h):d.swipe_h_threshold,m="undefined"!=typeof j&&j!==!1&&parseInt(j)?parseInt(j):d.swipe_v_threshold,n=b.originalEvent,o={position:{x:d.touch_capable?n.changedTouches[0].screenX:b.screenX,y:d.touch_capable?n.changedTouches[0].screenY:b.screenY},offset:{x:d.touch_capable?Math.round(n.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(b.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(n.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(b.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:b.target};i.position.y>o.position.y&&i.position.y-o.position.y>m&&(g="swipeup"),i.position.xk&&(g="swiperight"),i.position.ym&&(g="swipedown"),i.position.x>o.position.x&&i.position.x-o.position.x>k&&(g="swipeleft");var p=Math.abs(i.position.x-o.position.x),q=Math.abs(i.position.y-o.position.y),r={startEvnt:i,endEvnt:o,direction:g.replace("swipe",""),xAmount:p,yAmount:q,duration:o.time-i.time};c.trigger("swipeend",r)}e=!1,f=!1}var i,b=this,c=a(b),e=!1,f=!1,g={x:0,y:0},h={x:0,y:0};c.on(d.startevent,j),c.on(d.moveevent,k),c.on(d.endevent,l)},remove:function(){a(this).off(d.startevent,a(this).data.callee1).off(d.moveevent,a(this).data.callee2).off(d.endevent,a(this).data.callee3)}},a.event.special.scrollstart={setup:function(){function g(a,c){e=c,v(b,e?"scrollstart":"scrollend",a)}var e,f,b=this,c=a(b);c.on(d.scrollevent,function a(b){c.data("callee",a),e||g(b,!0),clearTimeout(f),f=setTimeout(function(){g(b,!1)},50)})},remove:function(){a(this).off(d.scrollevent,a(this).data.callee)}};var f,g,h,i,j,e=a(window),k={0:!0,180:!0};if(d.orientation_support){var l=window.innerWidth||e.width(),m=window.innerHeight||e.height(),n=50;i=l>m&&l-m>n,j=k[window.orientation],(i&&j||!i&&!j)&&(k={"-90":!0,90:!0})}a.event.special.orientationchange=f={setup:function(){return!d.orientation_support&&(h=g(),e.on("throttledresize",o),!0)},teardown:function(){return!d.orientation_support&&(e.off("throttledresize",o),!0)},add:function(a){var b=a.handler;a.handler=function(a){return a.orientation=g(),b.apply(this,arguments)}}},a.event.special.orientationchange.orientation=g=function(){var a=!0,b=document.documentElement;return a=d.orientation_support?k[window.orientation]:b&&b.clientWidth/b.clientHeight<1.1,a?"portrait":"landscape"},a.event.special.throttledresize={setup:function(){a(this).on("resize",q)},teardown:function(){a(this).off("resize",q)}};var s,t,u,p=250,q=function(){t=Date.now(),u=t-r,u>=p?(r=t,a(this).trigger("throttledresize")):(s&&window.clearTimeout(s),s=window.setTimeout(o,p-u))},r=0;a.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(b,c){a.event.special[b]={setup:function(){a(this).on(c,a.noop)}}})}(jQuery); From 9daae3a90209ec90462c2b321939fefe6d0c9a43 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 16 Nov 2016 19:17:18 +0000 Subject: [PATCH 084/149] Update bower.json --- bower.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bower.json b/bower.json index f2a9ff7..8fbc383 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jquery-touch-events", - "version": "1.0.5", + "version": "1.0.6", "main": "src/jquery.mobile-events.js", "ignore": [ "bower.json" From d9e6aa8ce17aa08e6e5ce40d4bcf0ea82da49b51 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 16 Nov 2016 19:17:35 +0000 Subject: [PATCH 085/149] Update package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b36c053..48bc70d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jquery-touch-events", - "version": "1.0.5", + "version": "1.0.6", "description": "Polyfill to remove click delays on browsers with touch UIs.", "maintainers": [ { From ec6358e70bb1c8d20d8b97b83834d2b461bf4c9a Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 16 Nov 2016 19:18:00 +0000 Subject: [PATCH 086/149] Sync to 1.0.6 --- src/jquery.mobile-events.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jquery.mobile-events.min.js b/src/jquery.mobile-events.min.js index 6176530..0e19f41 100644 --- a/src/jquery.mobile-events.min.js +++ b/src/jquery.mobile-events.min.js @@ -1 +1 @@ -"use strict";!function(e){function t(){var e=s();e!==r&&(r=e,u.trigger("orientationchange"))}function a(t,a,o,n){var i=o.type;o.type=a,e.event.dispatch.call(t,o,n),o.type=i}e.attrFn=e.attrFn||{};var o=navigator.userAgent.toLowerCase(),n=o.indexOf("chrome")>-1&&(o.indexOf("windows")>-1||o.indexOf("macintosh")>-1||o.indexOf("linux")>-1)&&o.indexOf("mobile")<0&&o.indexOf("android")<0,i={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:"ontouchstart"in window&&!n,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:"ontouchstart"in window&&!n?"touchstart":"mousedown",endevent:"ontouchstart"in window&&!n?"touchend":"mouseup",moveevent:"ontouchstart"in window&&!n?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!n?"tap":"click",scrollevent:"ontouchstart"in window&&!n?"touchmove":"scroll",hold_timer:null,tap_timer:null};e.isTouchCapable=function(){return i.touch_capable},e.getStartEvent=function(){return i.startevent},e.getEndEvent=function(){return i.endevent},e.getMoveEvent=function(){return i.moveevent},e.getTapEvent=function(){return i.tapevent},e.getScrollEvent=function(){return i.scrollevent},e.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],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(i.startevent,function n(e){if(o.data("callee",n),e.which&&1!==e.which)return!1;var c=e.originalEvent,s={position:{x:i.touch_capable?c.touches[0].screenX:e.screenX,y:i.touch_capable?c.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?c.changedTouches[0].pageX-o.offset().left:e.pageX-o.offset().left),y:Math.round(i.touch_capable?c.changedTouches[0].pageY-o.offset().top:e.pageY-o.offset().top)},time:Date.now(),target:e.target};return a(t,"tapstart",e,s),!0})},remove:function(){e(this).off(i.startevent,e(this).data.callee)}},e.event.special.tapmove={setup:function(){var t=this,o=e(t);o.on(i.moveevent,function n(e){o.data("callee",n);var c=e.originalEvent,s={position:{x:i.touch_capable?c.touches[0].screenX:e.screenX,y:i.touch_capable?c.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?c.changedTouches[0].pageX-o.offset().left:e.pageX-o.offset().left),y:Math.round(i.touch_capable?c.changedTouches[0].pageY-o.offset().top:e.pageY-o.offset().top)},time:Date.now(),target:e.target};return a(t,"tapmove",e,s),!0})},remove:function(){e(this).off(i.moveevent,e(this).data.callee)}},e.event.special.tapend={setup:function(){var t=this,o=e(t);o.on(i.endevent,function n(e){o.data("callee",n);var c=e.originalEvent,s={position:{x:i.touch_capable?c.changedTouches[0].screenX:e.screenX,y:i.touch_capable?c.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?c.changedTouches[0].pageX-o.offset().left:e.pageX-o.offset().left),y:Math.round(i.touch_capable?c.changedTouches[0].pageY-o.offset().top:e.pageY-o.offset().top)},time:Date.now(),target:e.target};return a(t,"tapend",e,s),!0})},remove:function(){e(this).off(i.endevent,e(this).data.callee)}},e.event.special.taphold={setup:function(){var t,o=this,n=e(o),c={x:0,y:0},s=0,r=0;n.on(i.startevent,function p(e){if(e.which&&1!==e.which)return!1;n.data("tapheld",!1),t=e.target;var h=e.originalEvent,u=Date.now(),l={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},f={x:i.touch_capable?h.touches[0].pageX-h.touches[0].target.offsetLeft:e.offsetX,y:i.touch_capable?h.touches[0].pageY-h.touches[0].target.offsetTop:e.offsetY};return c.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,c.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,s=c.x,r=c.y,i.hold_timer=window.setTimeout(function(){var g=c.x-s,d=c.y-r;if(e.target==t&&(c.x==s&&c.y==r||g>=-i.tap_pixel_range&&g<=i.tap_pixel_range&&d>=-i.tap_pixel_range&&d<=i.tap_pixel_range)){n.data("tapheld",!0);var v=Date.now(),w={x:i.touch_capable?h.touches[0].screenX:e.screenX,y:i.touch_capable?h.touches[0].screenY:e.screenY},_={x:Math.round(i.touch_capable?h.changedTouches[0].pageX-n.offset().left:e.pageX-n.offset().left),y:Math.round(i.touch_capable?h.changedTouches[0].pageY-n.offset().top:e.pageY-n.offset().top)},T=v-u,x={startTime:u,endTime:v,startPosition:l,startOffset:f,endPosition:w,endOffset:_,duration:T,target:e.target};n.data("callee1",p),a(o,"taphold",e,x)}},i.taphold_threshold),!0}).on(i.endevent,function h(){n.data("callee2",h),n.data("tapheld",!1),window.clearTimeout(i.hold_timer)}).on(i.moveevent,function u(e){n.data("callee3",u),s=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,r=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2).off(i.moveevent,e(this).data.callee3)}},e.event.special.doubletap={setup:function(){var t,o,n,c,s=this,r=e(s),p=null,h=!1;r.on(i.startevent,function u(e){return e.which&&1!==e.which?!1:(r.data("doubletapped",!1),t=e.target,r.data("callee1",u),n=e.originalEvent,p||(p={position:{x:i.touch_capable?n.touches[0].screenX:e.screenX,y:i.touch_capable?n.touches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?n.changedTouches[0].pageX-r.offset().left:e.pageX-r.offset().left),y:Math.round(i.touch_capable?n.changedTouches[0].pageY-r.offset().top:e.pageY-r.offset().top)},time:Date.now(),target:e.target}),!0)}).on(i.endevent,function l(e){var u=Date.now(),f=r.data("lastTouch")||u+1,g=u-f;if(window.clearTimeout(o),r.data("callee2",l),g100){r.data("doubletapped",!0),window.clearTimeout(i.tap_timer);var d={position:{x:i.touch_capable?e.originalEvent.changedTouches[0].screenX:e.screenX,y:i.touch_capable?e.originalEvent.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?n.changedTouches[0].pageX-r.offset().left:e.pageX-r.offset().left),y:Math.round(i.touch_capable?n.changedTouches[0].pageY-r.offset().top:e.pageY-r.offset().top)},time:Date.now(),target:e.target},v={firstTap:p,secondTap:d,interval:d.time-p.time};h||(a(s,"doubletap",e,v),p=null),h=!0,c=window.setTimeout(function(){h=!1},i.doubletap_int)}else r.data("lastTouch",u),o=window.setTimeout(function(){p=null,window.clearTimeout(o)},i.doubletap_int,[e]);r.data("lastTouch",u)})},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.endevent,e(this).data.callee2)}},e.event.special.singletap={setup:function(){var t=this,o=e(t),n=null,c=null,s={x:0,y:0};o.on(i.startevent,function r(e){return e.which&&1!==e.which?!1:(c=Date.now(),n=e.target,o.data("callee1",r),s.x=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageX:e.pageX,s.y=e.originalEvent.targetTouches?e.originalEvent.targetTouches[0].pageY:e.pageY,!0)}).on(i.endevent,function p(e){if(o.data("callee2",p),e.target==n){var r=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageX:e.pageX,h=e.originalEvent.changedTouches?e.originalEvent.changedTouches[0].pageY:e.pageY;i.tap_timer=window.setTimeout(function(){if(!o.data("doubletapped")&&!o.data("tapheld")&&s.x==r&&s.y==h){var n=e.originalEvent,p={position:{x:i.touch_capable?n.changedTouches[0].screenX:e.screenX,y:i.touch_capable?n.changedTouches[0].screenY:e.screenY},offset:{x:Math.round(i.touch_capable?n.changedTouches[0].pageX-o.offset().left:e.pageX-o.offset().left),y:Math.round(i.touch_capable?n.changedTouches[0].pageY-o.offset().top:e.pageY-o.offset().top)},time:Date.now(),target:e.target};p.time-c=-i.tap_pixel_range&&f<=i.tap_pixel_range&&g>=-i.tap_pixel_range&&g<=i.tap_pixel_range)){for(var d=e.originalEvent,v=[],w=0;wu.y&&h.y-u.y>g&&(o="swipeup"),h.xf&&(o="swiperight"),h.yg&&(o="swipedown"),h.x>u.x&&h.x-u.x>f&&(o="swipeleft"),void 0!=o&&r){h.x=0,h.y=0,u.x=0,u.y=0,r=!1;var d=t.originalEvent,v={position:{x:i.touch_capable?d.touches[0].screenX:t.screenX,y:i.touch_capable?d.touches[0].screenY:t.screenY},offset:{x:Math.round(i.touch_capable?d.changedTouches[0].pageX-s.offset().left:t.pageX-s.offset().left),y:Math.round(i.touch_capable?d.changedTouches[0].pageY-s.offset().top:t.pageY-s.offset().top)},time:Date.now(),target:t.target},w=Math.abs(n.position.x-v.position.x),_=Math.abs(n.position.y-v.position.y),T={startEvnt:n,endEvnt:v,direction:o.replace("swipe",""),xAmount:w,yAmount:_,duration:v.time-n.time};p=!0,s.trigger("swipe",T).trigger(o,T)}}function o(t){s=e(t.currentTarget);var a="";if(s.data("callee3",o),p){var c=s.data("xthreshold"),h=s.data("ythreshold"),u="undefined"!=typeof c&&c!==!1&&parseInt(c)?parseInt(c):i.swipe_h_threshold,l="undefined"!=typeof h&&h!==!1&&parseInt(h)?parseInt(h):i.swipe_v_threshold,f=t.originalEvent,g={position:{x:i.touch_capable?f.changedTouches[0].screenX:t.screenX,y:i.touch_capable?f.changedTouches[0].screenY:t.screenY},offset:{x:Math.round(i.touch_capable?f.changedTouches[0].pageX-s.offset().left:t.pageX-s.offset().left),y:Math.round(i.touch_capable?f.changedTouches[0].pageY-s.offset().top:t.pageY-s.offset().top)},time:Date.now(),target:t.target};n.position.y>g.position.y&&n.position.y-g.position.y>l&&(a="swipeup"),n.position.xu&&(a="swiperight"),n.position.yl&&(a="swipedown"),n.position.x>g.position.x&&n.position.x-g.position.x>u&&(a="swipeleft");var d=Math.abs(n.position.x-g.position.x),v=Math.abs(n.position.y-g.position.y),w={startEvnt:n,endEvnt:g,direction:a.replace("swipe",""),xAmount:d,yAmount:v,duration:g.time-n.time};s.trigger("swipeend",w)}r=!1,p=!1}var n,c=this,s=e(c),r=!1,p=!1,h={x:0,y:0},u={x:0,y:0};s.on(i.startevent,t),s.on(i.moveevent,a),s.on(i.endevent,o)},remove:function(){e(this).off(i.startevent,e(this).data.callee1).off(i.moveevent,e(this).data.callee2).off(i.endevent,e(this).data.callee3)}},e.event.special.scrollstart={setup:function(){function t(e,t){o=t,a(c,o?"scrollstart":"scrollend",e)}var o,n,c=this,s=e(c);s.on(i.scrollevent,function r(e){s.data("callee",r),o||t(e,!0),clearTimeout(n),n=setTimeout(function(){t(e,!1)},50)})},remove:function(){e(this).off(i.scrollevent,e(this).data.callee)}};var c,s,r,p,h,u=e(window),l={0:!0,180:!0};if(i.orientation_support){var f=window.innerWidth||u.width(),g=window.innerHeight||u.height(),d=50;p=f>g&&f-g>d,h=l[window.orientation],(p&&h||!p&&!h)&&(l={"-90":!0,90:!0})}e.event.special.orientationchange=c={setup:function(){return i.orientation_support?!1:(r=s(),u.on("throttledresize",t),!0)},teardown:function(){return i.orientation_support?!1:(u.off("throttledresize",t),!0)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=s(),t.apply(this,arguments)}}},e.event.special.orientationchange.orientation=s=function(){var e=!0,t=document.documentElement;return e=i.orientation_support?l[window.orientation]:t&&t.clientWidth/t.clientHeight<1.1,e?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",x)},teardown:function(){e(this).off("resize",x)}};var v,w,_,T=250,x=function(){w=Date.now(),_=w-y,_>=T?(y=w,e(this).trigger("throttledresize")):(v&&window.clearTimeout(v),v=window.setTimeout(t,T-_))},y=0;e.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(t,a){e.event.special[t]={setup:function(){e(this).on(a,e.noop)}}})}(jQuery); +"use strict";!function(a){function o(){var a=g();a!==h&&(h=a,e.trigger("orientationchange"))}function v(b,c,d,e){var f=d.type;d.type=c,a.event.dispatch.call(b,d,e),d.type=f}a.attrFn=a.attrFn||{};var b=navigator.userAgent.toLowerCase(),c=b.indexOf("chrome")>-1&&(b.indexOf("windows")>-1||b.indexOf("macintosh")>-1||b.indexOf("linux")>-1)&&b.indexOf("mobile")<0&&b.indexOf("android")<0,d={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:"ontouchstart"in window&&!c,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:"ontouchstart"in window&&!c?"touchstart":"mousedown",endevent:"ontouchstart"in window&&!c?"touchend":"mouseup",moveevent:"ontouchstart"in window&&!c?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!c?"tap":"click",scrollevent:"ontouchstart"in window&&!c?"touchmove":"scroll",hold_timer:null,tap_timer:null};a.isTouchCapable=function(){return d.touch_capable},a.getStartEvent=function(){return d.startevent},a.getEndEvent=function(){return d.endevent},a.getMoveEvent=function(){return d.moveevent},a.getTapEvent=function(){return d.tapevent},a.getScrollEvent=function(){return d.scrollevent},a.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],function(b,c){a.fn[c]=function(a){return a?this.on(c,a):this.trigger(c)},a.attrFn[c]=!0}),a.event.special.tapstart={setup:function(){var b=this,c=a(b);c.on(d.startevent,function a(e){if(c.data("callee",a),e.which&&1!==e.which)return!1;var f=e.originalEvent,g={position:{x:d.touch_capable?f.touches[0].screenX:e.screenX,y:d.touch_capable?f.touches[0].screenY:e.screenY},offset:{x:d.touch_capable?Math.round(f.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(e.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(f.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(e.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:e.target};return v(b,"tapstart",e,g),!0})},remove:function(){a(this).off(d.startevent,a(this).data.callee)}},a.event.special.tapmove={setup:function(){var b=this,c=a(b);c.on(d.moveevent,function a(e){c.data("callee",a);var f=e.originalEvent,g={position:{x:d.touch_capable?f.touches[0].screenX:e.screenX,y:d.touch_capable?f.touches[0].screenY:e.screenY},offset:{x:d.touch_capable?Math.round(f.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(e.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(f.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(e.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:e.target};return v(b,"tapmove",e,g),!0})},remove:function(){a(this).off(d.moveevent,a(this).data.callee)}},a.event.special.tapend={setup:function(){var b=this,c=a(b);c.on(d.endevent,function a(e){c.data("callee",a);var f=e.originalEvent,g={position:{x:d.touch_capable?f.changedTouches[0].screenX:e.screenX,y:d.touch_capable?f.changedTouches[0].screenY:e.screenY},offset:{x:d.touch_capable?Math.round(f.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(e.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(f.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(e.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:e.target};return v(b,"tapend",e,g),!0})},remove:function(){a(this).off(d.endevent,a(this).data.callee)}},a.event.special.taphold={setup:function(){var e,b=this,c=a(b),f={x:0,y:0},g=0,h=0;c.on(d.startevent,function a(i){if(i.which&&1!==i.which)return!1;c.data("tapheld",!1),e=i.target;var j=i.originalEvent,k=Date.now(),l={x:d.touch_capable?j.touches[0].screenX:i.screenX,y:d.touch_capable?j.touches[0].screenY:i.screenY},m={x:d.touch_capable?j.touches[0].pageX-j.touches[0].target.offsetLeft:i.offsetX,y:d.touch_capable?j.touches[0].pageY-j.touches[0].target.offsetTop:i.offsetY};return f.x=i.originalEvent.targetTouches?i.originalEvent.targetTouches[0].pageX:i.pageX,f.y=i.originalEvent.targetTouches?i.originalEvent.targetTouches[0].pageY:i.pageY,g=f.x,h=f.y,d.hold_timer=window.setTimeout(function(){var n=f.x-g,o=f.y-h;if(i.target==e&&(f.x==g&&f.y==h||n>=-d.tap_pixel_range&&n<=d.tap_pixel_range&&o>=-d.tap_pixel_range&&o<=d.tap_pixel_range)){c.data("tapheld",!0);var p=Date.now(),q={x:d.touch_capable?j.touches[0].screenX:i.screenX,y:d.touch_capable?j.touches[0].screenY:i.screenY},r={x:d.touch_capable?Math.round(j.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(i.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(j.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(i.pageY-(c.offset()?c.offset().top:0))},s=p-k,t={startTime:k,endTime:p,startPosition:l,startOffset:m,endPosition:q,endOffset:r,duration:s,target:i.target};c.data("callee1",a),v(b,"taphold",i,t)}},d.taphold_threshold),!0}).on(d.endevent,function a(){c.data("callee2",a),c.data("tapheld",!1),window.clearTimeout(d.hold_timer)}).on(d.moveevent,function a(b){c.data("callee3",a),g=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageX:b.pageX,h=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageY:b.pageY})},remove:function(){a(this).off(d.startevent,a(this).data.callee1).off(d.endevent,a(this).data.callee2).off(d.moveevent,a(this).data.callee3)}},a.event.special.doubletap={setup:function(){var e,f,h,i,b=this,c=a(b),g=null,j=!1;c.on(d.startevent,function a(b){return(!b.which||1===b.which)&&(c.data("doubletapped",!1),e=b.target,c.data("callee1",a),h=b.originalEvent,g||(g={position:{x:d.touch_capable?h.touches[0].screenX:b.screenX,y:d.touch_capable?h.touches[0].screenY:b.screenY},offset:{x:d.touch_capable?Math.round(h.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(b.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(h.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(b.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:b.target}),!0)}).on(d.endevent,function a(k){var l=Date.now(),m=c.data("lastTouch")||l+1,n=l-m;if(window.clearTimeout(f),c.data("callee2",a),n100){c.data("doubletapped",!0),window.clearTimeout(d.tap_timer);var o={position:{x:d.touch_capable?k.originalEvent.changedTouches[0].screenX:k.screenX,y:d.touch_capable?k.originalEvent.changedTouches[0].screenY:k.screenY},offset:{x:d.touch_capable?Math.round(h.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(k.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(h.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(k.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:k.target},p={firstTap:g,secondTap:o,interval:o.time-g.time};j||(v(b,"doubletap",k,p),g=null),j=!0,i=window.setTimeout(function(){j=!1},d.doubletap_int)}else c.data("lastTouch",l),f=window.setTimeout(function(){g=null,window.clearTimeout(f)},d.doubletap_int,[k]);c.data("lastTouch",l)})},remove:function(){a(this).off(d.startevent,a(this).data.callee1).off(d.endevent,a(this).data.callee2)}},a.event.special.singletap={setup:function(){var b=this,c=a(b),e=null,f=null,g={x:0,y:0};c.on(d.startevent,function a(b){return(!b.which||1===b.which)&&(f=Date.now(),e=b.target,c.data("callee1",a),g.x=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageX:b.pageX,g.y=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageY:b.pageY,!0)}).on(d.endevent,function a(h){if(c.data("callee2",a),h.target==e){var i=h.originalEvent.changedTouches?h.originalEvent.changedTouches[0].pageX:h.pageX,j=h.originalEvent.changedTouches?h.originalEvent.changedTouches[0].pageY:h.pageY;d.tap_timer=window.setTimeout(function(){var a=g.x-i,e=g.y-j;if(!c.data("doubletapped")&&!c.data("tapheld")&&(g.x==i&&g.y==j||a>=-d.tap_pixel_range&&a<=d.tap_pixel_range&&e>=-d.tap_pixel_range&&e<=d.tap_pixel_range)){var k=h.originalEvent,l={position:{x:d.touch_capable?k.changedTouches[0].screenX:h.screenX,y:d.touch_capable?k.changedTouches[0].screenY:h.screenY},offset:{x:d.touch_capable?Math.round(k.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(h.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(k.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(h.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:h.target};l.time-f=-d.tap_pixel_range&&m<=d.tap_pixel_range&&n>=-d.tap_pixel_range&&n<=d.tap_pixel_range)){for(var p=j.originalEvent,q=[],r=0;rh.y&&g.y-h.y>o&&(j="swipeup"),g.xn&&(j="swiperight"),g.yo&&(j="swipedown"),g.x>h.x&&g.x-h.x>n&&(j="swipeleft"),void 0!=j&&e){g.x=0,g.y=0,h.x=0,h.y=0,e=!1;var p=b.originalEvent,q={position:{x:d.touch_capable?p.touches[0].screenX:b.screenX,y:d.touch_capable?p.touches[0].screenY:b.screenY},offset:{x:d.touch_capable?Math.round(p.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(b.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(p.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(b.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:b.target},r=Math.abs(i.position.x-q.position.x),s=Math.abs(i.position.y-q.position.y),t={startEvnt:i,endEvnt:q,direction:j.replace("swipe",""),xAmount:r,yAmount:s,duration:q.time-i.time};f=!0,c.trigger("swipe",t).trigger(j,t)}}function l(b){c=a(b.currentTarget);var g="";if(c.data("callee3",l),f){var h=c.data("xthreshold"),j=c.data("ythreshold"),k="undefined"!=typeof h&&h!==!1&&parseInt(h)?parseInt(h):d.swipe_h_threshold,m="undefined"!=typeof j&&j!==!1&&parseInt(j)?parseInt(j):d.swipe_v_threshold,n=b.originalEvent,o={position:{x:d.touch_capable?n.changedTouches[0].screenX:b.screenX,y:d.touch_capable?n.changedTouches[0].screenY:b.screenY},offset:{x:d.touch_capable?Math.round(n.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(b.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(n.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(b.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:b.target};i.position.y>o.position.y&&i.position.y-o.position.y>m&&(g="swipeup"),i.position.xk&&(g="swiperight"),i.position.ym&&(g="swipedown"),i.position.x>o.position.x&&i.position.x-o.position.x>k&&(g="swipeleft");var p=Math.abs(i.position.x-o.position.x),q=Math.abs(i.position.y-o.position.y),r={startEvnt:i,endEvnt:o,direction:g.replace("swipe",""),xAmount:p,yAmount:q,duration:o.time-i.time};c.trigger("swipeend",r)}e=!1,f=!1}var i,b=this,c=a(b),e=!1,f=!1,g={x:0,y:0},h={x:0,y:0};c.on(d.startevent,j),c.on(d.moveevent,k),c.on(d.endevent,l)},remove:function(){a(this).off(d.startevent,a(this).data.callee1).off(d.moveevent,a(this).data.callee2).off(d.endevent,a(this).data.callee3)}},a.event.special.scrollstart={setup:function(){function g(a,c){e=c,v(b,e?"scrollstart":"scrollend",a)}var e,f,b=this,c=a(b);c.on(d.scrollevent,function a(b){c.data("callee",a),e||g(b,!0),clearTimeout(f),f=setTimeout(function(){g(b,!1)},50)})},remove:function(){a(this).off(d.scrollevent,a(this).data.callee)}};var f,g,h,i,j,e=a(window),k={0:!0,180:!0};if(d.orientation_support){var l=window.innerWidth||e.width(),m=window.innerHeight||e.height(),n=50;i=l>m&&l-m>n,j=k[window.orientation],(i&&j||!i&&!j)&&(k={"-90":!0,90:!0})}a.event.special.orientationchange=f={setup:function(){return!d.orientation_support&&(h=g(),e.on("throttledresize",o),!0)},teardown:function(){return!d.orientation_support&&(e.off("throttledresize",o),!0)},add:function(a){var b=a.handler;a.handler=function(a){return a.orientation=g(),b.apply(this,arguments)}}},a.event.special.orientationchange.orientation=g=function(){var a=!0,b=document.documentElement;return a=d.orientation_support?k[window.orientation]:b&&b.clientWidth/b.clientHeight<1.1,a?"portrait":"landscape"},a.event.special.throttledresize={setup:function(){a(this).on("resize",q)},teardown:function(){a(this).off("resize",q)}};var s,t,u,p=250,q=function(){t=Date.now(),u=t-r,u>=p?(r=t,a(this).trigger("throttledresize")):(s&&window.clearTimeout(s),s=window.setTimeout(o,p-u))},r=0;a.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(b,c){a.event.special[b]={setup:function(){a(this).on(c,a.noop)}}})}(jQuery); From 38c95dbc207eb91960793e8e13554faeaf59b345 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 16 Nov 2016 19:18:47 +0000 Subject: [PATCH 087/149] Sync to 1.0.6 --- src/jquery.mobile-events.js | 145 ++++++++++++++++++------------------ 1 file changed, 74 insertions(+), 71 deletions(-) diff --git a/src/jquery.mobile-events.js b/src/jquery.mobile-events.js index 51e3134..21143ff 100644 --- a/src/jquery.mobile-events.js +++ b/src/jquery.mobile-events.js @@ -1,6 +1,6 @@ /*! * jQuery Mobile Events - * by Ben Major (lincweb - www.lincweb.co.uk) + * by Ben Major * * Copyright 2011-2015, Ben Major * Licensed under the MIT License: @@ -52,20 +52,20 @@ endevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchend' : 'mouseup'), moveevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'mousemove'), tapevent: ('ontouchstart' in window && !isChromeDesktop) ? 'tap' : 'click', - scrollevent: ('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'scroll' + scrollevent: ('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'scroll', + + hold_timer: null, + tap_timer: null }; // 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; }; - var offsetTop = function() { return $(this).offset() ? $this.offset().top : 0; }; - var offsetLeft = function() { return $(this).offset() ? $this.offset().left : 0; }; - var offsetRight = function() { return $(this).offset() ? $this.offset().right : 0; }; - + $.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; }; + // Add Event shortcuts: $.each(['tapstart', 'tapend', 'tapmove', 'tap', 'tap2', 'tap3', 'tap4', 'singletap', 'doubletap', 'taphold', 'swipe', 'swipeup', 'swiperight', 'swipedown', 'swipeleft', 'swipeend', 'scrollstart', 'scrollend', 'orientationchange'], function (i, name) { $.fn[name] = function (fn) { @@ -78,12 +78,12 @@ // 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; @@ -96,13 +96,13 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offsetLeft()) : Math.round(e.pageX - offsetLeft()), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offsetTop()) : Math.round(e.pageY - offsetTop()) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) }, 'time': Date.now(), 'target': e.target }; - + triggerCustomEvent(thisObject, 'tapstart', e, touchData); return true; }); @@ -112,16 +112,16 @@ $(this).off(settings.startevent, $(this).data.callee); } }; - + // tapmove Event: $.event.special.tapmove = { - setup: function() { + setup: function() { var thisObject = this, $this = $(thisObject); - + $this.on(settings.moveevent, function tapMoveFunc(e) { $this.data('callee', tapMoveFunc); - + var origEvent = e.originalEvent, touchData = { 'position': { @@ -129,13 +129,13 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offsetLeft()) : Math.round(e.pageX - offsetLeft()), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offsetTop()) : Math.round(e.pageY - offsetTop()) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) }, 'time': Date.now(), 'target': e.target }; - + triggerCustomEvent(thisObject, 'tapmove', e, touchData); return true; }); @@ -162,8 +162,8 @@ 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offsetLeft()) : Math.round(e.pageX - offsetLeft()), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offsetTop()) : Math.round(e.pageY - offsetTop()) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) }, 'time': Date.now(), 'target': e.target @@ -188,8 +188,7 @@ y: 0 }, end_x = 0, - end_y = 0, - tapHoldTimer; + end_y = 0; $this.on(settings.startevent, function tapHoldFunc1(e) { if (e.which && e.which !== 1) { @@ -215,7 +214,7 @@ end_x = start_pos.x; end_y = start_pos.y; - tapHoldTimer = window.setTimeout(function () { + settings.hold_timer = window.setTimeout(function () { var diff_x = (start_pos.x - end_x), diff_y = (start_pos.y - end_y); @@ -229,8 +228,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, endOffset = { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offsetLeft()) : Math.round(e.pageX - offsetLeft()), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offsetTop()) : Math.round(e.pageY - offsetTop()) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) }; var duration = end_time - start_time; @@ -255,11 +254,11 @@ }).on(settings.endevent, function tapHoldFunc2() { $this.data('callee2', tapHoldFunc2); $this.data('tapheld', false); - window.clearTimeout(tapHoldTimer); + window.clearTimeout(settings.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; }); @@ -279,15 +278,15 @@ action, firstTap = null, origEvent, - cooloff, - cooling = false, - tapTimer; + 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; @@ -298,8 +297,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offsetLeft()) : Math.round(e.pageX - offsetLeft()), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offsetTop()) : Math.round(e.pageY - offsetTop()) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) }, 'time': Date.now(), 'target': e.target @@ -308,7 +307,7 @@ return true; }).on(settings.endevent, function doubleTapFunc2(e) { - + var now = Date.now(); var lastTouch = $this.data('lastTouch') || now + 1; var delta = now - lastTouch; @@ -317,7 +316,7 @@ if (delta < settings.doubletap_int && (e.target == origTarget) && delta > 100) { $this.data('doubletapped', true); - window.clearTimeout(tapTimer); + window.clearTimeout(settings.tap_timer); // Now get the current event: var lastTap = { @@ -326,8 +325,8 @@ 'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offsetLeft()) : Math.round(e.pageX - offsetLeft()), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offsetTop()) : Math.round(e.pageY - offsetTop()) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) }, 'time': Date.now(), 'target': e.target @@ -340,16 +339,16 @@ }; if (!cooling) { - triggerCustomEvent(thisObject, 'doubletap', e, touchData); + triggerCustomEvent(thisObject, 'doubletap', e, touchData); firstTap = null; } cooling = true; cooloff = window.setTimeout(function () { - cooling = false; + cooling = false; }, settings.doubletap_int); - + } else { $this.data('lastTouch', now); action = window.setTimeout(function () { @@ -357,7 +356,6 @@ window.clearTimeout(action); }, settings.doubletap_int, [e]); } - origTarget = e.target; $this.data('lastTouch', now); }); }, @@ -377,8 +375,7 @@ start_pos = { x: 0, y: 0 - }, - tapTimer; + }; $this.on(settings.startevent, function singleTapFunc1(e) { if (e.which && e.which !== 1) { @@ -391,19 +388,25 @@ // 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; - var end_pos_y = (e.originalEvent.changedTouches) ? e.originalEvent.changedTouches[0].pageY : e.pageY; + 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: - tapTimer = window.setTimeout(function () { - if (!$this.data('doubletapped') && !$this.data('tapheld') && (start_pos.x == end_pos_x) && (start_pos.y == end_pos_y)) { + 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 origEvent = e.originalEvent; var touchData = { 'position': { @@ -411,13 +414,13 @@ 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offsetLeft()) : Math.round(e.pageX - offsetLeft()), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offsetTop()) : Math.round(e.pageY - offsetTop()) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) }, 'time': Date.now(), 'target': e.target }; - + // Was it a taphold? if((touchData.time - startTime) < settings.taphold_threshold) { @@ -452,17 +455,17 @@ $this.data('callee1', tapFunc1); if( e.which && e.which !== 1 ) - { + { return false; } - else - { + 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; } @@ -475,11 +478,11 @@ 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 origEvent = e.originalEvent; var touchData = [ ]; - + for( var i = 0; i < touches.length; i++) { var touch = { @@ -488,16 +491,16 @@ 'y': (settings.touch_capable) ? origEvent.changedTouches[i].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - offsetLeft()) : Math.round(e.pageX - offsetLeft()), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - offsetTop()) : Math.round(e.pageY - offsetTop()) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) }, 'time': Date.now(), 'target': e.target }; - + touchData.push( touch ); } - + triggerCustomEvent(thisObject, 'tap', e, touchData); } }); @@ -543,8 +546,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offsetLeft()) : Math.round(e.pageX - offsetLeft()), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offsetTop()) : Math.round(e.pageY - offsetTop()) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) }, 'time': Date.now(), 'target': e.target @@ -594,8 +597,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offsetLeft()) : Math.round(e.pageX - offsetLeft()), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offsetTop()) : Math.round(e.pageY - offsetTop()) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) }, 'time': Date.now(), 'target': e.target @@ -636,8 +639,8 @@ 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - offsetLeft()) : Math.round(e.pageX - offsetLeft()), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - offsetTop()) : Math.round(e.pageY - offsetTop()) + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) }, 'time': Date.now(), 'target': e.target From d380d7e48e9bf96dd8c1c1b37e3218e2156f398a Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 16 Nov 2016 19:20:37 +0000 Subject: [PATCH 088/149] Added version info for 1.0.6 --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e03b90f..086e2bf 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,11 @@ 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 1.0.5** (2015-11-13 ++ **Version 1.0.6** (2016-11-16) + + Added slop factor for `singletap` + + Fixed a bug where `offset()` was sometimes called on `null` (instead of `window`). + ++ **Version 1.0.5** (2015-11-13) + Fixed a major bug where the reported `offset` position of events was incorrect when inside of a parent element. + **Version 1.0.4** (2015-11-12) From 76f6f4c7376092feeae22a073b8a36b1c477d523 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 1 Feb 2017 01:00:38 +0000 Subject: [PATCH 089/149] Added attribute threshold for taphold --- src/jquery.mobile-events.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/jquery.mobile-events.js b/src/jquery.mobile-events.js index 21143ff..25d4f85 100644 --- a/src/jquery.mobile-events.js +++ b/src/jquery.mobile-events.js @@ -213,6 +213,11 @@ 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; settings.hold_timer = window.setTimeout(function () { @@ -247,7 +252,7 @@ $this.data('callee1', tapHoldFunc1); triggerCustomEvent(thisObject, 'taphold', e, touchData); } - }, settings.taphold_threshold); + }, threshold); return true; } From 878b5155276075dc95305e4a3e7f48aa41444ddb Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 1 Feb 2017 01:01:30 +0000 Subject: [PATCH 090/149] Added attribute threshold for taphold --- src/jquery.mobile-events.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jquery.mobile-events.min.js b/src/jquery.mobile-events.min.js index 0e19f41..959b843 100644 --- a/src/jquery.mobile-events.min.js +++ b/src/jquery.mobile-events.min.js @@ -1 +1 @@ -"use strict";!function(a){function o(){var a=g();a!==h&&(h=a,e.trigger("orientationchange"))}function v(b,c,d,e){var f=d.type;d.type=c,a.event.dispatch.call(b,d,e),d.type=f}a.attrFn=a.attrFn||{};var b=navigator.userAgent.toLowerCase(),c=b.indexOf("chrome")>-1&&(b.indexOf("windows")>-1||b.indexOf("macintosh")>-1||b.indexOf("linux")>-1)&&b.indexOf("mobile")<0&&b.indexOf("android")<0,d={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:"ontouchstart"in window&&!c,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:"ontouchstart"in window&&!c?"touchstart":"mousedown",endevent:"ontouchstart"in window&&!c?"touchend":"mouseup",moveevent:"ontouchstart"in window&&!c?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!c?"tap":"click",scrollevent:"ontouchstart"in window&&!c?"touchmove":"scroll",hold_timer:null,tap_timer:null};a.isTouchCapable=function(){return d.touch_capable},a.getStartEvent=function(){return d.startevent},a.getEndEvent=function(){return d.endevent},a.getMoveEvent=function(){return d.moveevent},a.getTapEvent=function(){return d.tapevent},a.getScrollEvent=function(){return d.scrollevent},a.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],function(b,c){a.fn[c]=function(a){return a?this.on(c,a):this.trigger(c)},a.attrFn[c]=!0}),a.event.special.tapstart={setup:function(){var b=this,c=a(b);c.on(d.startevent,function a(e){if(c.data("callee",a),e.which&&1!==e.which)return!1;var f=e.originalEvent,g={position:{x:d.touch_capable?f.touches[0].screenX:e.screenX,y:d.touch_capable?f.touches[0].screenY:e.screenY},offset:{x:d.touch_capable?Math.round(f.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(e.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(f.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(e.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:e.target};return v(b,"tapstart",e,g),!0})},remove:function(){a(this).off(d.startevent,a(this).data.callee)}},a.event.special.tapmove={setup:function(){var b=this,c=a(b);c.on(d.moveevent,function a(e){c.data("callee",a);var f=e.originalEvent,g={position:{x:d.touch_capable?f.touches[0].screenX:e.screenX,y:d.touch_capable?f.touches[0].screenY:e.screenY},offset:{x:d.touch_capable?Math.round(f.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(e.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(f.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(e.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:e.target};return v(b,"tapmove",e,g),!0})},remove:function(){a(this).off(d.moveevent,a(this).data.callee)}},a.event.special.tapend={setup:function(){var b=this,c=a(b);c.on(d.endevent,function a(e){c.data("callee",a);var f=e.originalEvent,g={position:{x:d.touch_capable?f.changedTouches[0].screenX:e.screenX,y:d.touch_capable?f.changedTouches[0].screenY:e.screenY},offset:{x:d.touch_capable?Math.round(f.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(e.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(f.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(e.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:e.target};return v(b,"tapend",e,g),!0})},remove:function(){a(this).off(d.endevent,a(this).data.callee)}},a.event.special.taphold={setup:function(){var e,b=this,c=a(b),f={x:0,y:0},g=0,h=0;c.on(d.startevent,function a(i){if(i.which&&1!==i.which)return!1;c.data("tapheld",!1),e=i.target;var j=i.originalEvent,k=Date.now(),l={x:d.touch_capable?j.touches[0].screenX:i.screenX,y:d.touch_capable?j.touches[0].screenY:i.screenY},m={x:d.touch_capable?j.touches[0].pageX-j.touches[0].target.offsetLeft:i.offsetX,y:d.touch_capable?j.touches[0].pageY-j.touches[0].target.offsetTop:i.offsetY};return f.x=i.originalEvent.targetTouches?i.originalEvent.targetTouches[0].pageX:i.pageX,f.y=i.originalEvent.targetTouches?i.originalEvent.targetTouches[0].pageY:i.pageY,g=f.x,h=f.y,d.hold_timer=window.setTimeout(function(){var n=f.x-g,o=f.y-h;if(i.target==e&&(f.x==g&&f.y==h||n>=-d.tap_pixel_range&&n<=d.tap_pixel_range&&o>=-d.tap_pixel_range&&o<=d.tap_pixel_range)){c.data("tapheld",!0);var p=Date.now(),q={x:d.touch_capable?j.touches[0].screenX:i.screenX,y:d.touch_capable?j.touches[0].screenY:i.screenY},r={x:d.touch_capable?Math.round(j.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(i.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(j.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(i.pageY-(c.offset()?c.offset().top:0))},s=p-k,t={startTime:k,endTime:p,startPosition:l,startOffset:m,endPosition:q,endOffset:r,duration:s,target:i.target};c.data("callee1",a),v(b,"taphold",i,t)}},d.taphold_threshold),!0}).on(d.endevent,function a(){c.data("callee2",a),c.data("tapheld",!1),window.clearTimeout(d.hold_timer)}).on(d.moveevent,function a(b){c.data("callee3",a),g=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageX:b.pageX,h=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageY:b.pageY})},remove:function(){a(this).off(d.startevent,a(this).data.callee1).off(d.endevent,a(this).data.callee2).off(d.moveevent,a(this).data.callee3)}},a.event.special.doubletap={setup:function(){var e,f,h,i,b=this,c=a(b),g=null,j=!1;c.on(d.startevent,function a(b){return(!b.which||1===b.which)&&(c.data("doubletapped",!1),e=b.target,c.data("callee1",a),h=b.originalEvent,g||(g={position:{x:d.touch_capable?h.touches[0].screenX:b.screenX,y:d.touch_capable?h.touches[0].screenY:b.screenY},offset:{x:d.touch_capable?Math.round(h.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(b.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(h.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(b.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:b.target}),!0)}).on(d.endevent,function a(k){var l=Date.now(),m=c.data("lastTouch")||l+1,n=l-m;if(window.clearTimeout(f),c.data("callee2",a),n100){c.data("doubletapped",!0),window.clearTimeout(d.tap_timer);var o={position:{x:d.touch_capable?k.originalEvent.changedTouches[0].screenX:k.screenX,y:d.touch_capable?k.originalEvent.changedTouches[0].screenY:k.screenY},offset:{x:d.touch_capable?Math.round(h.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(k.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(h.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(k.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:k.target},p={firstTap:g,secondTap:o,interval:o.time-g.time};j||(v(b,"doubletap",k,p),g=null),j=!0,i=window.setTimeout(function(){j=!1},d.doubletap_int)}else c.data("lastTouch",l),f=window.setTimeout(function(){g=null,window.clearTimeout(f)},d.doubletap_int,[k]);c.data("lastTouch",l)})},remove:function(){a(this).off(d.startevent,a(this).data.callee1).off(d.endevent,a(this).data.callee2)}},a.event.special.singletap={setup:function(){var b=this,c=a(b),e=null,f=null,g={x:0,y:0};c.on(d.startevent,function a(b){return(!b.which||1===b.which)&&(f=Date.now(),e=b.target,c.data("callee1",a),g.x=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageX:b.pageX,g.y=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageY:b.pageY,!0)}).on(d.endevent,function a(h){if(c.data("callee2",a),h.target==e){var i=h.originalEvent.changedTouches?h.originalEvent.changedTouches[0].pageX:h.pageX,j=h.originalEvent.changedTouches?h.originalEvent.changedTouches[0].pageY:h.pageY;d.tap_timer=window.setTimeout(function(){var a=g.x-i,e=g.y-j;if(!c.data("doubletapped")&&!c.data("tapheld")&&(g.x==i&&g.y==j||a>=-d.tap_pixel_range&&a<=d.tap_pixel_range&&e>=-d.tap_pixel_range&&e<=d.tap_pixel_range)){var k=h.originalEvent,l={position:{x:d.touch_capable?k.changedTouches[0].screenX:h.screenX,y:d.touch_capable?k.changedTouches[0].screenY:h.screenY},offset:{x:d.touch_capable?Math.round(k.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(h.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(k.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(h.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:h.target};l.time-f=-d.tap_pixel_range&&m<=d.tap_pixel_range&&n>=-d.tap_pixel_range&&n<=d.tap_pixel_range)){for(var p=j.originalEvent,q=[],r=0;rh.y&&g.y-h.y>o&&(j="swipeup"),g.xn&&(j="swiperight"),g.yo&&(j="swipedown"),g.x>h.x&&g.x-h.x>n&&(j="swipeleft"),void 0!=j&&e){g.x=0,g.y=0,h.x=0,h.y=0,e=!1;var p=b.originalEvent,q={position:{x:d.touch_capable?p.touches[0].screenX:b.screenX,y:d.touch_capable?p.touches[0].screenY:b.screenY},offset:{x:d.touch_capable?Math.round(p.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(b.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(p.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(b.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:b.target},r=Math.abs(i.position.x-q.position.x),s=Math.abs(i.position.y-q.position.y),t={startEvnt:i,endEvnt:q,direction:j.replace("swipe",""),xAmount:r,yAmount:s,duration:q.time-i.time};f=!0,c.trigger("swipe",t).trigger(j,t)}}function l(b){c=a(b.currentTarget);var g="";if(c.data("callee3",l),f){var h=c.data("xthreshold"),j=c.data("ythreshold"),k="undefined"!=typeof h&&h!==!1&&parseInt(h)?parseInt(h):d.swipe_h_threshold,m="undefined"!=typeof j&&j!==!1&&parseInt(j)?parseInt(j):d.swipe_v_threshold,n=b.originalEvent,o={position:{x:d.touch_capable?n.changedTouches[0].screenX:b.screenX,y:d.touch_capable?n.changedTouches[0].screenY:b.screenY},offset:{x:d.touch_capable?Math.round(n.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(b.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(n.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(b.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:b.target};i.position.y>o.position.y&&i.position.y-o.position.y>m&&(g="swipeup"),i.position.xk&&(g="swiperight"),i.position.ym&&(g="swipedown"),i.position.x>o.position.x&&i.position.x-o.position.x>k&&(g="swipeleft");var p=Math.abs(i.position.x-o.position.x),q=Math.abs(i.position.y-o.position.y),r={startEvnt:i,endEvnt:o,direction:g.replace("swipe",""),xAmount:p,yAmount:q,duration:o.time-i.time};c.trigger("swipeend",r)}e=!1,f=!1}var i,b=this,c=a(b),e=!1,f=!1,g={x:0,y:0},h={x:0,y:0};c.on(d.startevent,j),c.on(d.moveevent,k),c.on(d.endevent,l)},remove:function(){a(this).off(d.startevent,a(this).data.callee1).off(d.moveevent,a(this).data.callee2).off(d.endevent,a(this).data.callee3)}},a.event.special.scrollstart={setup:function(){function g(a,c){e=c,v(b,e?"scrollstart":"scrollend",a)}var e,f,b=this,c=a(b);c.on(d.scrollevent,function a(b){c.data("callee",a),e||g(b,!0),clearTimeout(f),f=setTimeout(function(){g(b,!1)},50)})},remove:function(){a(this).off(d.scrollevent,a(this).data.callee)}};var f,g,h,i,j,e=a(window),k={0:!0,180:!0};if(d.orientation_support){var l=window.innerWidth||e.width(),m=window.innerHeight||e.height(),n=50;i=l>m&&l-m>n,j=k[window.orientation],(i&&j||!i&&!j)&&(k={"-90":!0,90:!0})}a.event.special.orientationchange=f={setup:function(){return!d.orientation_support&&(h=g(),e.on("throttledresize",o),!0)},teardown:function(){return!d.orientation_support&&(e.off("throttledresize",o),!0)},add:function(a){var b=a.handler;a.handler=function(a){return a.orientation=g(),b.apply(this,arguments)}}},a.event.special.orientationchange.orientation=g=function(){var a=!0,b=document.documentElement;return a=d.orientation_support?k[window.orientation]:b&&b.clientWidth/b.clientHeight<1.1,a?"portrait":"landscape"},a.event.special.throttledresize={setup:function(){a(this).on("resize",q)},teardown:function(){a(this).off("resize",q)}};var s,t,u,p=250,q=function(){t=Date.now(),u=t-r,u>=p?(r=t,a(this).trigger("throttledresize")):(s&&window.clearTimeout(s),s=window.setTimeout(o,p-u))},r=0;a.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(b,c){a.event.special[b]={setup:function(){a(this).on(c,a.noop)}}})}(jQuery); +"use strict";!function(a){function o(){var a=g();a!==h&&(h=a,e.trigger("orientationchange"))}function v(b,c,d,e){var f=d.type;d.type=c,a.event.dispatch.call(b,d,e),d.type=f}a.attrFn=a.attrFn||{};var b=navigator.userAgent.toLowerCase(),c=b.indexOf("chrome")>-1&&(b.indexOf("windows")>-1||b.indexOf("macintosh")>-1||b.indexOf("linux")>-1)&&b.indexOf("mobile")<0&&b.indexOf("android")<0,d={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:"ontouchstart"in window&&!c,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:"ontouchstart"in window&&!c?"touchstart":"mousedown",endevent:"ontouchstart"in window&&!c?"touchend":"mouseup",moveevent:"ontouchstart"in window&&!c?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!c?"tap":"click",scrollevent:"ontouchstart"in window&&!c?"touchmove":"scroll",hold_timer:null,tap_timer:null};a.isTouchCapable=function(){return d.touch_capable},a.getStartEvent=function(){return d.startevent},a.getEndEvent=function(){return d.endevent},a.getMoveEvent=function(){return d.moveevent},a.getTapEvent=function(){return d.tapevent},a.getScrollEvent=function(){return d.scrollevent},a.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],function(b,c){a.fn[c]=function(a){return a?this.on(c,a):this.trigger(c)},a.attrFn[c]=!0}),a.event.special.tapstart={setup:function(){var b=this,c=a(b);c.on(d.startevent,function a(e){if(c.data("callee",a),e.which&&1!==e.which)return!1;var f=e.originalEvent,g={position:{x:d.touch_capable?f.touches[0].screenX:e.screenX,y:d.touch_capable?f.touches[0].screenY:e.screenY},offset:{x:d.touch_capable?Math.round(f.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(e.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(f.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(e.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:e.target};return v(b,"tapstart",e,g),!0})},remove:function(){a(this).off(d.startevent,a(this).data.callee)}},a.event.special.tapmove={setup:function(){var b=this,c=a(b);c.on(d.moveevent,function a(e){c.data("callee",a);var f=e.originalEvent,g={position:{x:d.touch_capable?f.touches[0].screenX:e.screenX,y:d.touch_capable?f.touches[0].screenY:e.screenY},offset:{x:d.touch_capable?Math.round(f.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(e.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(f.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(e.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:e.target};return v(b,"tapmove",e,g),!0})},remove:function(){a(this).off(d.moveevent,a(this).data.callee)}},a.event.special.tapend={setup:function(){var b=this,c=a(b);c.on(d.endevent,function a(e){c.data("callee",a);var f=e.originalEvent,g={position:{x:d.touch_capable?f.changedTouches[0].screenX:e.screenX,y:d.touch_capable?f.changedTouches[0].screenY:e.screenY},offset:{x:d.touch_capable?Math.round(f.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(e.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(f.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(e.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:e.target};return v(b,"tapend",e,g),!0})},remove:function(){a(this).off(d.endevent,a(this).data.callee)}},a.event.special.taphold={setup:function(){var e,b=this,c=a(b),f={x:0,y:0},g=0,h=0;c.on(d.startevent,function a(i){if(i.which&&1!==i.which)return!1;c.data("tapheld",!1),e=i.target;var j=i.originalEvent,k=Date.now(),l={x:d.touch_capable?j.touches[0].screenX:i.screenX,y:d.touch_capable?j.touches[0].screenY:i.screenY},m={x:d.touch_capable?j.touches[0].pageX-j.touches[0].target.offsetLeft:i.offsetX,y:d.touch_capable?j.touches[0].pageY-j.touches[0].target.offsetTop:i.offsetY};f.x=i.originalEvent.targetTouches?i.originalEvent.targetTouches[0].pageX:i.pageX,f.y=i.originalEvent.targetTouches?i.originalEvent.targetTouches[0].pageY:i.pageY,g=f.x,h=f.y;var n=c.parent().data("threshold")?c.parent().data("threshold"):c.data("threshold"),o="undefined"!=typeof n&&n!==!1&&parseInt(n)?parseInt(n):d.taphold_threshold;return d.hold_timer=window.setTimeout(function(){var n=f.x-g,o=f.y-h;if(i.target==e&&(f.x==g&&f.y==h||n>=-d.tap_pixel_range&&n<=d.tap_pixel_range&&o>=-d.tap_pixel_range&&o<=d.tap_pixel_range)){c.data("tapheld",!0);var p=Date.now(),q={x:d.touch_capable?j.touches[0].screenX:i.screenX,y:d.touch_capable?j.touches[0].screenY:i.screenY},r={x:d.touch_capable?Math.round(j.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(i.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(j.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(i.pageY-(c.offset()?c.offset().top:0))},s=p-k,t={startTime:k,endTime:p,startPosition:l,startOffset:m,endPosition:q,endOffset:r,duration:s,target:i.target};c.data("callee1",a),v(b,"taphold",i,t)}},o),!0}).on(d.endevent,function a(){c.data("callee2",a),c.data("tapheld",!1),window.clearTimeout(d.hold_timer)}).on(d.moveevent,function a(b){c.data("callee3",a),g=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageX:b.pageX,h=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageY:b.pageY})},remove:function(){a(this).off(d.startevent,a(this).data.callee1).off(d.endevent,a(this).data.callee2).off(d.moveevent,a(this).data.callee3)}},a.event.special.doubletap={setup:function(){var e,f,h,i,b=this,c=a(b),g=null,j=!1;c.on(d.startevent,function a(b){return(!b.which||1===b.which)&&(c.data("doubletapped",!1),e=b.target,c.data("callee1",a),h=b.originalEvent,g||(g={position:{x:d.touch_capable?h.touches[0].screenX:b.screenX,y:d.touch_capable?h.touches[0].screenY:b.screenY},offset:{x:d.touch_capable?Math.round(h.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(b.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(h.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(b.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:b.target}),!0)}).on(d.endevent,function a(k){var l=Date.now(),m=c.data("lastTouch")||l+1,n=l-m;if(window.clearTimeout(f),c.data("callee2",a),n100){c.data("doubletapped",!0),window.clearTimeout(d.tap_timer);var o={position:{x:d.touch_capable?k.originalEvent.changedTouches[0].screenX:k.screenX,y:d.touch_capable?k.originalEvent.changedTouches[0].screenY:k.screenY},offset:{x:d.touch_capable?Math.round(h.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(k.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(h.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(k.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:k.target},p={firstTap:g,secondTap:o,interval:o.time-g.time};j||(v(b,"doubletap",k,p),g=null),j=!0,i=window.setTimeout(function(){j=!1},d.doubletap_int)}else c.data("lastTouch",l),f=window.setTimeout(function(){g=null,window.clearTimeout(f)},d.doubletap_int,[k]);c.data("lastTouch",l)})},remove:function(){a(this).off(d.startevent,a(this).data.callee1).off(d.endevent,a(this).data.callee2)}},a.event.special.singletap={setup:function(){var b=this,c=a(b),e=null,f=null,g={x:0,y:0};c.on(d.startevent,function a(b){return(!b.which||1===b.which)&&(f=Date.now(),e=b.target,c.data("callee1",a),g.x=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageX:b.pageX,g.y=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageY:b.pageY,!0)}).on(d.endevent,function a(h){if(c.data("callee2",a),h.target==e){var i=h.originalEvent.changedTouches?h.originalEvent.changedTouches[0].pageX:h.pageX,j=h.originalEvent.changedTouches?h.originalEvent.changedTouches[0].pageY:h.pageY;d.tap_timer=window.setTimeout(function(){var a=g.x-i,e=g.y-j;if(!c.data("doubletapped")&&!c.data("tapheld")&&(g.x==i&&g.y==j||a>=-d.tap_pixel_range&&a<=d.tap_pixel_range&&e>=-d.tap_pixel_range&&e<=d.tap_pixel_range)){var k=h.originalEvent,l={position:{x:d.touch_capable?k.changedTouches[0].screenX:h.screenX,y:d.touch_capable?k.changedTouches[0].screenY:h.screenY},offset:{x:d.touch_capable?Math.round(k.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(h.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(k.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(h.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:h.target};l.time-f=-d.tap_pixel_range&&m<=d.tap_pixel_range&&n>=-d.tap_pixel_range&&n<=d.tap_pixel_range)){for(var p=j.originalEvent,q=[],r=0;rh.y&&g.y-h.y>o&&(j="swipeup"),g.xn&&(j="swiperight"),g.yo&&(j="swipedown"),g.x>h.x&&g.x-h.x>n&&(j="swipeleft"),void 0!=j&&e){g.x=0,g.y=0,h.x=0,h.y=0,e=!1;var p=b.originalEvent,q={position:{x:d.touch_capable?p.touches[0].screenX:b.screenX,y:d.touch_capable?p.touches[0].screenY:b.screenY},offset:{x:d.touch_capable?Math.round(p.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(b.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(p.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(b.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:b.target},r=Math.abs(i.position.x-q.position.x),s=Math.abs(i.position.y-q.position.y),t={startEvnt:i,endEvnt:q,direction:j.replace("swipe",""),xAmount:r,yAmount:s,duration:q.time-i.time};f=!0,c.trigger("swipe",t).trigger(j,t)}}function l(b){c=a(b.currentTarget);var g="";if(c.data("callee3",l),f){var h=c.data("xthreshold"),j=c.data("ythreshold"),k="undefined"!=typeof h&&h!==!1&&parseInt(h)?parseInt(h):d.swipe_h_threshold,m="undefined"!=typeof j&&j!==!1&&parseInt(j)?parseInt(j):d.swipe_v_threshold,n=b.originalEvent,o={position:{x:d.touch_capable?n.changedTouches[0].screenX:b.screenX,y:d.touch_capable?n.changedTouches[0].screenY:b.screenY},offset:{x:d.touch_capable?Math.round(n.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(b.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(n.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(b.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:b.target};i.position.y>o.position.y&&i.position.y-o.position.y>m&&(g="swipeup"),i.position.xk&&(g="swiperight"),i.position.ym&&(g="swipedown"),i.position.x>o.position.x&&i.position.x-o.position.x>k&&(g="swipeleft");var p=Math.abs(i.position.x-o.position.x),q=Math.abs(i.position.y-o.position.y),r={startEvnt:i,endEvnt:o,direction:g.replace("swipe",""),xAmount:p,yAmount:q,duration:o.time-i.time};c.trigger("swipeend",r)}e=!1,f=!1}var i,b=this,c=a(b),e=!1,f=!1,g={x:0,y:0},h={x:0,y:0};c.on(d.startevent,j),c.on(d.moveevent,k),c.on(d.endevent,l)},remove:function(){a(this).off(d.startevent,a(this).data.callee1).off(d.moveevent,a(this).data.callee2).off(d.endevent,a(this).data.callee3)}},a.event.special.scrollstart={setup:function(){function g(a,c){e=c,v(b,e?"scrollstart":"scrollend",a)}var e,f,b=this,c=a(b);c.on(d.scrollevent,function a(b){c.data("callee",a),e||g(b,!0),clearTimeout(f),f=setTimeout(function(){g(b,!1)},50)})},remove:function(){a(this).off(d.scrollevent,a(this).data.callee)}};var f,g,h,i,j,e=a(window),k={0:!0,180:!0};if(d.orientation_support){var l=window.innerWidth||e.width(),m=window.innerHeight||e.height(),n=50;i=l>m&&l-m>n,j=k[window.orientation],(i&&j||!i&&!j)&&(k={"-90":!0,90:!0})}a.event.special.orientationchange=f={setup:function(){return!d.orientation_support&&(h=g(),e.on("throttledresize",o),!0)},teardown:function(){return!d.orientation_support&&(e.off("throttledresize",o),!0)},add:function(a){var b=a.handler;a.handler=function(a){return a.orientation=g(),b.apply(this,arguments)}}},a.event.special.orientationchange.orientation=g=function(){var a=!0,b=document.documentElement;return a=d.orientation_support?k[window.orientation]:b&&b.clientWidth/b.clientHeight<1.1,a?"portrait":"landscape"},a.event.special.throttledresize={setup:function(){a(this).on("resize",q)},teardown:function(){a(this).off("resize",q)}};var s,t,u,p=250,q=function(){t=Date.now(),u=t-r,u>=p?(r=t,a(this).trigger("throttledresize")):(s&&window.clearTimeout(s),s=window.setTimeout(o,p-u))},r=0;a.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(b,c){a.event.special[b]={setup:function(){a(this).on(c,a.noop)}}})}(jQuery); From b38dc2f264ab1731b730f2c16bd2e4c2d7b16b36 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 1 Feb 2017 01:02:19 +0000 Subject: [PATCH 091/149] Added attribute threshold for taphold --- src/1.0.7/jquery.mobile-events.js | 878 ++++++++++++++++++++++++++++++ 1 file changed, 878 insertions(+) create mode 100644 src/1.0.7/jquery.mobile-events.js diff --git a/src/1.0.7/jquery.mobile-events.js b/src/1.0.7/jquery.mobile-events.js new file mode 100644 index 0000000..25d4f85 --- /dev/null +++ b/src/1.0.7/jquery.mobile-events.js @@ -0,0 +1,878 @@ +/*! + * jQuery Mobile Events + * by Ben Major + * + * Copyright 2011-2015, 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 || {}; + + // navigator.userAgent.toLowerCase() isn't reliable for Chrome installs + // on mobile devices. As such, we will create a boolean isChromeDesktop + // The reason that we need to do this is because Chrome annoyingly + // purports support for touch events even if the underlying hardware + // does not! + var agent = navigator.userAgent.toLowerCase(), + isChromeDesktop = (agent.indexOf('chrome') > -1 && ((agent.indexOf('windows') > -1) || (agent.indexOf('macintosh') > -1) || (agent.indexOf('linux') > -1)) && agent.indexOf('mobile') < 0 && agent.indexOf('android') < 0), + + settings = { + tap_pixel_range: 5, + swipe_h_threshold: 50, + swipe_v_threshold: 50, + taphold_threshold: 750, + doubletap_int: 500, + + touch_capable: ('ontouchstart' in window && !isChromeDesktop), + orientation_support: ('orientation' in window && 'onorientationchange' in window), + + startevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchstart' : 'mousedown'), + endevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchend' : 'mouseup'), + moveevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'mousemove'), + tapevent: ('ontouchstart' in window && !isChromeDesktop) ? 'tap' : 'click', + scrollevent: ('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'scroll', + + hold_timer: null, + tap_timer: null + }; + + // 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; }; + + // Add Event shortcuts: + $.each(['tapstart', 'tapend', 'tapmove', 'tap', 'tap2', 'tap3', 'tap4', 'singletap', 'doubletap', 'taphold', 'swipe', 'swipeup', 'swiperight', 'swipedown', 'swipeleft', 'swipeend', 'scrollstart', 'scrollend', 'orientationchange'], 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 origEvent = e.originalEvent, + touchData = { + 'position': { + 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 origEvent = e.originalEvent, + touchData = { + 'position': { + 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 origEvent = e.originalEvent; + var touchData = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 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; + + settings.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(), + endPosition = { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + endOffset = { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }; + var duration = end_time - start_time; + + // Build the touch data: + var touchData = { + 'startTime': start_time, + 'endTime': end_time, + 'startPosition': startPosition, + 'startOffset': startOffset, + 'endPosition': endPosition, + 'endOffset': endOffset, + 'duration': duration, + 'target': e.target + }; + $this.data('callee1', tapHoldFunc1); + triggerCustomEvent(thisObject, 'taphold', e, touchData); + } + }, threshold); + + return true; + } + }).on(settings.endevent, function tapHoldFunc2() { + $this.data('callee2', tapHoldFunc2); + $this.data('tapheld', false); + window.clearTimeout(settings.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) { + firstTap = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + 'time': Date.now(), + 'target': e.target + }; + } + + 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 == origTarget) && delta > 100) { + $this.data('doubletapped', true); + window.clearTimeout(settings.tap_timer); + + // Now get the current event: + var lastTap = { + 'position': { + 'x': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + 'time': Date.now(), + 'target': e.target + }; + + 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 origEvent = e.originalEvent; + var touchData = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 origEvent = e.originalEvent; + var touchData = [ ]; + + for( var i = 0; i < touches.length; i++) + { + var touch = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[i].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[i].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + 'time': Date.now(), + 'target': e.target + }; + + touchData.push( touch ); + } + + triggerCustomEvent(thisObject, 'tap', 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 origEvent = e.originalEvent; + // Read event data into our startEvt: + startEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 (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 (originalCoord.x > finalCoord.x && (originalCoord.x - finalCoord.x > h_threshold)) { + swipedir = 'swipeleft'; + } + 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 origEvent = e.originalEvent; + var endEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 origEvent = e.originalEvent; + var endEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + 'time': Date.now(), + '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); + + 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' + }, function (e, srcE) { + $.event.special[e] = { + setup: function () { + $(this).on(srcE, $.noop); + } + }; + }); + +}(jQuery)); From 37bb7b01e7a6ea0c22c2e12073cfa049c0c1de3a Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 1 Feb 2017 01:02:41 +0000 Subject: [PATCH 092/149] Added attribute threshold for taphold --- src/1.0.7/jquery.mobile-events.min.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/1.0.7/jquery.mobile-events.min.js diff --git a/src/1.0.7/jquery.mobile-events.min.js b/src/1.0.7/jquery.mobile-events.min.js new file mode 100644 index 0000000..959b843 --- /dev/null +++ b/src/1.0.7/jquery.mobile-events.min.js @@ -0,0 +1 @@ +"use strict";!function(a){function o(){var a=g();a!==h&&(h=a,e.trigger("orientationchange"))}function v(b,c,d,e){var f=d.type;d.type=c,a.event.dispatch.call(b,d,e),d.type=f}a.attrFn=a.attrFn||{};var b=navigator.userAgent.toLowerCase(),c=b.indexOf("chrome")>-1&&(b.indexOf("windows")>-1||b.indexOf("macintosh")>-1||b.indexOf("linux")>-1)&&b.indexOf("mobile")<0&&b.indexOf("android")<0,d={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:"ontouchstart"in window&&!c,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:"ontouchstart"in window&&!c?"touchstart":"mousedown",endevent:"ontouchstart"in window&&!c?"touchend":"mouseup",moveevent:"ontouchstart"in window&&!c?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!c?"tap":"click",scrollevent:"ontouchstart"in window&&!c?"touchmove":"scroll",hold_timer:null,tap_timer:null};a.isTouchCapable=function(){return d.touch_capable},a.getStartEvent=function(){return d.startevent},a.getEndEvent=function(){return d.endevent},a.getMoveEvent=function(){return d.moveevent},a.getTapEvent=function(){return d.tapevent},a.getScrollEvent=function(){return d.scrollevent},a.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],function(b,c){a.fn[c]=function(a){return a?this.on(c,a):this.trigger(c)},a.attrFn[c]=!0}),a.event.special.tapstart={setup:function(){var b=this,c=a(b);c.on(d.startevent,function a(e){if(c.data("callee",a),e.which&&1!==e.which)return!1;var f=e.originalEvent,g={position:{x:d.touch_capable?f.touches[0].screenX:e.screenX,y:d.touch_capable?f.touches[0].screenY:e.screenY},offset:{x:d.touch_capable?Math.round(f.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(e.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(f.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(e.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:e.target};return v(b,"tapstart",e,g),!0})},remove:function(){a(this).off(d.startevent,a(this).data.callee)}},a.event.special.tapmove={setup:function(){var b=this,c=a(b);c.on(d.moveevent,function a(e){c.data("callee",a);var f=e.originalEvent,g={position:{x:d.touch_capable?f.touches[0].screenX:e.screenX,y:d.touch_capable?f.touches[0].screenY:e.screenY},offset:{x:d.touch_capable?Math.round(f.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(e.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(f.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(e.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:e.target};return v(b,"tapmove",e,g),!0})},remove:function(){a(this).off(d.moveevent,a(this).data.callee)}},a.event.special.tapend={setup:function(){var b=this,c=a(b);c.on(d.endevent,function a(e){c.data("callee",a);var f=e.originalEvent,g={position:{x:d.touch_capable?f.changedTouches[0].screenX:e.screenX,y:d.touch_capable?f.changedTouches[0].screenY:e.screenY},offset:{x:d.touch_capable?Math.round(f.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(e.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(f.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(e.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:e.target};return v(b,"tapend",e,g),!0})},remove:function(){a(this).off(d.endevent,a(this).data.callee)}},a.event.special.taphold={setup:function(){var e,b=this,c=a(b),f={x:0,y:0},g=0,h=0;c.on(d.startevent,function a(i){if(i.which&&1!==i.which)return!1;c.data("tapheld",!1),e=i.target;var j=i.originalEvent,k=Date.now(),l={x:d.touch_capable?j.touches[0].screenX:i.screenX,y:d.touch_capable?j.touches[0].screenY:i.screenY},m={x:d.touch_capable?j.touches[0].pageX-j.touches[0].target.offsetLeft:i.offsetX,y:d.touch_capable?j.touches[0].pageY-j.touches[0].target.offsetTop:i.offsetY};f.x=i.originalEvent.targetTouches?i.originalEvent.targetTouches[0].pageX:i.pageX,f.y=i.originalEvent.targetTouches?i.originalEvent.targetTouches[0].pageY:i.pageY,g=f.x,h=f.y;var n=c.parent().data("threshold")?c.parent().data("threshold"):c.data("threshold"),o="undefined"!=typeof n&&n!==!1&&parseInt(n)?parseInt(n):d.taphold_threshold;return d.hold_timer=window.setTimeout(function(){var n=f.x-g,o=f.y-h;if(i.target==e&&(f.x==g&&f.y==h||n>=-d.tap_pixel_range&&n<=d.tap_pixel_range&&o>=-d.tap_pixel_range&&o<=d.tap_pixel_range)){c.data("tapheld",!0);var p=Date.now(),q={x:d.touch_capable?j.touches[0].screenX:i.screenX,y:d.touch_capable?j.touches[0].screenY:i.screenY},r={x:d.touch_capable?Math.round(j.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(i.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(j.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(i.pageY-(c.offset()?c.offset().top:0))},s=p-k,t={startTime:k,endTime:p,startPosition:l,startOffset:m,endPosition:q,endOffset:r,duration:s,target:i.target};c.data("callee1",a),v(b,"taphold",i,t)}},o),!0}).on(d.endevent,function a(){c.data("callee2",a),c.data("tapheld",!1),window.clearTimeout(d.hold_timer)}).on(d.moveevent,function a(b){c.data("callee3",a),g=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageX:b.pageX,h=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageY:b.pageY})},remove:function(){a(this).off(d.startevent,a(this).data.callee1).off(d.endevent,a(this).data.callee2).off(d.moveevent,a(this).data.callee3)}},a.event.special.doubletap={setup:function(){var e,f,h,i,b=this,c=a(b),g=null,j=!1;c.on(d.startevent,function a(b){return(!b.which||1===b.which)&&(c.data("doubletapped",!1),e=b.target,c.data("callee1",a),h=b.originalEvent,g||(g={position:{x:d.touch_capable?h.touches[0].screenX:b.screenX,y:d.touch_capable?h.touches[0].screenY:b.screenY},offset:{x:d.touch_capable?Math.round(h.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(b.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(h.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(b.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:b.target}),!0)}).on(d.endevent,function a(k){var l=Date.now(),m=c.data("lastTouch")||l+1,n=l-m;if(window.clearTimeout(f),c.data("callee2",a),n100){c.data("doubletapped",!0),window.clearTimeout(d.tap_timer);var o={position:{x:d.touch_capable?k.originalEvent.changedTouches[0].screenX:k.screenX,y:d.touch_capable?k.originalEvent.changedTouches[0].screenY:k.screenY},offset:{x:d.touch_capable?Math.round(h.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(k.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(h.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(k.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:k.target},p={firstTap:g,secondTap:o,interval:o.time-g.time};j||(v(b,"doubletap",k,p),g=null),j=!0,i=window.setTimeout(function(){j=!1},d.doubletap_int)}else c.data("lastTouch",l),f=window.setTimeout(function(){g=null,window.clearTimeout(f)},d.doubletap_int,[k]);c.data("lastTouch",l)})},remove:function(){a(this).off(d.startevent,a(this).data.callee1).off(d.endevent,a(this).data.callee2)}},a.event.special.singletap={setup:function(){var b=this,c=a(b),e=null,f=null,g={x:0,y:0};c.on(d.startevent,function a(b){return(!b.which||1===b.which)&&(f=Date.now(),e=b.target,c.data("callee1",a),g.x=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageX:b.pageX,g.y=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageY:b.pageY,!0)}).on(d.endevent,function a(h){if(c.data("callee2",a),h.target==e){var i=h.originalEvent.changedTouches?h.originalEvent.changedTouches[0].pageX:h.pageX,j=h.originalEvent.changedTouches?h.originalEvent.changedTouches[0].pageY:h.pageY;d.tap_timer=window.setTimeout(function(){var a=g.x-i,e=g.y-j;if(!c.data("doubletapped")&&!c.data("tapheld")&&(g.x==i&&g.y==j||a>=-d.tap_pixel_range&&a<=d.tap_pixel_range&&e>=-d.tap_pixel_range&&e<=d.tap_pixel_range)){var k=h.originalEvent,l={position:{x:d.touch_capable?k.changedTouches[0].screenX:h.screenX,y:d.touch_capable?k.changedTouches[0].screenY:h.screenY},offset:{x:d.touch_capable?Math.round(k.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(h.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(k.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(h.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:h.target};l.time-f=-d.tap_pixel_range&&m<=d.tap_pixel_range&&n>=-d.tap_pixel_range&&n<=d.tap_pixel_range)){for(var p=j.originalEvent,q=[],r=0;rh.y&&g.y-h.y>o&&(j="swipeup"),g.xn&&(j="swiperight"),g.yo&&(j="swipedown"),g.x>h.x&&g.x-h.x>n&&(j="swipeleft"),void 0!=j&&e){g.x=0,g.y=0,h.x=0,h.y=0,e=!1;var p=b.originalEvent,q={position:{x:d.touch_capable?p.touches[0].screenX:b.screenX,y:d.touch_capable?p.touches[0].screenY:b.screenY},offset:{x:d.touch_capable?Math.round(p.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(b.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(p.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(b.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:b.target},r=Math.abs(i.position.x-q.position.x),s=Math.abs(i.position.y-q.position.y),t={startEvnt:i,endEvnt:q,direction:j.replace("swipe",""),xAmount:r,yAmount:s,duration:q.time-i.time};f=!0,c.trigger("swipe",t).trigger(j,t)}}function l(b){c=a(b.currentTarget);var g="";if(c.data("callee3",l),f){var h=c.data("xthreshold"),j=c.data("ythreshold"),k="undefined"!=typeof h&&h!==!1&&parseInt(h)?parseInt(h):d.swipe_h_threshold,m="undefined"!=typeof j&&j!==!1&&parseInt(j)?parseInt(j):d.swipe_v_threshold,n=b.originalEvent,o={position:{x:d.touch_capable?n.changedTouches[0].screenX:b.screenX,y:d.touch_capable?n.changedTouches[0].screenY:b.screenY},offset:{x:d.touch_capable?Math.round(n.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(b.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(n.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(b.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:b.target};i.position.y>o.position.y&&i.position.y-o.position.y>m&&(g="swipeup"),i.position.xk&&(g="swiperight"),i.position.ym&&(g="swipedown"),i.position.x>o.position.x&&i.position.x-o.position.x>k&&(g="swipeleft");var p=Math.abs(i.position.x-o.position.x),q=Math.abs(i.position.y-o.position.y),r={startEvnt:i,endEvnt:o,direction:g.replace("swipe",""),xAmount:p,yAmount:q,duration:o.time-i.time};c.trigger("swipeend",r)}e=!1,f=!1}var i,b=this,c=a(b),e=!1,f=!1,g={x:0,y:0},h={x:0,y:0};c.on(d.startevent,j),c.on(d.moveevent,k),c.on(d.endevent,l)},remove:function(){a(this).off(d.startevent,a(this).data.callee1).off(d.moveevent,a(this).data.callee2).off(d.endevent,a(this).data.callee3)}},a.event.special.scrollstart={setup:function(){function g(a,c){e=c,v(b,e?"scrollstart":"scrollend",a)}var e,f,b=this,c=a(b);c.on(d.scrollevent,function a(b){c.data("callee",a),e||g(b,!0),clearTimeout(f),f=setTimeout(function(){g(b,!1)},50)})},remove:function(){a(this).off(d.scrollevent,a(this).data.callee)}};var f,g,h,i,j,e=a(window),k={0:!0,180:!0};if(d.orientation_support){var l=window.innerWidth||e.width(),m=window.innerHeight||e.height(),n=50;i=l>m&&l-m>n,j=k[window.orientation],(i&&j||!i&&!j)&&(k={"-90":!0,90:!0})}a.event.special.orientationchange=f={setup:function(){return!d.orientation_support&&(h=g(),e.on("throttledresize",o),!0)},teardown:function(){return!d.orientation_support&&(e.off("throttledresize",o),!0)},add:function(a){var b=a.handler;a.handler=function(a){return a.orientation=g(),b.apply(this,arguments)}}},a.event.special.orientationchange.orientation=g=function(){var a=!0,b=document.documentElement;return a=d.orientation_support?k[window.orientation]:b&&b.clientWidth/b.clientHeight<1.1,a?"portrait":"landscape"},a.event.special.throttledresize={setup:function(){a(this).on("resize",q)},teardown:function(){a(this).off("resize",q)}};var s,t,u,p=250,q=function(){t=Date.now(),u=t-r,u>=p?(r=t,a(this).trigger("throttledresize")):(s&&window.clearTimeout(s),s=window.setTimeout(o,p-u))},r=0;a.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(b,c){a.event.special[b]={setup:function(){a(this).on(c,a.noop)}}})}(jQuery); From cc90fe68e1055147aa8b1d6c23ad49bc1ec2c1fe Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 1 Feb 2017 01:03:06 +0000 Subject: [PATCH 093/149] Added version info for 1.0.7 --- bower.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bower.json b/bower.json index 8fbc383..859be7f 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jquery-touch-events", - "version": "1.0.6", + "version": "1.0.7", "main": "src/jquery.mobile-events.js", "ignore": [ "bower.json" From 6844b6ba276602c3a6677c4b93cd9fc40ec330f8 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 1 Feb 2017 01:03:34 +0000 Subject: [PATCH 094/149] Added version info for 1.0.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 48bc70d..03e40e8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jquery-touch-events", - "version": "1.0.6", + "version": "1.0.7", "description": "Polyfill to remove click delays on browsers with touch UIs.", "maintainers": [ { From 89917f0aa2d3be94a1c561a75b6b412694ade354 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 1 Feb 2017 01:05:56 +0000 Subject: [PATCH 095/149] Added threshold info for doubletap --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 086e2bf..1f3db37 100644 --- a/README.md +++ b/README.md @@ -246,6 +246,11 @@ The value you define is the difference in pixels that the user must move before ``data-ythreshold`` defines the vertical threshold. +**Update as of 1.0.7:** +Following requests from users and contributors, as of 1.0.7 it is now possible to also define the `doubletap` threshold via jQuery's `data-` attributes as follows: + +``data-threshold`` defines the amount of time (in milliseconds) after which the `doubletap` event is fired on the target element. + ## 7. Utility Functions: In addition to the numerous additional events that are provided, the library also includes a number of utility functions that can be used to further leverage the power of native events within your website or application. These utility functions can be used for unifying basic events, such as `tapstart` or `mousedown`. From bbc169787a078af051b5040c2428dbcb719ae0e6 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 1 Feb 2017 01:12:17 +0000 Subject: [PATCH 096/149] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 1f3db37..f47ca78 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,9 @@ 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 1.0.7** (2017-02-01) + + Added threshold support for `taphold` + + **Version 1.0.6** (2016-11-16) + Added slop factor for `singletap` + Fixed a bug where `offset()` was sometimes called on `null` (instead of `window`). From 321be57c2ec0b9d286f90f26c10520080cc56f1a Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 1 Feb 2017 17:48:58 +0000 Subject: [PATCH 097/149] Now supports Chrome on all touch devices - Fixes a bug where certain instances of Chrome on touch devices did not correctly fire events. - Added license info to minified script. --- src/1.0.8/jquery.mobile-events.js | 877 ++++++++++++++++++++++++++++++ 1 file changed, 877 insertions(+) create mode 100644 src/1.0.8/jquery.mobile-events.js diff --git a/src/1.0.8/jquery.mobile-events.js b/src/1.0.8/jquery.mobile-events.js new file mode 100644 index 0000000..cfc07c9 --- /dev/null +++ b/src/1.0.8/jquery.mobile-events.js @@ -0,0 +1,877 @@ +/*! + * jQuery Mobile Events + * by Ben Major + * + * Copyright 2011-2015, 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 || {}; + + // navigator.userAgent.toLowerCase() isn't reliable for Chrome installs + // on mobile devices. As such, we will create a boolean isChromeDesktop + // The reason that we need to do this is because Chrome annoyingly + // purports support for touch events even if the underlying hardware + // does not! + var touchCapable = ('ontouchstart' in window), + + settings = { + tap_pixel_range: 5, + swipe_h_threshold: 50, + swipe_v_threshold: 50, + taphold_threshold: 750, + doubletap_int: 500, + + 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 + }; + + // 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; }; + + // Add Event shortcuts: + $.each(['tapstart', 'tapend', 'tapmove', 'tap', 'tap2', 'tap3', 'tap4', 'singletap', 'doubletap', 'taphold', 'swipe', 'swipeup', 'swiperight', 'swipedown', 'swipeleft', 'swipeend', 'scrollstart', 'scrollend', 'orientationchange'], 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 origEvent = e.originalEvent, + touchData = { + 'position': { + 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 origEvent = e.originalEvent, + touchData = { + 'position': { + 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 origEvent = e.originalEvent; + var touchData = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 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; + + settings.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(), + endPosition = { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + endOffset = { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }; + var duration = end_time - start_time; + + // Build the touch data: + var touchData = { + 'startTime': start_time, + 'endTime': end_time, + 'startPosition': startPosition, + 'startOffset': startOffset, + 'endPosition': endPosition, + 'endOffset': endOffset, + 'duration': duration, + 'target': e.target + }; + $this.data('callee1', tapHoldFunc1); + triggerCustomEvent(thisObject, 'taphold', e, touchData); + } + }, threshold); + + return true; + } + }).on(settings.endevent, function tapHoldFunc2() { + $this.data('callee2', tapHoldFunc2); + $this.data('tapheld', false); + window.clearTimeout(settings.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) { + firstTap = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + 'time': Date.now(), + 'target': e.target + }; + } + + 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 == origTarget) && delta > 100) { + $this.data('doubletapped', true); + window.clearTimeout(settings.tap_timer); + + // Now get the current event: + var lastTap = { + 'position': { + 'x': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + 'time': Date.now(), + 'target': e.target + }; + + 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 origEvent = e.originalEvent; + var touchData = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 origEvent = e.originalEvent; + var touchData = [ ]; + + for( var i = 0; i < touches.length; i++) + { + var touch = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[i].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[i].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + 'time': Date.now(), + 'target': e.target + }; + + touchData.push( touch ); + } + + triggerCustomEvent(thisObject, 'tap', 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 origEvent = e.originalEvent; + // Read event data into our startEvt: + startEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 (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 (originalCoord.x > finalCoord.x && (originalCoord.x - finalCoord.x > h_threshold)) { + swipedir = 'swipeleft'; + } + 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 origEvent = e.originalEvent; + var endEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 origEvent = e.originalEvent; + var endEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + 'time': Date.now(), + '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); + + 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' + }, function (e, srcE) { + $.event.special[e] = { + setup: function () { + $(this).on(srcE, $.noop); + } + }; + }); + +}(jQuery)); From ff11421614e48a5165850dfc88e55947bfe7b41e Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 1 Feb 2017 17:49:51 +0000 Subject: [PATCH 098/149] Now supports Chrome on all touch devices - Fixes a bug where certain instances of Chrome on touch devices did not correctly fire events. - Added license info to minified script. --- src/1.0.8/jquery.mobile-events.min.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/1.0.8/jquery.mobile-events.min.js diff --git a/src/1.0.8/jquery.mobile-events.min.js b/src/1.0.8/jquery.mobile-events.min.js new file mode 100644 index 0000000..81f4903 --- /dev/null +++ b/src/1.0.8/jquery.mobile-events.min.js @@ -0,0 +1,27 @@ +/*! + * jQuery Mobile Events + * by Ben Major + * + * Copyright 2011-2015, 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(a){function n(){var a=f();a!==g&&(g=a,d.trigger("orientationchange"))}function u(b,c,d,e){var f=d.type;d.type=c,a.event.dispatch.call(b,d,e),d.type=f}a.attrFn=a.attrFn||{};var b="ontouchstart"in window,c={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:b,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:b?"touchstart":"mousedown",endevent:b?"touchend":"mouseup",moveevent:b?"touchmove":"mousemove",tapevent:b?"tap":"click",scrollevent:b?"touchmove":"scroll",hold_timer:null,tap_timer:null};a.isTouchCapable=function(){return c.touch_capable},a.getStartEvent=function(){return c.startevent},a.getEndEvent=function(){return c.endevent},a.getMoveEvent=function(){return c.moveevent},a.getTapEvent=function(){return c.tapevent},a.getScrollEvent=function(){return c.scrollevent},a.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],function(b,c){a.fn[c]=function(a){return a?this.on(c,a):this.trigger(c)},a.attrFn[c]=!0}),a.event.special.tapstart={setup:function(){var b=this,d=a(b);d.on(c.startevent,function a(e){if(d.data("callee",a),e.which&&1!==e.which)return!1;var f=e.originalEvent,g={position:{x:c.touch_capable?f.touches[0].screenX:e.screenX,y:c.touch_capable?f.touches[0].screenY:e.screenY},offset:{x:c.touch_capable?Math.round(f.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(e.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(f.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(e.pageY-(d.offset()?d.offset().top:0))},time:Date.now(),target:e.target};return u(b,"tapstart",e,g),!0})},remove:function(){a(this).off(c.startevent,a(this).data.callee)}},a.event.special.tapmove={setup:function(){var b=this,d=a(b);d.on(c.moveevent,function a(e){d.data("callee",a);var f=e.originalEvent,g={position:{x:c.touch_capable?f.touches[0].screenX:e.screenX,y:c.touch_capable?f.touches[0].screenY:e.screenY},offset:{x:c.touch_capable?Math.round(f.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(e.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(f.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(e.pageY-(d.offset()?d.offset().top:0))},time:Date.now(),target:e.target};return u(b,"tapmove",e,g),!0})},remove:function(){a(this).off(c.moveevent,a(this).data.callee)}},a.event.special.tapend={setup:function(){var b=this,d=a(b);d.on(c.endevent,function a(e){d.data("callee",a);var f=e.originalEvent,g={position:{x:c.touch_capable?f.changedTouches[0].screenX:e.screenX,y:c.touch_capable?f.changedTouches[0].screenY:e.screenY},offset:{x:c.touch_capable?Math.round(f.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(e.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(f.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(e.pageY-(d.offset()?d.offset().top:0))},time:Date.now(),target:e.target};return u(b,"tapend",e,g),!0})},remove:function(){a(this).off(c.endevent,a(this).data.callee)}},a.event.special.taphold={setup:function(){var e,b=this,d=a(b),f={x:0,y:0},g=0,h=0;d.on(c.startevent,function a(i){if(i.which&&1!==i.which)return!1;d.data("tapheld",!1),e=i.target;var j=i.originalEvent,k=Date.now(),l={x:c.touch_capable?j.touches[0].screenX:i.screenX,y:c.touch_capable?j.touches[0].screenY:i.screenY},m={x:c.touch_capable?j.touches[0].pageX-j.touches[0].target.offsetLeft:i.offsetX,y:c.touch_capable?j.touches[0].pageY-j.touches[0].target.offsetTop:i.offsetY};f.x=i.originalEvent.targetTouches?i.originalEvent.targetTouches[0].pageX:i.pageX,f.y=i.originalEvent.targetTouches?i.originalEvent.targetTouches[0].pageY:i.pageY,g=f.x,h=f.y;var n=d.parent().data("threshold")?d.parent().data("threshold"):d.data("threshold"),o="undefined"!=typeof n&&n!==!1&&parseInt(n)?parseInt(n):c.taphold_threshold;return c.hold_timer=window.setTimeout(function(){var n=f.x-g,o=f.y-h;if(i.target==e&&(f.x==g&&f.y==h||n>=-c.tap_pixel_range&&n<=c.tap_pixel_range&&o>=-c.tap_pixel_range&&o<=c.tap_pixel_range)){d.data("tapheld",!0);var p=Date.now(),q={x:c.touch_capable?j.touches[0].screenX:i.screenX,y:c.touch_capable?j.touches[0].screenY:i.screenY},r={x:c.touch_capable?Math.round(j.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(i.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(j.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(i.pageY-(d.offset()?d.offset().top:0))},s=p-k,t={startTime:k,endTime:p,startPosition:l,startOffset:m,endPosition:q,endOffset:r,duration:s,target:i.target};d.data("callee1",a),u(b,"taphold",i,t)}},o),!0}).on(c.endevent,function a(){d.data("callee2",a),d.data("tapheld",!1),window.clearTimeout(c.hold_timer)}).on(c.moveevent,function a(b){d.data("callee3",a),g=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageX:b.pageX,h=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageY:b.pageY})},remove:function(){a(this).off(c.startevent,a(this).data.callee1).off(c.endevent,a(this).data.callee2).off(c.moveevent,a(this).data.callee3)}},a.event.special.doubletap={setup:function(){var e,f,h,i,b=this,d=a(b),g=null,j=!1;d.on(c.startevent,function a(b){return(!b.which||1===b.which)&&(d.data("doubletapped",!1),e=b.target,d.data("callee1",a),h=b.originalEvent,g||(g={position:{x:c.touch_capable?h.touches[0].screenX:b.screenX,y:c.touch_capable?h.touches[0].screenY:b.screenY},offset:{x:c.touch_capable?Math.round(h.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(b.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(h.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(b.pageY-(d.offset()?d.offset().top:0))},time:Date.now(),target:b.target}),!0)}).on(c.endevent,function a(k){var l=Date.now(),m=d.data("lastTouch")||l+1,n=l-m;if(window.clearTimeout(f),d.data("callee2",a),n100){d.data("doubletapped",!0),window.clearTimeout(c.tap_timer);var o={position:{x:c.touch_capable?k.originalEvent.changedTouches[0].screenX:k.screenX,y:c.touch_capable?k.originalEvent.changedTouches[0].screenY:k.screenY},offset:{x:c.touch_capable?Math.round(h.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(k.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(h.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(k.pageY-(d.offset()?d.offset().top:0))},time:Date.now(),target:k.target},p={firstTap:g,secondTap:o,interval:o.time-g.time};j||(u(b,"doubletap",k,p),g=null),j=!0,i=window.setTimeout(function(){j=!1},c.doubletap_int)}else d.data("lastTouch",l),f=window.setTimeout(function(){g=null,window.clearTimeout(f)},c.doubletap_int,[k]);d.data("lastTouch",l)})},remove:function(){a(this).off(c.startevent,a(this).data.callee1).off(c.endevent,a(this).data.callee2)}},a.event.special.singletap={setup:function(){var b=this,d=a(b),e=null,f=null,g={x:0,y:0};d.on(c.startevent,function a(b){return(!b.which||1===b.which)&&(f=Date.now(),e=b.target,d.data("callee1",a),g.x=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageX:b.pageX,g.y=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageY:b.pageY,!0)}).on(c.endevent,function a(h){if(d.data("callee2",a),h.target==e){var i=h.originalEvent.changedTouches?h.originalEvent.changedTouches[0].pageX:h.pageX,j=h.originalEvent.changedTouches?h.originalEvent.changedTouches[0].pageY:h.pageY;c.tap_timer=window.setTimeout(function(){var a=g.x-i,e=g.y-j;if(!d.data("doubletapped")&&!d.data("tapheld")&&(g.x==i&&g.y==j||a>=-c.tap_pixel_range&&a<=c.tap_pixel_range&&e>=-c.tap_pixel_range&&e<=c.tap_pixel_range)){var k=h.originalEvent,l={position:{x:c.touch_capable?k.changedTouches[0].screenX:h.screenX,y:c.touch_capable?k.changedTouches[0].screenY:h.screenY},offset:{x:c.touch_capable?Math.round(k.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(h.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(k.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(h.pageY-(d.offset()?d.offset().top:0))},time:Date.now(),target:h.target};l.time-f=-c.tap_pixel_range&&m<=c.tap_pixel_range&&n>=-c.tap_pixel_range&&n<=c.tap_pixel_range)){for(var p=j.originalEvent,q=[],r=0;rh.y&&g.y-h.y>o&&(j="swipeup"),g.xn&&(j="swiperight"),g.yo&&(j="swipedown"),g.x>h.x&&g.x-h.x>n&&(j="swipeleft"),void 0!=j&&e){g.x=0,g.y=0,h.x=0,h.y=0,e=!1;var p=b.originalEvent,q={position:{x:c.touch_capable?p.touches[0].screenX:b.screenX,y:c.touch_capable?p.touches[0].screenY:b.screenY},offset:{x:c.touch_capable?Math.round(p.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(b.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(p.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(b.pageY-(d.offset()?d.offset().top:0))},time:Date.now(),target:b.target},r=Math.abs(i.position.x-q.position.x),s=Math.abs(i.position.y-q.position.y),t={startEvnt:i,endEvnt:q,direction:j.replace("swipe",""),xAmount:r,yAmount:s,duration:q.time-i.time};f=!0,d.trigger("swipe",t).trigger(j,t)}}function l(b){d=a(b.currentTarget);var g="";if(d.data("callee3",l),f){var h=d.data("xthreshold"),j=d.data("ythreshold"),k="undefined"!=typeof h&&h!==!1&&parseInt(h)?parseInt(h):c.swipe_h_threshold,m="undefined"!=typeof j&&j!==!1&&parseInt(j)?parseInt(j):c.swipe_v_threshold,n=b.originalEvent,o={position:{x:c.touch_capable?n.changedTouches[0].screenX:b.screenX,y:c.touch_capable?n.changedTouches[0].screenY:b.screenY},offset:{x:c.touch_capable?Math.round(n.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(b.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(n.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(b.pageY-(d.offset()?d.offset().top:0))},time:Date.now(),target:b.target};i.position.y>o.position.y&&i.position.y-o.position.y>m&&(g="swipeup"),i.position.xk&&(g="swiperight"),i.position.ym&&(g="swipedown"),i.position.x>o.position.x&&i.position.x-o.position.x>k&&(g="swipeleft");var p=Math.abs(i.position.x-o.position.x),q=Math.abs(i.position.y-o.position.y),r={startEvnt:i,endEvnt:o,direction:g.replace("swipe",""),xAmount:p,yAmount:q,duration:o.time-i.time};d.trigger("swipeend",r)}e=!1,f=!1}var i,b=this,d=a(b),e=!1,f=!1,g={x:0,y:0},h={x:0,y:0};d.on(c.startevent,j),d.on(c.moveevent,k),d.on(c.endevent,l)},remove:function(){a(this).off(c.startevent,a(this).data.callee1).off(c.moveevent,a(this).data.callee2).off(c.endevent,a(this).data.callee3)}},a.event.special.scrollstart={setup:function(){function g(a,c){e=c,u(b,e?"scrollstart":"scrollend",a)}var e,f,b=this,d=a(b);d.on(c.scrollevent,function a(b){d.data("callee",a),e||g(b,!0),clearTimeout(f),f=setTimeout(function(){g(b,!1)},50)})},remove:function(){a(this).off(c.scrollevent,a(this).data.callee)}};var e,f,g,h,i,d=a(window),j={0:!0,180:!0};if(c.orientation_support){var k=window.innerWidth||d.width(),l=window.innerHeight||d.height(),m=50;h=k>l&&k-l>m,i=j[window.orientation],(h&&i||!h&&!i)&&(j={"-90":!0,90:!0})}a.event.special.orientationchange=e={setup:function(){return!c.orientation_support&&(g=f(),d.on("throttledresize",n),!0)},teardown:function(){return!c.orientation_support&&(d.off("throttledresize",n),!0)},add:function(a){var b=a.handler;a.handler=function(a){return a.orientation=f(),b.apply(this,arguments)}}},a.event.special.orientationchange.orientation=f=function(){var a=!0,b=document.documentElement;return a=c.orientation_support?j[window.orientation]:b&&b.clientWidth/b.clientHeight<1.1,a?"portrait":"landscape"},a.event.special.throttledresize={setup:function(){a(this).on("resize",p)},teardown:function(){a(this).off("resize",p)}};var r,s,t,o=250,p=function(){s=Date.now(),t=s-q,t>=o?(q=s,a(this).trigger("throttledresize")):(r&&window.clearTimeout(r),r=window.setTimeout(n,o-t))},q=0;a.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(b,c){a.event.special[b]={setup:function(){a(this).on(c,a.noop)}}})}(jQuery); From fd574f48bbc2988837c3384867fefe2a9abf0a1c Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 1 Feb 2017 17:50:04 +0000 Subject: [PATCH 099/149] Update jquery.mobile-events.js --- src/1.0.8/jquery.mobile-events.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/1.0.8/jquery.mobile-events.js b/src/1.0.8/jquery.mobile-events.js index cfc07c9..65fb4f6 100644 --- a/src/1.0.8/jquery.mobile-events.js +++ b/src/1.0.8/jquery.mobile-events.js @@ -2,7 +2,7 @@ * jQuery Mobile Events * by Ben Major * - * Copyright 2011-2015, Ben Major + * Copyright 2011-2017, Ben Major * Licensed under the MIT License: * * Permission is hereby granted, free of charge, to any person obtaining a copy From 30b5c3307600d37a8ab1919a0546b0e6362f43a4 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 1 Feb 2017 17:50:17 +0000 Subject: [PATCH 100/149] Update jquery.mobile-events.min.js --- src/1.0.8/jquery.mobile-events.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/1.0.8/jquery.mobile-events.min.js b/src/1.0.8/jquery.mobile-events.min.js index 81f4903..c72b49f 100644 --- a/src/1.0.8/jquery.mobile-events.min.js +++ b/src/1.0.8/jquery.mobile-events.min.js @@ -2,7 +2,7 @@ * jQuery Mobile Events * by Ben Major * - * Copyright 2011-2015, Ben Major + * Copyright 2011-2017, Ben Major * Licensed under the MIT License: * * Permission is hereby granted, free of charge, to any person obtaining a copy From ff27ac4b980125a25d0f3486dbe9a46bb7ba8f83 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 1 Feb 2017 17:50:39 +0000 Subject: [PATCH 101/149] Sync to 1.0.8 --- src/jquery.mobile-events.min.js | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/jquery.mobile-events.min.js b/src/jquery.mobile-events.min.js index 959b843..81f4903 100644 --- a/src/jquery.mobile-events.min.js +++ b/src/jquery.mobile-events.min.js @@ -1 +1,27 @@ -"use strict";!function(a){function o(){var a=g();a!==h&&(h=a,e.trigger("orientationchange"))}function v(b,c,d,e){var f=d.type;d.type=c,a.event.dispatch.call(b,d,e),d.type=f}a.attrFn=a.attrFn||{};var b=navigator.userAgent.toLowerCase(),c=b.indexOf("chrome")>-1&&(b.indexOf("windows")>-1||b.indexOf("macintosh")>-1||b.indexOf("linux")>-1)&&b.indexOf("mobile")<0&&b.indexOf("android")<0,d={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:"ontouchstart"in window&&!c,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:"ontouchstart"in window&&!c?"touchstart":"mousedown",endevent:"ontouchstart"in window&&!c?"touchend":"mouseup",moveevent:"ontouchstart"in window&&!c?"touchmove":"mousemove",tapevent:"ontouchstart"in window&&!c?"tap":"click",scrollevent:"ontouchstart"in window&&!c?"touchmove":"scroll",hold_timer:null,tap_timer:null};a.isTouchCapable=function(){return d.touch_capable},a.getStartEvent=function(){return d.startevent},a.getEndEvent=function(){return d.endevent},a.getMoveEvent=function(){return d.moveevent},a.getTapEvent=function(){return d.tapevent},a.getScrollEvent=function(){return d.scrollevent},a.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],function(b,c){a.fn[c]=function(a){return a?this.on(c,a):this.trigger(c)},a.attrFn[c]=!0}),a.event.special.tapstart={setup:function(){var b=this,c=a(b);c.on(d.startevent,function a(e){if(c.data("callee",a),e.which&&1!==e.which)return!1;var f=e.originalEvent,g={position:{x:d.touch_capable?f.touches[0].screenX:e.screenX,y:d.touch_capable?f.touches[0].screenY:e.screenY},offset:{x:d.touch_capable?Math.round(f.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(e.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(f.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(e.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:e.target};return v(b,"tapstart",e,g),!0})},remove:function(){a(this).off(d.startevent,a(this).data.callee)}},a.event.special.tapmove={setup:function(){var b=this,c=a(b);c.on(d.moveevent,function a(e){c.data("callee",a);var f=e.originalEvent,g={position:{x:d.touch_capable?f.touches[0].screenX:e.screenX,y:d.touch_capable?f.touches[0].screenY:e.screenY},offset:{x:d.touch_capable?Math.round(f.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(e.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(f.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(e.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:e.target};return v(b,"tapmove",e,g),!0})},remove:function(){a(this).off(d.moveevent,a(this).data.callee)}},a.event.special.tapend={setup:function(){var b=this,c=a(b);c.on(d.endevent,function a(e){c.data("callee",a);var f=e.originalEvent,g={position:{x:d.touch_capable?f.changedTouches[0].screenX:e.screenX,y:d.touch_capable?f.changedTouches[0].screenY:e.screenY},offset:{x:d.touch_capable?Math.round(f.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(e.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(f.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(e.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:e.target};return v(b,"tapend",e,g),!0})},remove:function(){a(this).off(d.endevent,a(this).data.callee)}},a.event.special.taphold={setup:function(){var e,b=this,c=a(b),f={x:0,y:0},g=0,h=0;c.on(d.startevent,function a(i){if(i.which&&1!==i.which)return!1;c.data("tapheld",!1),e=i.target;var j=i.originalEvent,k=Date.now(),l={x:d.touch_capable?j.touches[0].screenX:i.screenX,y:d.touch_capable?j.touches[0].screenY:i.screenY},m={x:d.touch_capable?j.touches[0].pageX-j.touches[0].target.offsetLeft:i.offsetX,y:d.touch_capable?j.touches[0].pageY-j.touches[0].target.offsetTop:i.offsetY};f.x=i.originalEvent.targetTouches?i.originalEvent.targetTouches[0].pageX:i.pageX,f.y=i.originalEvent.targetTouches?i.originalEvent.targetTouches[0].pageY:i.pageY,g=f.x,h=f.y;var n=c.parent().data("threshold")?c.parent().data("threshold"):c.data("threshold"),o="undefined"!=typeof n&&n!==!1&&parseInt(n)?parseInt(n):d.taphold_threshold;return d.hold_timer=window.setTimeout(function(){var n=f.x-g,o=f.y-h;if(i.target==e&&(f.x==g&&f.y==h||n>=-d.tap_pixel_range&&n<=d.tap_pixel_range&&o>=-d.tap_pixel_range&&o<=d.tap_pixel_range)){c.data("tapheld",!0);var p=Date.now(),q={x:d.touch_capable?j.touches[0].screenX:i.screenX,y:d.touch_capable?j.touches[0].screenY:i.screenY},r={x:d.touch_capable?Math.round(j.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(i.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(j.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(i.pageY-(c.offset()?c.offset().top:0))},s=p-k,t={startTime:k,endTime:p,startPosition:l,startOffset:m,endPosition:q,endOffset:r,duration:s,target:i.target};c.data("callee1",a),v(b,"taphold",i,t)}},o),!0}).on(d.endevent,function a(){c.data("callee2",a),c.data("tapheld",!1),window.clearTimeout(d.hold_timer)}).on(d.moveevent,function a(b){c.data("callee3",a),g=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageX:b.pageX,h=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageY:b.pageY})},remove:function(){a(this).off(d.startevent,a(this).data.callee1).off(d.endevent,a(this).data.callee2).off(d.moveevent,a(this).data.callee3)}},a.event.special.doubletap={setup:function(){var e,f,h,i,b=this,c=a(b),g=null,j=!1;c.on(d.startevent,function a(b){return(!b.which||1===b.which)&&(c.data("doubletapped",!1),e=b.target,c.data("callee1",a),h=b.originalEvent,g||(g={position:{x:d.touch_capable?h.touches[0].screenX:b.screenX,y:d.touch_capable?h.touches[0].screenY:b.screenY},offset:{x:d.touch_capable?Math.round(h.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(b.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(h.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(b.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:b.target}),!0)}).on(d.endevent,function a(k){var l=Date.now(),m=c.data("lastTouch")||l+1,n=l-m;if(window.clearTimeout(f),c.data("callee2",a),n100){c.data("doubletapped",!0),window.clearTimeout(d.tap_timer);var o={position:{x:d.touch_capable?k.originalEvent.changedTouches[0].screenX:k.screenX,y:d.touch_capable?k.originalEvent.changedTouches[0].screenY:k.screenY},offset:{x:d.touch_capable?Math.round(h.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(k.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(h.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(k.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:k.target},p={firstTap:g,secondTap:o,interval:o.time-g.time};j||(v(b,"doubletap",k,p),g=null),j=!0,i=window.setTimeout(function(){j=!1},d.doubletap_int)}else c.data("lastTouch",l),f=window.setTimeout(function(){g=null,window.clearTimeout(f)},d.doubletap_int,[k]);c.data("lastTouch",l)})},remove:function(){a(this).off(d.startevent,a(this).data.callee1).off(d.endevent,a(this).data.callee2)}},a.event.special.singletap={setup:function(){var b=this,c=a(b),e=null,f=null,g={x:0,y:0};c.on(d.startevent,function a(b){return(!b.which||1===b.which)&&(f=Date.now(),e=b.target,c.data("callee1",a),g.x=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageX:b.pageX,g.y=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageY:b.pageY,!0)}).on(d.endevent,function a(h){if(c.data("callee2",a),h.target==e){var i=h.originalEvent.changedTouches?h.originalEvent.changedTouches[0].pageX:h.pageX,j=h.originalEvent.changedTouches?h.originalEvent.changedTouches[0].pageY:h.pageY;d.tap_timer=window.setTimeout(function(){var a=g.x-i,e=g.y-j;if(!c.data("doubletapped")&&!c.data("tapheld")&&(g.x==i&&g.y==j||a>=-d.tap_pixel_range&&a<=d.tap_pixel_range&&e>=-d.tap_pixel_range&&e<=d.tap_pixel_range)){var k=h.originalEvent,l={position:{x:d.touch_capable?k.changedTouches[0].screenX:h.screenX,y:d.touch_capable?k.changedTouches[0].screenY:h.screenY},offset:{x:d.touch_capable?Math.round(k.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(h.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(k.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(h.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:h.target};l.time-f=-d.tap_pixel_range&&m<=d.tap_pixel_range&&n>=-d.tap_pixel_range&&n<=d.tap_pixel_range)){for(var p=j.originalEvent,q=[],r=0;rh.y&&g.y-h.y>o&&(j="swipeup"),g.xn&&(j="swiperight"),g.yo&&(j="swipedown"),g.x>h.x&&g.x-h.x>n&&(j="swipeleft"),void 0!=j&&e){g.x=0,g.y=0,h.x=0,h.y=0,e=!1;var p=b.originalEvent,q={position:{x:d.touch_capable?p.touches[0].screenX:b.screenX,y:d.touch_capable?p.touches[0].screenY:b.screenY},offset:{x:d.touch_capable?Math.round(p.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(b.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(p.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(b.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:b.target},r=Math.abs(i.position.x-q.position.x),s=Math.abs(i.position.y-q.position.y),t={startEvnt:i,endEvnt:q,direction:j.replace("swipe",""),xAmount:r,yAmount:s,duration:q.time-i.time};f=!0,c.trigger("swipe",t).trigger(j,t)}}function l(b){c=a(b.currentTarget);var g="";if(c.data("callee3",l),f){var h=c.data("xthreshold"),j=c.data("ythreshold"),k="undefined"!=typeof h&&h!==!1&&parseInt(h)?parseInt(h):d.swipe_h_threshold,m="undefined"!=typeof j&&j!==!1&&parseInt(j)?parseInt(j):d.swipe_v_threshold,n=b.originalEvent,o={position:{x:d.touch_capable?n.changedTouches[0].screenX:b.screenX,y:d.touch_capable?n.changedTouches[0].screenY:b.screenY},offset:{x:d.touch_capable?Math.round(n.changedTouches[0].pageX-(c.offset()?c.offset().left:0)):Math.round(b.pageX-(c.offset()?c.offset().left:0)),y:d.touch_capable?Math.round(n.changedTouches[0].pageY-(c.offset()?c.offset().top:0)):Math.round(b.pageY-(c.offset()?c.offset().top:0))},time:Date.now(),target:b.target};i.position.y>o.position.y&&i.position.y-o.position.y>m&&(g="swipeup"),i.position.xk&&(g="swiperight"),i.position.ym&&(g="swipedown"),i.position.x>o.position.x&&i.position.x-o.position.x>k&&(g="swipeleft");var p=Math.abs(i.position.x-o.position.x),q=Math.abs(i.position.y-o.position.y),r={startEvnt:i,endEvnt:o,direction:g.replace("swipe",""),xAmount:p,yAmount:q,duration:o.time-i.time};c.trigger("swipeend",r)}e=!1,f=!1}var i,b=this,c=a(b),e=!1,f=!1,g={x:0,y:0},h={x:0,y:0};c.on(d.startevent,j),c.on(d.moveevent,k),c.on(d.endevent,l)},remove:function(){a(this).off(d.startevent,a(this).data.callee1).off(d.moveevent,a(this).data.callee2).off(d.endevent,a(this).data.callee3)}},a.event.special.scrollstart={setup:function(){function g(a,c){e=c,v(b,e?"scrollstart":"scrollend",a)}var e,f,b=this,c=a(b);c.on(d.scrollevent,function a(b){c.data("callee",a),e||g(b,!0),clearTimeout(f),f=setTimeout(function(){g(b,!1)},50)})},remove:function(){a(this).off(d.scrollevent,a(this).data.callee)}};var f,g,h,i,j,e=a(window),k={0:!0,180:!0};if(d.orientation_support){var l=window.innerWidth||e.width(),m=window.innerHeight||e.height(),n=50;i=l>m&&l-m>n,j=k[window.orientation],(i&&j||!i&&!j)&&(k={"-90":!0,90:!0})}a.event.special.orientationchange=f={setup:function(){return!d.orientation_support&&(h=g(),e.on("throttledresize",o),!0)},teardown:function(){return!d.orientation_support&&(e.off("throttledresize",o),!0)},add:function(a){var b=a.handler;a.handler=function(a){return a.orientation=g(),b.apply(this,arguments)}}},a.event.special.orientationchange.orientation=g=function(){var a=!0,b=document.documentElement;return a=d.orientation_support?k[window.orientation]:b&&b.clientWidth/b.clientHeight<1.1,a?"portrait":"landscape"},a.event.special.throttledresize={setup:function(){a(this).on("resize",q)},teardown:function(){a(this).off("resize",q)}};var s,t,u,p=250,q=function(){t=Date.now(),u=t-r,u>=p?(r=t,a(this).trigger("throttledresize")):(s&&window.clearTimeout(s),s=window.setTimeout(o,p-u))},r=0;a.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(b,c){a.event.special[b]={setup:function(){a(this).on(c,a.noop)}}})}(jQuery); +/*! + * jQuery Mobile Events + * by Ben Major + * + * Copyright 2011-2015, 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(a){function n(){var a=f();a!==g&&(g=a,d.trigger("orientationchange"))}function u(b,c,d,e){var f=d.type;d.type=c,a.event.dispatch.call(b,d,e),d.type=f}a.attrFn=a.attrFn||{};var b="ontouchstart"in window,c={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:b,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:b?"touchstart":"mousedown",endevent:b?"touchend":"mouseup",moveevent:b?"touchmove":"mousemove",tapevent:b?"tap":"click",scrollevent:b?"touchmove":"scroll",hold_timer:null,tap_timer:null};a.isTouchCapable=function(){return c.touch_capable},a.getStartEvent=function(){return c.startevent},a.getEndEvent=function(){return c.endevent},a.getMoveEvent=function(){return c.moveevent},a.getTapEvent=function(){return c.tapevent},a.getScrollEvent=function(){return c.scrollevent},a.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],function(b,c){a.fn[c]=function(a){return a?this.on(c,a):this.trigger(c)},a.attrFn[c]=!0}),a.event.special.tapstart={setup:function(){var b=this,d=a(b);d.on(c.startevent,function a(e){if(d.data("callee",a),e.which&&1!==e.which)return!1;var f=e.originalEvent,g={position:{x:c.touch_capable?f.touches[0].screenX:e.screenX,y:c.touch_capable?f.touches[0].screenY:e.screenY},offset:{x:c.touch_capable?Math.round(f.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(e.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(f.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(e.pageY-(d.offset()?d.offset().top:0))},time:Date.now(),target:e.target};return u(b,"tapstart",e,g),!0})},remove:function(){a(this).off(c.startevent,a(this).data.callee)}},a.event.special.tapmove={setup:function(){var b=this,d=a(b);d.on(c.moveevent,function a(e){d.data("callee",a);var f=e.originalEvent,g={position:{x:c.touch_capable?f.touches[0].screenX:e.screenX,y:c.touch_capable?f.touches[0].screenY:e.screenY},offset:{x:c.touch_capable?Math.round(f.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(e.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(f.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(e.pageY-(d.offset()?d.offset().top:0))},time:Date.now(),target:e.target};return u(b,"tapmove",e,g),!0})},remove:function(){a(this).off(c.moveevent,a(this).data.callee)}},a.event.special.tapend={setup:function(){var b=this,d=a(b);d.on(c.endevent,function a(e){d.data("callee",a);var f=e.originalEvent,g={position:{x:c.touch_capable?f.changedTouches[0].screenX:e.screenX,y:c.touch_capable?f.changedTouches[0].screenY:e.screenY},offset:{x:c.touch_capable?Math.round(f.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(e.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(f.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(e.pageY-(d.offset()?d.offset().top:0))},time:Date.now(),target:e.target};return u(b,"tapend",e,g),!0})},remove:function(){a(this).off(c.endevent,a(this).data.callee)}},a.event.special.taphold={setup:function(){var e,b=this,d=a(b),f={x:0,y:0},g=0,h=0;d.on(c.startevent,function a(i){if(i.which&&1!==i.which)return!1;d.data("tapheld",!1),e=i.target;var j=i.originalEvent,k=Date.now(),l={x:c.touch_capable?j.touches[0].screenX:i.screenX,y:c.touch_capable?j.touches[0].screenY:i.screenY},m={x:c.touch_capable?j.touches[0].pageX-j.touches[0].target.offsetLeft:i.offsetX,y:c.touch_capable?j.touches[0].pageY-j.touches[0].target.offsetTop:i.offsetY};f.x=i.originalEvent.targetTouches?i.originalEvent.targetTouches[0].pageX:i.pageX,f.y=i.originalEvent.targetTouches?i.originalEvent.targetTouches[0].pageY:i.pageY,g=f.x,h=f.y;var n=d.parent().data("threshold")?d.parent().data("threshold"):d.data("threshold"),o="undefined"!=typeof n&&n!==!1&&parseInt(n)?parseInt(n):c.taphold_threshold;return c.hold_timer=window.setTimeout(function(){var n=f.x-g,o=f.y-h;if(i.target==e&&(f.x==g&&f.y==h||n>=-c.tap_pixel_range&&n<=c.tap_pixel_range&&o>=-c.tap_pixel_range&&o<=c.tap_pixel_range)){d.data("tapheld",!0);var p=Date.now(),q={x:c.touch_capable?j.touches[0].screenX:i.screenX,y:c.touch_capable?j.touches[0].screenY:i.screenY},r={x:c.touch_capable?Math.round(j.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(i.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(j.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(i.pageY-(d.offset()?d.offset().top:0))},s=p-k,t={startTime:k,endTime:p,startPosition:l,startOffset:m,endPosition:q,endOffset:r,duration:s,target:i.target};d.data("callee1",a),u(b,"taphold",i,t)}},o),!0}).on(c.endevent,function a(){d.data("callee2",a),d.data("tapheld",!1),window.clearTimeout(c.hold_timer)}).on(c.moveevent,function a(b){d.data("callee3",a),g=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageX:b.pageX,h=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageY:b.pageY})},remove:function(){a(this).off(c.startevent,a(this).data.callee1).off(c.endevent,a(this).data.callee2).off(c.moveevent,a(this).data.callee3)}},a.event.special.doubletap={setup:function(){var e,f,h,i,b=this,d=a(b),g=null,j=!1;d.on(c.startevent,function a(b){return(!b.which||1===b.which)&&(d.data("doubletapped",!1),e=b.target,d.data("callee1",a),h=b.originalEvent,g||(g={position:{x:c.touch_capable?h.touches[0].screenX:b.screenX,y:c.touch_capable?h.touches[0].screenY:b.screenY},offset:{x:c.touch_capable?Math.round(h.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(b.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(h.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(b.pageY-(d.offset()?d.offset().top:0))},time:Date.now(),target:b.target}),!0)}).on(c.endevent,function a(k){var l=Date.now(),m=d.data("lastTouch")||l+1,n=l-m;if(window.clearTimeout(f),d.data("callee2",a),n100){d.data("doubletapped",!0),window.clearTimeout(c.tap_timer);var o={position:{x:c.touch_capable?k.originalEvent.changedTouches[0].screenX:k.screenX,y:c.touch_capable?k.originalEvent.changedTouches[0].screenY:k.screenY},offset:{x:c.touch_capable?Math.round(h.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(k.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(h.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(k.pageY-(d.offset()?d.offset().top:0))},time:Date.now(),target:k.target},p={firstTap:g,secondTap:o,interval:o.time-g.time};j||(u(b,"doubletap",k,p),g=null),j=!0,i=window.setTimeout(function(){j=!1},c.doubletap_int)}else d.data("lastTouch",l),f=window.setTimeout(function(){g=null,window.clearTimeout(f)},c.doubletap_int,[k]);d.data("lastTouch",l)})},remove:function(){a(this).off(c.startevent,a(this).data.callee1).off(c.endevent,a(this).data.callee2)}},a.event.special.singletap={setup:function(){var b=this,d=a(b),e=null,f=null,g={x:0,y:0};d.on(c.startevent,function a(b){return(!b.which||1===b.which)&&(f=Date.now(),e=b.target,d.data("callee1",a),g.x=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageX:b.pageX,g.y=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageY:b.pageY,!0)}).on(c.endevent,function a(h){if(d.data("callee2",a),h.target==e){var i=h.originalEvent.changedTouches?h.originalEvent.changedTouches[0].pageX:h.pageX,j=h.originalEvent.changedTouches?h.originalEvent.changedTouches[0].pageY:h.pageY;c.tap_timer=window.setTimeout(function(){var a=g.x-i,e=g.y-j;if(!d.data("doubletapped")&&!d.data("tapheld")&&(g.x==i&&g.y==j||a>=-c.tap_pixel_range&&a<=c.tap_pixel_range&&e>=-c.tap_pixel_range&&e<=c.tap_pixel_range)){var k=h.originalEvent,l={position:{x:c.touch_capable?k.changedTouches[0].screenX:h.screenX,y:c.touch_capable?k.changedTouches[0].screenY:h.screenY},offset:{x:c.touch_capable?Math.round(k.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(h.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(k.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(h.pageY-(d.offset()?d.offset().top:0))},time:Date.now(),target:h.target};l.time-f=-c.tap_pixel_range&&m<=c.tap_pixel_range&&n>=-c.tap_pixel_range&&n<=c.tap_pixel_range)){for(var p=j.originalEvent,q=[],r=0;rh.y&&g.y-h.y>o&&(j="swipeup"),g.xn&&(j="swiperight"),g.yo&&(j="swipedown"),g.x>h.x&&g.x-h.x>n&&(j="swipeleft"),void 0!=j&&e){g.x=0,g.y=0,h.x=0,h.y=0,e=!1;var p=b.originalEvent,q={position:{x:c.touch_capable?p.touches[0].screenX:b.screenX,y:c.touch_capable?p.touches[0].screenY:b.screenY},offset:{x:c.touch_capable?Math.round(p.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(b.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(p.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(b.pageY-(d.offset()?d.offset().top:0))},time:Date.now(),target:b.target},r=Math.abs(i.position.x-q.position.x),s=Math.abs(i.position.y-q.position.y),t={startEvnt:i,endEvnt:q,direction:j.replace("swipe",""),xAmount:r,yAmount:s,duration:q.time-i.time};f=!0,d.trigger("swipe",t).trigger(j,t)}}function l(b){d=a(b.currentTarget);var g="";if(d.data("callee3",l),f){var h=d.data("xthreshold"),j=d.data("ythreshold"),k="undefined"!=typeof h&&h!==!1&&parseInt(h)?parseInt(h):c.swipe_h_threshold,m="undefined"!=typeof j&&j!==!1&&parseInt(j)?parseInt(j):c.swipe_v_threshold,n=b.originalEvent,o={position:{x:c.touch_capable?n.changedTouches[0].screenX:b.screenX,y:c.touch_capable?n.changedTouches[0].screenY:b.screenY},offset:{x:c.touch_capable?Math.round(n.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(b.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(n.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(b.pageY-(d.offset()?d.offset().top:0))},time:Date.now(),target:b.target};i.position.y>o.position.y&&i.position.y-o.position.y>m&&(g="swipeup"),i.position.xk&&(g="swiperight"),i.position.ym&&(g="swipedown"),i.position.x>o.position.x&&i.position.x-o.position.x>k&&(g="swipeleft");var p=Math.abs(i.position.x-o.position.x),q=Math.abs(i.position.y-o.position.y),r={startEvnt:i,endEvnt:o,direction:g.replace("swipe",""),xAmount:p,yAmount:q,duration:o.time-i.time};d.trigger("swipeend",r)}e=!1,f=!1}var i,b=this,d=a(b),e=!1,f=!1,g={x:0,y:0},h={x:0,y:0};d.on(c.startevent,j),d.on(c.moveevent,k),d.on(c.endevent,l)},remove:function(){a(this).off(c.startevent,a(this).data.callee1).off(c.moveevent,a(this).data.callee2).off(c.endevent,a(this).data.callee3)}},a.event.special.scrollstart={setup:function(){function g(a,c){e=c,u(b,e?"scrollstart":"scrollend",a)}var e,f,b=this,d=a(b);d.on(c.scrollevent,function a(b){d.data("callee",a),e||g(b,!0),clearTimeout(f),f=setTimeout(function(){g(b,!1)},50)})},remove:function(){a(this).off(c.scrollevent,a(this).data.callee)}};var e,f,g,h,i,d=a(window),j={0:!0,180:!0};if(c.orientation_support){var k=window.innerWidth||d.width(),l=window.innerHeight||d.height(),m=50;h=k>l&&k-l>m,i=j[window.orientation],(h&&i||!h&&!i)&&(j={"-90":!0,90:!0})}a.event.special.orientationchange=e={setup:function(){return!c.orientation_support&&(g=f(),d.on("throttledresize",n),!0)},teardown:function(){return!c.orientation_support&&(d.off("throttledresize",n),!0)},add:function(a){var b=a.handler;a.handler=function(a){return a.orientation=f(),b.apply(this,arguments)}}},a.event.special.orientationchange.orientation=f=function(){var a=!0,b=document.documentElement;return a=c.orientation_support?j[window.orientation]:b&&b.clientWidth/b.clientHeight<1.1,a?"portrait":"landscape"},a.event.special.throttledresize={setup:function(){a(this).on("resize",p)},teardown:function(){a(this).off("resize",p)}};var r,s,t,o=250,p=function(){s=Date.now(),t=s-q,t>=o?(q=s,a(this).trigger("throttledresize")):(r&&window.clearTimeout(r),r=window.setTimeout(n,o-t))},q=0;a.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(b,c){a.event.special[b]={setup:function(){a(this).on(c,a.noop)}}})}(jQuery); From 7982335dc944ada452f45f2ac9fd0eb64a423553 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 1 Feb 2017 17:50:59 +0000 Subject: [PATCH 102/149] Sync to 1.0.8 --- src/jquery.mobile-events.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/jquery.mobile-events.js b/src/jquery.mobile-events.js index 25d4f85..65fb4f6 100644 --- a/src/jquery.mobile-events.js +++ b/src/jquery.mobile-events.js @@ -2,7 +2,7 @@ * jQuery Mobile Events * by Ben Major * - * Copyright 2011-2015, Ben Major + * Copyright 2011-2017, Ben Major * Licensed under the MIT License: * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -35,9 +35,8 @@ // The reason that we need to do this is because Chrome annoyingly // purports support for touch events even if the underlying hardware // does not! - var agent = navigator.userAgent.toLowerCase(), - isChromeDesktop = (agent.indexOf('chrome') > -1 && ((agent.indexOf('windows') > -1) || (agent.indexOf('macintosh') > -1) || (agent.indexOf('linux') > -1)) && agent.indexOf('mobile') < 0 && agent.indexOf('android') < 0), - + var touchCapable = ('ontouchstart' in window), + settings = { tap_pixel_range: 5, swipe_h_threshold: 50, @@ -45,14 +44,14 @@ taphold_threshold: 750, doubletap_int: 500, - touch_capable: ('ontouchstart' in window && !isChromeDesktop), + touch_capable: touchCapable, orientation_support: ('orientation' in window && 'onorientationchange' in window), - startevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchstart' : 'mousedown'), - endevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchend' : 'mouseup'), - moveevent: (('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'mousemove'), - tapevent: ('ontouchstart' in window && !isChromeDesktop) ? 'tap' : 'click', - scrollevent: ('ontouchstart' in window && !isChromeDesktop) ? 'touchmove' : 'scroll', + 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 From e16041cbb359d1a53d828278dd78ca658c02ba33 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 1 Feb 2017 17:52:23 +0000 Subject: [PATCH 103/149] Added version info for 1.0.8 --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index f47ca78..38a5156 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,10 @@ 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 1.0.8** (2017-02-01) + + Fixes a bug where certain instances of Chrome on touch devices did not correctly fire events. + + Added license info to minified script. + + **Version 1.0.7** (2017-02-01) + Added threshold support for `taphold` From 7c787ae7a0fb2d814dfd56a3c03e5487478e5eb7 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 1 Feb 2017 17:53:07 +0000 Subject: [PATCH 104/149] Added tag for 1.0.8 --- bower.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bower.json b/bower.json index 859be7f..8a9e90f 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jquery-touch-events", - "version": "1.0.7", + "version": "1.0.8", "main": "src/jquery.mobile-events.js", "ignore": [ "bower.json" From a0b021e8f1a9a79ed32325bd45fc6071479f6b91 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 1 Feb 2017 17:53:18 +0000 Subject: [PATCH 105/149] Added tag for 1.0.8 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 03e40e8..bd630c5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jquery-touch-events", - "version": "1.0.7", + "version": "1.0.8", "description": "Polyfill to remove click delays on browsers with touch UIs.", "maintainers": [ { From f424e9df3bfd38605d59642d5101443103818c3c Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 12 May 2017 13:57:06 +0100 Subject: [PATCH 106/149] Update README.md Removed references to live() and bind(). --- README.md | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 38a5156..9cc135f 100644 --- a/README.md +++ b/README.md @@ -87,23 +87,14 @@ $ npm install git+https://github.com/benmajor/jQuery-Touch-Events.git ``` ### 3. Usage: -All of the events outlined above have been written using jQuery's ``event.special`` object, and so can be used in conjunction with jQuery's event handling functions, as well as shortcut wrappers. As a result, all of the events that are supported by this library may be handled using any of jQuery's own event-specific methods, such as `bind()`, `on()`, `live()` (for legacy) and `one()`. +All of the events outlined above have been written using jQuery's ``event.special`` object, and so can be used in conjunction with jQuery's event handling functions, as well as shortcut wrappers. As a result, all of the events that are supported by this library may be handled using any of jQuery's own event-specific methods, such as `on()` and `one()`. The following code snippets showcase some basic usage with jQuery: **Binding a ``tap`` event to an element:** -``` -$('#myElement').bind('tap', function(e) { - console.log('User tapped #myElement'); -}); -``` -**Using with ``.on()`` and ``.live()``:** -``` -$('#myElement').live('tap', function(e) { - console.log('User tapped #myElement'); -}); -``` +When binding, you should use jQuery's `on()` function as follows (avoid the use of `live()` and `bind()` as these are now deprecated and will be removed from future versions of jQuery). + ``` $('#myElement').on('tap', function(e) { console.log('User tapped #myElement'); @@ -115,16 +106,10 @@ $('#myElement').on('tap', function(e) { $('#myElement').trigger('tap'); ``` -**Removing the event with ``.off()``, ``.die()`` and ``.unbind()``:** +**Removing the event:** ``` $('#myElement').off('tap', handler); ``` -``` -$('#myElement').die('tap', handler); -``` -``` -$('#myElement').unbind('tap', handler); -``` **Using method wrapper:** ``` From 5890ad1b799134af5715e44b7c6269f44ced3009 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 7 Jun 2017 09:51:11 +0100 Subject: [PATCH 107/149] Fixed index issue Fixes a minor issue where binding to elements with the same selector caused `doubletap` to fire incorrectly. --- src/1.0.9 | 882 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 882 insertions(+) create mode 100644 src/1.0.9 diff --git a/src/1.0.9 b/src/1.0.9 new file mode 100644 index 0000000..6976761 --- /dev/null +++ b/src/1.0.9 @@ -0,0 +1,882 @@ +/*! + * jQuery Mobile Events + * by Ben Major + * + * Copyright 2011-2017, 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 || {}; + + // navigator.userAgent.toLowerCase() isn't reliable for Chrome installs + // on mobile devices. As such, we will create a boolean isChromeDesktop + // The reason that we need to do this is because Chrome annoyingly + // purports support for touch events even if the underlying hardware + // does not! + var touchCapable = ('ontouchstart' in window), + + settings = { + tap_pixel_range: 5, + swipe_h_threshold: 50, + swipe_v_threshold: 50, + taphold_threshold: 750, + doubletap_int: 500, + + 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 + }; + + // 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; }; + + // Add Event shortcuts: + $.each(['tapstart', 'tapend', 'tapmove', 'tap', 'tap2', 'tap3', 'tap4', 'singletap', 'doubletap', 'taphold', 'swipe', 'swipeup', 'swiperight', 'swipedown', 'swipeleft', 'swipeend', 'scrollstart', 'scrollend', 'orientationchange'], 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 origEvent = e.originalEvent, + touchData = { + 'position': { + 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 origEvent = e.originalEvent, + touchData = { + 'position': { + 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 origEvent = e.originalEvent; + var touchData = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 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; + + settings.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(), + endPosition = { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + endOffset = { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }; + var duration = end_time - start_time; + + // Build the touch data: + var touchData = { + 'startTime': start_time, + 'endTime': end_time, + 'startPosition': startPosition, + 'startOffset': startOffset, + 'endPosition': endPosition, + 'endOffset': endOffset, + 'duration': duration, + 'target': e.target + }; + $this.data('callee1', tapHoldFunc1); + triggerCustomEvent(thisObject, 'taphold', e, touchData); + } + }, threshold); + + return true; + } + }).on(settings.endevent, function tapHoldFunc2() { + $this.data('callee2', tapHoldFunc2); + $this.data('tapheld', false); + window.clearTimeout(settings.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) { + firstTap = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 lastTap = { + 'position': { + 'x': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 origEvent = e.originalEvent; + var touchData = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 origEvent = e.originalEvent; + var touchData = [ ]; + + for( var i = 0; i < touches.length; i++) + { + var touch = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[i].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[i].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + 'time': Date.now(), + 'target': e.target + }; + + touchData.push( touch ); + } + + triggerCustomEvent(thisObject, 'tap', 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 origEvent = e.originalEvent; + // Read event data into our startEvt: + startEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 (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 (originalCoord.x > finalCoord.x && (originalCoord.x - finalCoord.x > h_threshold)) { + swipedir = 'swipeleft'; + } + 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 origEvent = e.originalEvent; + var endEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 origEvent = e.originalEvent; + var endEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + 'time': Date.now(), + '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); + + 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' + }, function (e, srcE) { + $.event.special[e] = { + setup: function () { + $(this).on(srcE, $.noop); + } + }; + }); + +}(jQuery)); From 44c98577a5d4220a3f776bb389ef610d95e24a99 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 7 Jun 2017 09:51:39 +0100 Subject: [PATCH 108/149] Delete 1.0.9 --- src/1.0.9 | 882 ------------------------------------------------------ 1 file changed, 882 deletions(-) delete mode 100644 src/1.0.9 diff --git a/src/1.0.9 b/src/1.0.9 deleted file mode 100644 index 6976761..0000000 --- a/src/1.0.9 +++ /dev/null @@ -1,882 +0,0 @@ -/*! - * jQuery Mobile Events - * by Ben Major - * - * Copyright 2011-2017, 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 || {}; - - // navigator.userAgent.toLowerCase() isn't reliable for Chrome installs - // on mobile devices. As such, we will create a boolean isChromeDesktop - // The reason that we need to do this is because Chrome annoyingly - // purports support for touch events even if the underlying hardware - // does not! - var touchCapable = ('ontouchstart' in window), - - settings = { - tap_pixel_range: 5, - swipe_h_threshold: 50, - swipe_v_threshold: 50, - taphold_threshold: 750, - doubletap_int: 500, - - 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 - }; - - // 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; }; - - // Add Event shortcuts: - $.each(['tapstart', 'tapend', 'tapmove', 'tap', 'tap2', 'tap3', 'tap4', 'singletap', 'doubletap', 'taphold', 'swipe', 'swipeup', 'swiperight', 'swipedown', 'swipeleft', 'swipeend', 'scrollstart', 'scrollend', 'orientationchange'], 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 origEvent = e.originalEvent, - touchData = { - 'position': { - 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), - 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY - }, - 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) - }, - '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 origEvent = e.originalEvent, - touchData = { - 'position': { - 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), - 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY - }, - 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) - }, - '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 origEvent = e.originalEvent; - var touchData = { - 'position': { - 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY - }, - 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) - }, - '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].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY - }, - 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; - - settings.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(), - endPosition = { - 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY - }, - endOffset = { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) - }; - var duration = end_time - start_time; - - // Build the touch data: - var touchData = { - 'startTime': start_time, - 'endTime': end_time, - 'startPosition': startPosition, - 'startOffset': startOffset, - 'endPosition': endPosition, - 'endOffset': endOffset, - 'duration': duration, - 'target': e.target - }; - $this.data('callee1', tapHoldFunc1); - triggerCustomEvent(thisObject, 'taphold', e, touchData); - } - }, threshold); - - return true; - } - }).on(settings.endevent, function tapHoldFunc2() { - $this.data('callee2', tapHoldFunc2); - $this.data('tapheld', false); - window.clearTimeout(settings.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) { - firstTap = { - 'position': { - 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY - }, - 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) - }, - '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 lastTap = { - 'position': { - 'x': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenX : e.screenX, - 'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenY : e.screenY - }, - 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) - }, - '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 origEvent = e.originalEvent; - var touchData = { - 'position': { - 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY - }, - 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) - }, - '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 origEvent = e.originalEvent; - var touchData = [ ]; - - for( var i = 0; i < touches.length; i++) - { - var touch = { - 'position': { - 'x': (settings.touch_capable) ? origEvent.changedTouches[i].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.changedTouches[i].screenY : e.screenY - }, - 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) - }, - 'time': Date.now(), - 'target': e.target - }; - - touchData.push( touch ); - } - - triggerCustomEvent(thisObject, 'tap', 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 origEvent = e.originalEvent; - // Read event data into our startEvt: - startEvnt = { - 'position': { - 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY - }, - 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) - }, - '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 (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 (originalCoord.x > finalCoord.x && (originalCoord.x - finalCoord.x > h_threshold)) { - swipedir = 'swipeleft'; - } - 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 origEvent = e.originalEvent; - var endEvnt = { - 'position': { - 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY - }, - 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) - }, - '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 origEvent = e.originalEvent; - var endEvnt = { - 'position': { - 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY - }, - 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) - }, - 'time': Date.now(), - '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); - - 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' - }, function (e, srcE) { - $.event.special[e] = { - setup: function () { - $(this).on(srcE, $.noop); - } - }; - }); - -}(jQuery)); From 6239fd9af4f823a547a842ecafb6f3995dc5c0d8 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 7 Jun 2017 09:52:12 +0100 Subject: [PATCH 109/149] Fix for index bug Fixes a minor issue where binding to elements with the same selector caused `doubletap` to fire incorrectly. --- src/1.0.9/jquery.mobile-events.js | 882 ++++++++++++++++++++++++++++++ 1 file changed, 882 insertions(+) create mode 100644 src/1.0.9/jquery.mobile-events.js diff --git a/src/1.0.9/jquery.mobile-events.js b/src/1.0.9/jquery.mobile-events.js new file mode 100644 index 0000000..6976761 --- /dev/null +++ b/src/1.0.9/jquery.mobile-events.js @@ -0,0 +1,882 @@ +/*! + * jQuery Mobile Events + * by Ben Major + * + * Copyright 2011-2017, 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 || {}; + + // navigator.userAgent.toLowerCase() isn't reliable for Chrome installs + // on mobile devices. As such, we will create a boolean isChromeDesktop + // The reason that we need to do this is because Chrome annoyingly + // purports support for touch events even if the underlying hardware + // does not! + var touchCapable = ('ontouchstart' in window), + + settings = { + tap_pixel_range: 5, + swipe_h_threshold: 50, + swipe_v_threshold: 50, + taphold_threshold: 750, + doubletap_int: 500, + + 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 + }; + + // 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; }; + + // Add Event shortcuts: + $.each(['tapstart', 'tapend', 'tapmove', 'tap', 'tap2', 'tap3', 'tap4', 'singletap', 'doubletap', 'taphold', 'swipe', 'swipeup', 'swiperight', 'swipedown', 'swipeleft', 'swipeend', 'scrollstart', 'scrollend', 'orientationchange'], 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 origEvent = e.originalEvent, + touchData = { + 'position': { + 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 origEvent = e.originalEvent, + touchData = { + 'position': { + 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 origEvent = e.originalEvent; + var touchData = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 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; + + settings.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(), + endPosition = { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + endOffset = { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }; + var duration = end_time - start_time; + + // Build the touch data: + var touchData = { + 'startTime': start_time, + 'endTime': end_time, + 'startPosition': startPosition, + 'startOffset': startOffset, + 'endPosition': endPosition, + 'endOffset': endOffset, + 'duration': duration, + 'target': e.target + }; + $this.data('callee1', tapHoldFunc1); + triggerCustomEvent(thisObject, 'taphold', e, touchData); + } + }, threshold); + + return true; + } + }).on(settings.endevent, function tapHoldFunc2() { + $this.data('callee2', tapHoldFunc2); + $this.data('tapheld', false); + window.clearTimeout(settings.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) { + firstTap = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 lastTap = { + 'position': { + 'x': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 origEvent = e.originalEvent; + var touchData = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 origEvent = e.originalEvent; + var touchData = [ ]; + + for( var i = 0; i < touches.length; i++) + { + var touch = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[i].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[i].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + 'time': Date.now(), + 'target': e.target + }; + + touchData.push( touch ); + } + + triggerCustomEvent(thisObject, 'tap', 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 origEvent = e.originalEvent; + // Read event data into our startEvt: + startEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 (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 (originalCoord.x > finalCoord.x && (originalCoord.x - finalCoord.x > h_threshold)) { + swipedir = 'swipeleft'; + } + 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 origEvent = e.originalEvent; + var endEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 origEvent = e.originalEvent; + var endEvnt = { + 'position': { + 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, + 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + }, + 'offset': { + 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + 'time': Date.now(), + '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); + + 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' + }, function (e, srcE) { + $.event.special[e] = { + setup: function () { + $(this).on(srcE, $.noop); + } + }; + }); + +}(jQuery)); From 1f5ad5910c4f9d35c80f5a950356d55512795ab3 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 7 Jun 2017 09:53:45 +0100 Subject: [PATCH 110/149] Fix for index bug Fixes a minor issue where binding to elements with the same selector caused `doubletap` to fire incorrectly. --- src/1.0.9/jquery.mobile-events.min.js | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/1.0.9/jquery.mobile-events.min.js diff --git a/src/1.0.9/jquery.mobile-events.min.js b/src/1.0.9/jquery.mobile-events.min.js new file mode 100644 index 0000000..0269098 --- /dev/null +++ b/src/1.0.9/jquery.mobile-events.min.js @@ -0,0 +1,28 @@ +/*! + * jQuery Mobile Events + * by Ben Major + * + * Copyright 2011-2017, 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(a){function b(){var x=j();x!==k&&(k=x,g.trigger('orientationchange'))}function c(x,y,z,A){var B=z.type;z.type=y,a.event.dispatch.call(x,z,A),z.type=B}a.attrFn=a.attrFn||{};var d='ontouchstart'in window,f={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:d,orientation_support:'orientation'in window&&'onorientationchange'in window,startevent:d?'touchstart':'mousedown',endevent:d?'touchend':'mouseup',moveevent:d?'touchmove':'mousemove',tapevent:d?'tap':'click',scrollevent:d?'touchmove':'scroll',hold_timer:null,tap_timer:null};a.isTouchCapable=function(){return f.touch_capable},a.getStartEvent=function(){return f.startevent},a.getEndEvent=function(){return f.endevent},a.getMoveEvent=function(){return f.moveevent},a.getTapEvent=function(){return f.tapevent},a.getScrollEvent=function(){return f.scrollevent},a.each(['tapstart','tapend','tapmove','tap','tap2','tap3','tap4','singletap','doubletap','taphold','swipe','swipeup','swiperight','swipedown','swipeleft','swipeend','scrollstart','scrollend','orientationchange'],function(x,y){a.fn[y]=function(z){return z?this.on(y,z):this.trigger(y)},a.attrFn[y]=!0}),a.event.special.tapstart={setup:function(){var x=this,y=a(x);y.on(f.startevent,function z(A){if(y.data('callee',z),A.which&&1!==A.which)return!1;var B=A.originalEvent,C={position:{x:f.touch_capable?B.touches[0].screenX:A.screenX,y:f.touch_capable?B.touches[0].screenY:A.screenY},offset:{x:f.touch_capable?Math.round(B.changedTouches[0].pageX-(y.offset()?y.offset().left:0)):Math.round(A.pageX-(y.offset()?y.offset().left:0)),y:f.touch_capable?Math.round(B.changedTouches[0].pageY-(y.offset()?y.offset().top:0)):Math.round(A.pageY-(y.offset()?y.offset().top:0))},time:Date.now(),target:A.target};return c(x,'tapstart',A,C),!0})},remove:function(){a(this).off(f.startevent,a(this).data.callee)}},a.event.special.tapmove={setup:function(){var x=this,y=a(x);y.on(f.moveevent,function z(A){y.data('callee',z);var B=A.originalEvent,C={position:{x:f.touch_capable?B.touches[0].screenX:A.screenX,y:f.touch_capable?B.touches[0].screenY:A.screenY},offset:{x:f.touch_capable?Math.round(B.changedTouches[0].pageX-(y.offset()?y.offset().left:0)):Math.round(A.pageX-(y.offset()?y.offset().left:0)),y:f.touch_capable?Math.round(B.changedTouches[0].pageY-(y.offset()?y.offset().top:0)):Math.round(A.pageY-(y.offset()?y.offset().top:0))},time:Date.now(),target:A.target};return c(x,'tapmove',A,C),!0})},remove:function(){a(this).off(f.moveevent,a(this).data.callee)}},a.event.special.tapend={setup:function(){var x=this,y=a(x);y.on(f.endevent,function z(A){y.data('callee',z);var B=A.originalEvent,C={position:{x:f.touch_capable?B.changedTouches[0].screenX:A.screenX,y:f.touch_capable?B.changedTouches[0].screenY:A.screenY},offset:{x:f.touch_capable?Math.round(B.changedTouches[0].pageX-(y.offset()?y.offset().left:0)):Math.round(A.pageX-(y.offset()?y.offset().left:0)),y:f.touch_capable?Math.round(B.changedTouches[0].pageY-(y.offset()?y.offset().top:0)):Math.round(A.pageY-(y.offset()?y.offset().top:0))},time:Date.now(),target:A.target};return c(x,'tapend',A,C),!0})},remove:function(){a(this).off(f.endevent,a(this).data.callee)}},a.event.special.taphold={setup:function(){var z,x=this,y=a(x),A={x:0,y:0},B=0,C=0;y.on(f.startevent,function D(E){if(E.which&&1!==E.which)return!1;y.data('tapheld',!1),z=E.target;var F=E.originalEvent,G=Date.now(),H={x:f.touch_capable?F.touches[0].screenX:E.screenX,y:f.touch_capable?F.touches[0].screenY:E.screenY},I={x:f.touch_capable?F.touches[0].pageX-F.touches[0].target.offsetLeft:E.offsetX,y:f.touch_capable?F.touches[0].pageY-F.touches[0].target.offsetTop:E.offsetY};A.x=E.originalEvent.targetTouches?E.originalEvent.targetTouches[0].pageX:E.pageX,A.y=E.originalEvent.targetTouches?E.originalEvent.targetTouches[0].pageY:E.pageY,B=A.x,C=A.y;var J=y.parent().data('threshold')?y.parent().data('threshold'):y.data('threshold'),K='undefined'!=typeof J&&!1!==J&&parseInt(J)?parseInt(J):f.taphold_threshold;return f.hold_timer=window.setTimeout(function(){var L=A.x-B,M=A.y-C;if(E.target==z&&(A.x==B&&A.y==C||L>=-f.tap_pixel_range&&L<=f.tap_pixel_range&&M>=-f.tap_pixel_range&&M<=f.tap_pixel_range)){y.data('tapheld',!0);var N=Date.now(),O={x:f.touch_capable?F.touches[0].screenX:E.screenX,y:f.touch_capable?F.touches[0].screenY:E.screenY},P={x:f.touch_capable?Math.round(F.changedTouches[0].pageX-(y.offset()?y.offset().left:0)):Math.round(E.pageX-(y.offset()?y.offset().left:0)),y:f.touch_capable?Math.round(F.changedTouches[0].pageY-(y.offset()?y.offset().top:0)):Math.round(E.pageY-(y.offset()?y.offset().top:0))},R={startTime:G,endTime:N,startPosition:H,startOffset:I,endPosition:O,endOffset:P,duration:N-G,target:E.target};y.data('callee1',D),c(x,'taphold',E,R)}},K),!0}).on(f.endevent,function D(){y.data('callee2',D),y.data('tapheld',!1),window.clearTimeout(f.hold_timer)}).on(f.moveevent,function D(E){y.data('callee3',D),B=E.originalEvent.targetTouches?E.originalEvent.targetTouches[0].pageX:E.pageX,C=E.originalEvent.targetTouches?E.originalEvent.targetTouches[0].pageY:E.pageY})},remove:function(){a(this).off(f.startevent,a(this).data.callee1).off(f.endevent,a(this).data.callee2).off(f.moveevent,a(this).data.callee3)}},a.event.special.doubletap={setup:function(){var z,A,C,D,x=this,y=a(x),B=null,E=!1;y.on(f.startevent,function F(G){return G.which&&1!==G.which?!1:(y.data('doubletapped',!1),z=G.target,y.data('callee1',F),C=G.originalEvent,B||(B={position:{x:f.touch_capable?C.touches[0].screenX:G.screenX,y:f.touch_capable?C.touches[0].screenY:G.screenY},offset:{x:f.touch_capable?Math.round(C.changedTouches[0].pageX-(y.offset()?y.offset().left:0)):Math.round(G.pageX-(y.offset()?y.offset().left:0)),y:f.touch_capable?Math.round(C.changedTouches[0].pageY-(y.offset()?y.offset().top:0)):Math.round(G.pageY-(y.offset()?y.offset().top:0))},time:Date.now(),target:G.target,element:G.originalEvent.srcElement,index:a(G.target).index()}),!0)}).on(f.endevent,function F(G){var H=Date.now(),I=y.data('lastTouch')||H+1,J=H-I;if(window.clearTimeout(A),y.data('callee2',F),J=-f.tap_pixel_range&&G<=f.tap_pixel_range&&H>=-f.tap_pixel_range&&H<=f.tap_pixel_range)){var I=D.originalEvent,J={position:{x:f.touch_capable?I.changedTouches[0].screenX:D.screenX,y:f.touch_capable?I.changedTouches[0].screenY:D.screenY},offset:{x:f.touch_capable?Math.round(I.changedTouches[0].pageX-(y.offset()?y.offset().left:0)):Math.round(D.pageX-(y.offset()?y.offset().left:0)),y:f.touch_capable?Math.round(I.changedTouches[0].pageY-(y.offset()?y.offset().top:0)):Math.round(D.pageY-(y.offset()?y.offset().top:0))},time:Date.now(),target:D.target};J.time-A=-f.tap_pixel_range&&I<=f.tap_pixel_range&&J>=-f.tap_pixel_range&&J<=f.tap_pixel_range)){for(var O,L=F.originalEvent,M=[],N=0;NF.y&&E.y-F.y>M&&(I='swipeup'),E.xL&&(I='swiperight'),E.yM&&(I='swipedown'),E.x>F.x&&E.x-F.x>L&&(I='swipeleft'),void 0!=I&&C){E.x=0,E.y=0,F.x=0,F.y=0,C=!1;var N=H.originalEvent,O={position:{x:f.touch_capable?N.touches[0].screenX:H.screenX,y:f.touch_capable?N.touches[0].screenY:H.screenY},offset:{x:f.touch_capable?Math.round(N.changedTouches[0].pageX-(B.offset()?B.offset().left:0)):Math.round(H.pageX-(B.offset()?B.offset().left:0)),y:f.touch_capable?Math.round(N.changedTouches[0].pageY-(B.offset()?B.offset().top:0)):Math.round(H.pageY-(B.offset()?B.offset().top:0))},time:Date.now(),target:H.target},P=Math.abs(G.position.x-O.position.x),Q=Math.abs(G.position.y-O.position.y),R={startEvnt:G,endEvnt:O,direction:I.replace('swipe',''),xAmount:P,yAmount:Q,duration:O.time-G.time};D=!0,B.trigger('swipe',R).trigger(I,R)}}function z(H){B=a(H.currentTarget);var I='';if(B.data('callee3',z),D){var J=B.data('xthreshold'),K=B.data('ythreshold'),L='undefined'!=typeof J&&!1!==J&&parseInt(J)?parseInt(J):f.swipe_h_threshold,M='undefined'!=typeof K&&!1!==K&&parseInt(K)?parseInt(K):f.swipe_v_threshold,N=H.originalEvent,O={position:{x:f.touch_capable?N.changedTouches[0].screenX:H.screenX,y:f.touch_capable?N.changedTouches[0].screenY:H.screenY},offset:{x:f.touch_capable?Math.round(N.changedTouches[0].pageX-(B.offset()?B.offset().left:0)):Math.round(H.pageX-(B.offset()?B.offset().left:0)),y:f.touch_capable?Math.round(N.changedTouches[0].pageY-(B.offset()?B.offset().top:0)):Math.round(H.pageY-(B.offset()?B.offset().top:0))},time:Date.now(),target:H.target};G.position.y>O.position.y&&G.position.y-O.position.y>M&&(I='swipeup'),G.position.xL&&(I='swiperight'),G.position.yM&&(I='swipedown'),G.position.x>O.position.x&&G.position.x-O.position.x>L&&(I='swipeleft');var P=Math.abs(G.position.x-O.position.x),Q=Math.abs(G.position.y-O.position.y),R={startEvnt:G,endEvnt:O,direction:I.replace('swipe',''),xAmount:P,yAmount:Q,duration:O.time-G.time};B.trigger('swipeend',R)}C=!1,D=!1}var G,A=this,B=a(A),C=!1,D=!1,E={x:0,y:0},F={x:0,y:0};B.on(f.startevent,x),B.on(f.moveevent,y),B.on(f.endevent,z)},remove:function(){a(this).off(f.startevent,a(this).data.callee1).off(f.moveevent,a(this).data.callee2).off(f.endevent,a(this).data.callee3)}},a.event.special.scrollstart={setup:function(){function x(C,D){A=D,c(y,A?'scrollstart':'scrollend',C)}var A,B,y=this,z=a(y);z.on(f.scrollevent,function C(D){z.data('callee',C),A||x(D,!0),clearTimeout(B),B=setTimeout(function(){x(D,!1)},50)})},remove:function(){a(this).off(f.scrollevent,a(this).data.callee)}};var h,j,k,l,m,g=a(window),n={0:!0,180:!0};if(f.orientation_support){var o=window.innerWidth||g.width(),p=window.innerHeight||g.height();l=o>p&&o-p>50,m=n[window.orientation],(l&&m||!l&&!m)&&(n={90:!0,'-90':!0})}a.event.special.orientationchange=h={setup:function(){return!f.orientation_support&&(k=j(),g.on('throttledresize',b),!0)},teardown:function(){return!f.orientation_support&&(g.off('throttledresize',b),!0)},add:function(x){var y=x.handler;x.handler=function(z){return z.orientation=j(),y.apply(this,arguments)}}},a.event.special.orientationchange.orientation=j=function(){var x=!0,y=document.documentElement;return x=f.orientation_support?n[window.orientation]:y&&1.1>y.clientWidth/y.clientHeight,x?'portrait':'landscape'},a.event.special.throttledresize={setup:function(){a(this).on('resize',s)},teardown:function(){a(this).off('resize',s)}};var u,v,w,r=250,s=function(){v=Date.now(),w=v-t,w>=r?(t=v,a(this).trigger('throttledresize')):(u&&window.clearTimeout(u),u=window.setTimeout(b,r-w))},t=0;a.each({scrollend:'scrollstart',swipeup:'swipe',swiperight:'swipe',swipedown:'swipe',swipeleft:'swipe',swipeend:'swipe',tap2:'tap'},function(x,y){a.event.special[x]={setup:function(){a(this).on(y,a.noop)}}})})(jQuery); From b3e842e795676df9f27b60cdd32de27288fe71a3 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 7 Jun 2017 09:55:16 +0100 Subject: [PATCH 111/149] Added v1.0.9 info --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 9cc135f..4cfea14 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,9 @@ 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 1.0.9** (2017-06-07) + + Fixes a bug where binding to multiple elements with the same selector caused issues with `doubletap`. + + **Version 1.0.8** (2017-02-01) + Fixes a bug where certain instances of Chrome on touch devices did not correctly fire events. + Added license info to minified script. From b55a083d47121fa101de5dd502ffe418767d76ac Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 7 Jun 2017 09:55:46 +0100 Subject: [PATCH 112/149] Sync to 1.0.9 --- src/jquery.mobile-events.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/jquery.mobile-events.js b/src/jquery.mobile-events.js index 65fb4f6..6976761 100644 --- a/src/jquery.mobile-events.js +++ b/src/jquery.mobile-events.js @@ -289,6 +289,7 @@ if (e.which && e.which !== 1) { return false; } + $this.data('doubletapped', false); origTarget = e.target; $this.data('callee1', doubleTapFunc1); @@ -305,7 +306,9 @@ 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) }, 'time': Date.now(), - 'target': e.target + 'target': e.target, + 'element': e.originalEvent.srcElement, + 'index': $(e.target).index() }; } @@ -318,7 +321,7 @@ window.clearTimeout(action); $this.data('callee2', doubleTapFunc2); - if (delta < settings.doubletap_int && (e.target == origTarget) && delta > 100) { + if (delta < settings.doubletap_int && ($(e.target).index() == firstTap.index) && delta > 100) { $this.data('doubletapped', true); window.clearTimeout(settings.tap_timer); @@ -333,7 +336,9 @@ 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) }, 'time': Date.now(), - 'target': e.target + 'target': e.target, + 'element': e.originalEvent.srcElement, + 'index': $(e.target).index() }; var touchData = { From 2d049bad9fdef52a5a106ec14397cc614c94179f Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 7 Jun 2017 09:56:00 +0100 Subject: [PATCH 113/149] Sync to 1.0.9 --- src/jquery.mobile-events.min.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/jquery.mobile-events.min.js b/src/jquery.mobile-events.min.js index 81f4903..0269098 100644 --- a/src/jquery.mobile-events.min.js +++ b/src/jquery.mobile-events.min.js @@ -2,7 +2,7 @@ * jQuery Mobile Events * by Ben Major * - * Copyright 2011-2015, Ben Major + * Copyright 2011-2017, Ben Major * Licensed under the MIT License: * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -24,4 +24,5 @@ * THE SOFTWARE. * */ -"use strict";!function(a){function n(){var a=f();a!==g&&(g=a,d.trigger("orientationchange"))}function u(b,c,d,e){var f=d.type;d.type=c,a.event.dispatch.call(b,d,e),d.type=f}a.attrFn=a.attrFn||{};var b="ontouchstart"in window,c={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:b,orientation_support:"orientation"in window&&"onorientationchange"in window,startevent:b?"touchstart":"mousedown",endevent:b?"touchend":"mouseup",moveevent:b?"touchmove":"mousemove",tapevent:b?"tap":"click",scrollevent:b?"touchmove":"scroll",hold_timer:null,tap_timer:null};a.isTouchCapable=function(){return c.touch_capable},a.getStartEvent=function(){return c.startevent},a.getEndEvent=function(){return c.endevent},a.getMoveEvent=function(){return c.moveevent},a.getTapEvent=function(){return c.tapevent},a.getScrollEvent=function(){return c.scrollevent},a.each(["tapstart","tapend","tapmove","tap","tap2","tap3","tap4","singletap","doubletap","taphold","swipe","swipeup","swiperight","swipedown","swipeleft","swipeend","scrollstart","scrollend","orientationchange"],function(b,c){a.fn[c]=function(a){return a?this.on(c,a):this.trigger(c)},a.attrFn[c]=!0}),a.event.special.tapstart={setup:function(){var b=this,d=a(b);d.on(c.startevent,function a(e){if(d.data("callee",a),e.which&&1!==e.which)return!1;var f=e.originalEvent,g={position:{x:c.touch_capable?f.touches[0].screenX:e.screenX,y:c.touch_capable?f.touches[0].screenY:e.screenY},offset:{x:c.touch_capable?Math.round(f.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(e.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(f.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(e.pageY-(d.offset()?d.offset().top:0))},time:Date.now(),target:e.target};return u(b,"tapstart",e,g),!0})},remove:function(){a(this).off(c.startevent,a(this).data.callee)}},a.event.special.tapmove={setup:function(){var b=this,d=a(b);d.on(c.moveevent,function a(e){d.data("callee",a);var f=e.originalEvent,g={position:{x:c.touch_capable?f.touches[0].screenX:e.screenX,y:c.touch_capable?f.touches[0].screenY:e.screenY},offset:{x:c.touch_capable?Math.round(f.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(e.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(f.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(e.pageY-(d.offset()?d.offset().top:0))},time:Date.now(),target:e.target};return u(b,"tapmove",e,g),!0})},remove:function(){a(this).off(c.moveevent,a(this).data.callee)}},a.event.special.tapend={setup:function(){var b=this,d=a(b);d.on(c.endevent,function a(e){d.data("callee",a);var f=e.originalEvent,g={position:{x:c.touch_capable?f.changedTouches[0].screenX:e.screenX,y:c.touch_capable?f.changedTouches[0].screenY:e.screenY},offset:{x:c.touch_capable?Math.round(f.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(e.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(f.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(e.pageY-(d.offset()?d.offset().top:0))},time:Date.now(),target:e.target};return u(b,"tapend",e,g),!0})},remove:function(){a(this).off(c.endevent,a(this).data.callee)}},a.event.special.taphold={setup:function(){var e,b=this,d=a(b),f={x:0,y:0},g=0,h=0;d.on(c.startevent,function a(i){if(i.which&&1!==i.which)return!1;d.data("tapheld",!1),e=i.target;var j=i.originalEvent,k=Date.now(),l={x:c.touch_capable?j.touches[0].screenX:i.screenX,y:c.touch_capable?j.touches[0].screenY:i.screenY},m={x:c.touch_capable?j.touches[0].pageX-j.touches[0].target.offsetLeft:i.offsetX,y:c.touch_capable?j.touches[0].pageY-j.touches[0].target.offsetTop:i.offsetY};f.x=i.originalEvent.targetTouches?i.originalEvent.targetTouches[0].pageX:i.pageX,f.y=i.originalEvent.targetTouches?i.originalEvent.targetTouches[0].pageY:i.pageY,g=f.x,h=f.y;var n=d.parent().data("threshold")?d.parent().data("threshold"):d.data("threshold"),o="undefined"!=typeof n&&n!==!1&&parseInt(n)?parseInt(n):c.taphold_threshold;return c.hold_timer=window.setTimeout(function(){var n=f.x-g,o=f.y-h;if(i.target==e&&(f.x==g&&f.y==h||n>=-c.tap_pixel_range&&n<=c.tap_pixel_range&&o>=-c.tap_pixel_range&&o<=c.tap_pixel_range)){d.data("tapheld",!0);var p=Date.now(),q={x:c.touch_capable?j.touches[0].screenX:i.screenX,y:c.touch_capable?j.touches[0].screenY:i.screenY},r={x:c.touch_capable?Math.round(j.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(i.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(j.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(i.pageY-(d.offset()?d.offset().top:0))},s=p-k,t={startTime:k,endTime:p,startPosition:l,startOffset:m,endPosition:q,endOffset:r,duration:s,target:i.target};d.data("callee1",a),u(b,"taphold",i,t)}},o),!0}).on(c.endevent,function a(){d.data("callee2",a),d.data("tapheld",!1),window.clearTimeout(c.hold_timer)}).on(c.moveevent,function a(b){d.data("callee3",a),g=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageX:b.pageX,h=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageY:b.pageY})},remove:function(){a(this).off(c.startevent,a(this).data.callee1).off(c.endevent,a(this).data.callee2).off(c.moveevent,a(this).data.callee3)}},a.event.special.doubletap={setup:function(){var e,f,h,i,b=this,d=a(b),g=null,j=!1;d.on(c.startevent,function a(b){return(!b.which||1===b.which)&&(d.data("doubletapped",!1),e=b.target,d.data("callee1",a),h=b.originalEvent,g||(g={position:{x:c.touch_capable?h.touches[0].screenX:b.screenX,y:c.touch_capable?h.touches[0].screenY:b.screenY},offset:{x:c.touch_capable?Math.round(h.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(b.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(h.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(b.pageY-(d.offset()?d.offset().top:0))},time:Date.now(),target:b.target}),!0)}).on(c.endevent,function a(k){var l=Date.now(),m=d.data("lastTouch")||l+1,n=l-m;if(window.clearTimeout(f),d.data("callee2",a),n100){d.data("doubletapped",!0),window.clearTimeout(c.tap_timer);var o={position:{x:c.touch_capable?k.originalEvent.changedTouches[0].screenX:k.screenX,y:c.touch_capable?k.originalEvent.changedTouches[0].screenY:k.screenY},offset:{x:c.touch_capable?Math.round(h.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(k.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(h.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(k.pageY-(d.offset()?d.offset().top:0))},time:Date.now(),target:k.target},p={firstTap:g,secondTap:o,interval:o.time-g.time};j||(u(b,"doubletap",k,p),g=null),j=!0,i=window.setTimeout(function(){j=!1},c.doubletap_int)}else d.data("lastTouch",l),f=window.setTimeout(function(){g=null,window.clearTimeout(f)},c.doubletap_int,[k]);d.data("lastTouch",l)})},remove:function(){a(this).off(c.startevent,a(this).data.callee1).off(c.endevent,a(this).data.callee2)}},a.event.special.singletap={setup:function(){var b=this,d=a(b),e=null,f=null,g={x:0,y:0};d.on(c.startevent,function a(b){return(!b.which||1===b.which)&&(f=Date.now(),e=b.target,d.data("callee1",a),g.x=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageX:b.pageX,g.y=b.originalEvent.targetTouches?b.originalEvent.targetTouches[0].pageY:b.pageY,!0)}).on(c.endevent,function a(h){if(d.data("callee2",a),h.target==e){var i=h.originalEvent.changedTouches?h.originalEvent.changedTouches[0].pageX:h.pageX,j=h.originalEvent.changedTouches?h.originalEvent.changedTouches[0].pageY:h.pageY;c.tap_timer=window.setTimeout(function(){var a=g.x-i,e=g.y-j;if(!d.data("doubletapped")&&!d.data("tapheld")&&(g.x==i&&g.y==j||a>=-c.tap_pixel_range&&a<=c.tap_pixel_range&&e>=-c.tap_pixel_range&&e<=c.tap_pixel_range)){var k=h.originalEvent,l={position:{x:c.touch_capable?k.changedTouches[0].screenX:h.screenX,y:c.touch_capable?k.changedTouches[0].screenY:h.screenY},offset:{x:c.touch_capable?Math.round(k.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(h.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(k.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(h.pageY-(d.offset()?d.offset().top:0))},time:Date.now(),target:h.target};l.time-f=-c.tap_pixel_range&&m<=c.tap_pixel_range&&n>=-c.tap_pixel_range&&n<=c.tap_pixel_range)){for(var p=j.originalEvent,q=[],r=0;rh.y&&g.y-h.y>o&&(j="swipeup"),g.xn&&(j="swiperight"),g.yo&&(j="swipedown"),g.x>h.x&&g.x-h.x>n&&(j="swipeleft"),void 0!=j&&e){g.x=0,g.y=0,h.x=0,h.y=0,e=!1;var p=b.originalEvent,q={position:{x:c.touch_capable?p.touches[0].screenX:b.screenX,y:c.touch_capable?p.touches[0].screenY:b.screenY},offset:{x:c.touch_capable?Math.round(p.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(b.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(p.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(b.pageY-(d.offset()?d.offset().top:0))},time:Date.now(),target:b.target},r=Math.abs(i.position.x-q.position.x),s=Math.abs(i.position.y-q.position.y),t={startEvnt:i,endEvnt:q,direction:j.replace("swipe",""),xAmount:r,yAmount:s,duration:q.time-i.time};f=!0,d.trigger("swipe",t).trigger(j,t)}}function l(b){d=a(b.currentTarget);var g="";if(d.data("callee3",l),f){var h=d.data("xthreshold"),j=d.data("ythreshold"),k="undefined"!=typeof h&&h!==!1&&parseInt(h)?parseInt(h):c.swipe_h_threshold,m="undefined"!=typeof j&&j!==!1&&parseInt(j)?parseInt(j):c.swipe_v_threshold,n=b.originalEvent,o={position:{x:c.touch_capable?n.changedTouches[0].screenX:b.screenX,y:c.touch_capable?n.changedTouches[0].screenY:b.screenY},offset:{x:c.touch_capable?Math.round(n.changedTouches[0].pageX-(d.offset()?d.offset().left:0)):Math.round(b.pageX-(d.offset()?d.offset().left:0)),y:c.touch_capable?Math.round(n.changedTouches[0].pageY-(d.offset()?d.offset().top:0)):Math.round(b.pageY-(d.offset()?d.offset().top:0))},time:Date.now(),target:b.target};i.position.y>o.position.y&&i.position.y-o.position.y>m&&(g="swipeup"),i.position.xk&&(g="swiperight"),i.position.ym&&(g="swipedown"),i.position.x>o.position.x&&i.position.x-o.position.x>k&&(g="swipeleft");var p=Math.abs(i.position.x-o.position.x),q=Math.abs(i.position.y-o.position.y),r={startEvnt:i,endEvnt:o,direction:g.replace("swipe",""),xAmount:p,yAmount:q,duration:o.time-i.time};d.trigger("swipeend",r)}e=!1,f=!1}var i,b=this,d=a(b),e=!1,f=!1,g={x:0,y:0},h={x:0,y:0};d.on(c.startevent,j),d.on(c.moveevent,k),d.on(c.endevent,l)},remove:function(){a(this).off(c.startevent,a(this).data.callee1).off(c.moveevent,a(this).data.callee2).off(c.endevent,a(this).data.callee3)}},a.event.special.scrollstart={setup:function(){function g(a,c){e=c,u(b,e?"scrollstart":"scrollend",a)}var e,f,b=this,d=a(b);d.on(c.scrollevent,function a(b){d.data("callee",a),e||g(b,!0),clearTimeout(f),f=setTimeout(function(){g(b,!1)},50)})},remove:function(){a(this).off(c.scrollevent,a(this).data.callee)}};var e,f,g,h,i,d=a(window),j={0:!0,180:!0};if(c.orientation_support){var k=window.innerWidth||d.width(),l=window.innerHeight||d.height(),m=50;h=k>l&&k-l>m,i=j[window.orientation],(h&&i||!h&&!i)&&(j={"-90":!0,90:!0})}a.event.special.orientationchange=e={setup:function(){return!c.orientation_support&&(g=f(),d.on("throttledresize",n),!0)},teardown:function(){return!c.orientation_support&&(d.off("throttledresize",n),!0)},add:function(a){var b=a.handler;a.handler=function(a){return a.orientation=f(),b.apply(this,arguments)}}},a.event.special.orientationchange.orientation=f=function(){var a=!0,b=document.documentElement;return a=c.orientation_support?j[window.orientation]:b&&b.clientWidth/b.clientHeight<1.1,a?"portrait":"landscape"},a.event.special.throttledresize={setup:function(){a(this).on("resize",p)},teardown:function(){a(this).off("resize",p)}};var r,s,t,o=250,p=function(){s=Date.now(),t=s-q,t>=o?(q=s,a(this).trigger("throttledresize")):(r&&window.clearTimeout(r),r=window.setTimeout(n,o-t))},q=0;a.each({scrollend:"scrollstart",swipeup:"swipe",swiperight:"swipe",swipedown:"swipe",swipeleft:"swipe",swipeend:"swipe",tap2:"tap"},function(b,c){a.event.special[b]={setup:function(){a(this).on(c,a.noop)}}})}(jQuery); + +'use strict';(function(a){function b(){var x=j();x!==k&&(k=x,g.trigger('orientationchange'))}function c(x,y,z,A){var B=z.type;z.type=y,a.event.dispatch.call(x,z,A),z.type=B}a.attrFn=a.attrFn||{};var d='ontouchstart'in window,f={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:d,orientation_support:'orientation'in window&&'onorientationchange'in window,startevent:d?'touchstart':'mousedown',endevent:d?'touchend':'mouseup',moveevent:d?'touchmove':'mousemove',tapevent:d?'tap':'click',scrollevent:d?'touchmove':'scroll',hold_timer:null,tap_timer:null};a.isTouchCapable=function(){return f.touch_capable},a.getStartEvent=function(){return f.startevent},a.getEndEvent=function(){return f.endevent},a.getMoveEvent=function(){return f.moveevent},a.getTapEvent=function(){return f.tapevent},a.getScrollEvent=function(){return f.scrollevent},a.each(['tapstart','tapend','tapmove','tap','tap2','tap3','tap4','singletap','doubletap','taphold','swipe','swipeup','swiperight','swipedown','swipeleft','swipeend','scrollstart','scrollend','orientationchange'],function(x,y){a.fn[y]=function(z){return z?this.on(y,z):this.trigger(y)},a.attrFn[y]=!0}),a.event.special.tapstart={setup:function(){var x=this,y=a(x);y.on(f.startevent,function z(A){if(y.data('callee',z),A.which&&1!==A.which)return!1;var B=A.originalEvent,C={position:{x:f.touch_capable?B.touches[0].screenX:A.screenX,y:f.touch_capable?B.touches[0].screenY:A.screenY},offset:{x:f.touch_capable?Math.round(B.changedTouches[0].pageX-(y.offset()?y.offset().left:0)):Math.round(A.pageX-(y.offset()?y.offset().left:0)),y:f.touch_capable?Math.round(B.changedTouches[0].pageY-(y.offset()?y.offset().top:0)):Math.round(A.pageY-(y.offset()?y.offset().top:0))},time:Date.now(),target:A.target};return c(x,'tapstart',A,C),!0})},remove:function(){a(this).off(f.startevent,a(this).data.callee)}},a.event.special.tapmove={setup:function(){var x=this,y=a(x);y.on(f.moveevent,function z(A){y.data('callee',z);var B=A.originalEvent,C={position:{x:f.touch_capable?B.touches[0].screenX:A.screenX,y:f.touch_capable?B.touches[0].screenY:A.screenY},offset:{x:f.touch_capable?Math.round(B.changedTouches[0].pageX-(y.offset()?y.offset().left:0)):Math.round(A.pageX-(y.offset()?y.offset().left:0)),y:f.touch_capable?Math.round(B.changedTouches[0].pageY-(y.offset()?y.offset().top:0)):Math.round(A.pageY-(y.offset()?y.offset().top:0))},time:Date.now(),target:A.target};return c(x,'tapmove',A,C),!0})},remove:function(){a(this).off(f.moveevent,a(this).data.callee)}},a.event.special.tapend={setup:function(){var x=this,y=a(x);y.on(f.endevent,function z(A){y.data('callee',z);var B=A.originalEvent,C={position:{x:f.touch_capable?B.changedTouches[0].screenX:A.screenX,y:f.touch_capable?B.changedTouches[0].screenY:A.screenY},offset:{x:f.touch_capable?Math.round(B.changedTouches[0].pageX-(y.offset()?y.offset().left:0)):Math.round(A.pageX-(y.offset()?y.offset().left:0)),y:f.touch_capable?Math.round(B.changedTouches[0].pageY-(y.offset()?y.offset().top:0)):Math.round(A.pageY-(y.offset()?y.offset().top:0))},time:Date.now(),target:A.target};return c(x,'tapend',A,C),!0})},remove:function(){a(this).off(f.endevent,a(this).data.callee)}},a.event.special.taphold={setup:function(){var z,x=this,y=a(x),A={x:0,y:0},B=0,C=0;y.on(f.startevent,function D(E){if(E.which&&1!==E.which)return!1;y.data('tapheld',!1),z=E.target;var F=E.originalEvent,G=Date.now(),H={x:f.touch_capable?F.touches[0].screenX:E.screenX,y:f.touch_capable?F.touches[0].screenY:E.screenY},I={x:f.touch_capable?F.touches[0].pageX-F.touches[0].target.offsetLeft:E.offsetX,y:f.touch_capable?F.touches[0].pageY-F.touches[0].target.offsetTop:E.offsetY};A.x=E.originalEvent.targetTouches?E.originalEvent.targetTouches[0].pageX:E.pageX,A.y=E.originalEvent.targetTouches?E.originalEvent.targetTouches[0].pageY:E.pageY,B=A.x,C=A.y;var J=y.parent().data('threshold')?y.parent().data('threshold'):y.data('threshold'),K='undefined'!=typeof J&&!1!==J&&parseInt(J)?parseInt(J):f.taphold_threshold;return f.hold_timer=window.setTimeout(function(){var L=A.x-B,M=A.y-C;if(E.target==z&&(A.x==B&&A.y==C||L>=-f.tap_pixel_range&&L<=f.tap_pixel_range&&M>=-f.tap_pixel_range&&M<=f.tap_pixel_range)){y.data('tapheld',!0);var N=Date.now(),O={x:f.touch_capable?F.touches[0].screenX:E.screenX,y:f.touch_capable?F.touches[0].screenY:E.screenY},P={x:f.touch_capable?Math.round(F.changedTouches[0].pageX-(y.offset()?y.offset().left:0)):Math.round(E.pageX-(y.offset()?y.offset().left:0)),y:f.touch_capable?Math.round(F.changedTouches[0].pageY-(y.offset()?y.offset().top:0)):Math.round(E.pageY-(y.offset()?y.offset().top:0))},R={startTime:G,endTime:N,startPosition:H,startOffset:I,endPosition:O,endOffset:P,duration:N-G,target:E.target};y.data('callee1',D),c(x,'taphold',E,R)}},K),!0}).on(f.endevent,function D(){y.data('callee2',D),y.data('tapheld',!1),window.clearTimeout(f.hold_timer)}).on(f.moveevent,function D(E){y.data('callee3',D),B=E.originalEvent.targetTouches?E.originalEvent.targetTouches[0].pageX:E.pageX,C=E.originalEvent.targetTouches?E.originalEvent.targetTouches[0].pageY:E.pageY})},remove:function(){a(this).off(f.startevent,a(this).data.callee1).off(f.endevent,a(this).data.callee2).off(f.moveevent,a(this).data.callee3)}},a.event.special.doubletap={setup:function(){var z,A,C,D,x=this,y=a(x),B=null,E=!1;y.on(f.startevent,function F(G){return G.which&&1!==G.which?!1:(y.data('doubletapped',!1),z=G.target,y.data('callee1',F),C=G.originalEvent,B||(B={position:{x:f.touch_capable?C.touches[0].screenX:G.screenX,y:f.touch_capable?C.touches[0].screenY:G.screenY},offset:{x:f.touch_capable?Math.round(C.changedTouches[0].pageX-(y.offset()?y.offset().left:0)):Math.round(G.pageX-(y.offset()?y.offset().left:0)),y:f.touch_capable?Math.round(C.changedTouches[0].pageY-(y.offset()?y.offset().top:0)):Math.round(G.pageY-(y.offset()?y.offset().top:0))},time:Date.now(),target:G.target,element:G.originalEvent.srcElement,index:a(G.target).index()}),!0)}).on(f.endevent,function F(G){var H=Date.now(),I=y.data('lastTouch')||H+1,J=H-I;if(window.clearTimeout(A),y.data('callee2',F),J=-f.tap_pixel_range&&G<=f.tap_pixel_range&&H>=-f.tap_pixel_range&&H<=f.tap_pixel_range)){var I=D.originalEvent,J={position:{x:f.touch_capable?I.changedTouches[0].screenX:D.screenX,y:f.touch_capable?I.changedTouches[0].screenY:D.screenY},offset:{x:f.touch_capable?Math.round(I.changedTouches[0].pageX-(y.offset()?y.offset().left:0)):Math.round(D.pageX-(y.offset()?y.offset().left:0)),y:f.touch_capable?Math.round(I.changedTouches[0].pageY-(y.offset()?y.offset().top:0)):Math.round(D.pageY-(y.offset()?y.offset().top:0))},time:Date.now(),target:D.target};J.time-A=-f.tap_pixel_range&&I<=f.tap_pixel_range&&J>=-f.tap_pixel_range&&J<=f.tap_pixel_range)){for(var O,L=F.originalEvent,M=[],N=0;NF.y&&E.y-F.y>M&&(I='swipeup'),E.xL&&(I='swiperight'),E.yM&&(I='swipedown'),E.x>F.x&&E.x-F.x>L&&(I='swipeleft'),void 0!=I&&C){E.x=0,E.y=0,F.x=0,F.y=0,C=!1;var N=H.originalEvent,O={position:{x:f.touch_capable?N.touches[0].screenX:H.screenX,y:f.touch_capable?N.touches[0].screenY:H.screenY},offset:{x:f.touch_capable?Math.round(N.changedTouches[0].pageX-(B.offset()?B.offset().left:0)):Math.round(H.pageX-(B.offset()?B.offset().left:0)),y:f.touch_capable?Math.round(N.changedTouches[0].pageY-(B.offset()?B.offset().top:0)):Math.round(H.pageY-(B.offset()?B.offset().top:0))},time:Date.now(),target:H.target},P=Math.abs(G.position.x-O.position.x),Q=Math.abs(G.position.y-O.position.y),R={startEvnt:G,endEvnt:O,direction:I.replace('swipe',''),xAmount:P,yAmount:Q,duration:O.time-G.time};D=!0,B.trigger('swipe',R).trigger(I,R)}}function z(H){B=a(H.currentTarget);var I='';if(B.data('callee3',z),D){var J=B.data('xthreshold'),K=B.data('ythreshold'),L='undefined'!=typeof J&&!1!==J&&parseInt(J)?parseInt(J):f.swipe_h_threshold,M='undefined'!=typeof K&&!1!==K&&parseInt(K)?parseInt(K):f.swipe_v_threshold,N=H.originalEvent,O={position:{x:f.touch_capable?N.changedTouches[0].screenX:H.screenX,y:f.touch_capable?N.changedTouches[0].screenY:H.screenY},offset:{x:f.touch_capable?Math.round(N.changedTouches[0].pageX-(B.offset()?B.offset().left:0)):Math.round(H.pageX-(B.offset()?B.offset().left:0)),y:f.touch_capable?Math.round(N.changedTouches[0].pageY-(B.offset()?B.offset().top:0)):Math.round(H.pageY-(B.offset()?B.offset().top:0))},time:Date.now(),target:H.target};G.position.y>O.position.y&&G.position.y-O.position.y>M&&(I='swipeup'),G.position.xL&&(I='swiperight'),G.position.yM&&(I='swipedown'),G.position.x>O.position.x&&G.position.x-O.position.x>L&&(I='swipeleft');var P=Math.abs(G.position.x-O.position.x),Q=Math.abs(G.position.y-O.position.y),R={startEvnt:G,endEvnt:O,direction:I.replace('swipe',''),xAmount:P,yAmount:Q,duration:O.time-G.time};B.trigger('swipeend',R)}C=!1,D=!1}var G,A=this,B=a(A),C=!1,D=!1,E={x:0,y:0},F={x:0,y:0};B.on(f.startevent,x),B.on(f.moveevent,y),B.on(f.endevent,z)},remove:function(){a(this).off(f.startevent,a(this).data.callee1).off(f.moveevent,a(this).data.callee2).off(f.endevent,a(this).data.callee3)}},a.event.special.scrollstart={setup:function(){function x(C,D){A=D,c(y,A?'scrollstart':'scrollend',C)}var A,B,y=this,z=a(y);z.on(f.scrollevent,function C(D){z.data('callee',C),A||x(D,!0),clearTimeout(B),B=setTimeout(function(){x(D,!1)},50)})},remove:function(){a(this).off(f.scrollevent,a(this).data.callee)}};var h,j,k,l,m,g=a(window),n={0:!0,180:!0};if(f.orientation_support){var o=window.innerWidth||g.width(),p=window.innerHeight||g.height();l=o>p&&o-p>50,m=n[window.orientation],(l&&m||!l&&!m)&&(n={90:!0,'-90':!0})}a.event.special.orientationchange=h={setup:function(){return!f.orientation_support&&(k=j(),g.on('throttledresize',b),!0)},teardown:function(){return!f.orientation_support&&(g.off('throttledresize',b),!0)},add:function(x){var y=x.handler;x.handler=function(z){return z.orientation=j(),y.apply(this,arguments)}}},a.event.special.orientationchange.orientation=j=function(){var x=!0,y=document.documentElement;return x=f.orientation_support?n[window.orientation]:y&&1.1>y.clientWidth/y.clientHeight,x?'portrait':'landscape'},a.event.special.throttledresize={setup:function(){a(this).on('resize',s)},teardown:function(){a(this).off('resize',s)}};var u,v,w,r=250,s=function(){v=Date.now(),w=v-t,w>=r?(t=v,a(this).trigger('throttledresize')):(u&&window.clearTimeout(u),u=window.setTimeout(b,r-w))},t=0;a.each({scrollend:'scrollstart',swipeup:'swipe',swiperight:'swipe',swipedown:'swipe',swipeleft:'swipe',swipeend:'swipe',tap2:'tap'},function(x,y){a.event.special[x]={setup:function(){a(this).on(y,a.noop)}}})})(jQuery); From 8b6a8b157a9e3093dbf7f991131d8c56c4750e06 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 7 Jun 2017 09:59:16 +0100 Subject: [PATCH 114/149] Add 1.0.9 --- bower.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bower.json b/bower.json index 8a9e90f..8dc90b7 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jquery-touch-events", - "version": "1.0.8", + "version": "1.0.9", "main": "src/jquery.mobile-events.js", "ignore": [ "bower.json" From 9fc9063c96b87cfb15317f113ef711ac9706302b Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 7 Jun 2017 09:59:37 +0100 Subject: [PATCH 115/149] Add 1.0.9 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bd630c5..99e8e45 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jquery-touch-events", - "version": "1.0.8", + "version": "1.0.9", "description": "Polyfill to remove click delays on browsers with touch UIs.", "maintainers": [ { From 31f5e4780e870faf988d5a901277c6fc065e3f3a Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 7 Jun 2017 10:00:52 +0100 Subject: [PATCH 116/149] Added link to cdnjs --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4cfea14..7295feb 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,7 @@ After almost 2 years in public beta, I am pleased to announce that the library i jQuery Touch Events, as the name suggests, require only the jQuery library (version 1.7+) to run. You should download the latest release from the `src` folder, and include the Javascript file within your project, **after** jQuery has been included. It is recommended to also wrap your code inside the `DOMReady` callback function of jQuery (`$(function() { })`, for example). + **Manual installation:** Once you have downloaded the JS files from the master branch, you should include them using the following code: @@ -71,7 +72,7 @@ Once you have downloaded the JS files from the master branch, you should include ``` -The awesome guys over at cdnjs have kindly added the library to their CDN so you can include it as follows directly into your application: +The awesome guys over at [cdnjs](https://cdnjs.com/libraries/jquery-touch-events) have kindly added the library to their CDN so you can include it as follows directly into your application: ``` From 39ca4b5f77cbc4e8c2f9db6ac0a99a5625d57f1c Mon Sep 17 00:00:00 2001 From: Paul Date: Thu, 23 Nov 2017 19:01:52 +0100 Subject: [PATCH 117/149] Fix errors when internal events are triggered manually Triggering internally used event like mousemove manually would cause an error, because originalEvent property would be empty, closes #138. --- src/jquery.mobile-events.js | 62 +++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/src/jquery.mobile-events.js b/src/jquery.mobile-events.js index 6976761..13f60fa 100644 --- a/src/jquery.mobile-events.js +++ b/src/jquery.mobile-events.js @@ -82,8 +82,12 @@ $this = $(thisObject); $this.on(settings.startevent, function tapStartFunc(e) { - $this.data('callee', tapStartFunc); + + if (! e.originalEvent) { + return; + } + if (e.which && e.which !== 1) { return false; } @@ -120,7 +124,11 @@ $this.on(settings.moveevent, function tapMoveFunc(e) { $this.data('callee', tapMoveFunc); - + + if (! e.originalEvent) { + return; + } + var origEvent = e.originalEvent, touchData = { 'position': { @@ -154,6 +162,10 @@ // Touch event data: $this.data('callee', tapEndFunc); + if (! e.originalEvent) { + return; + } + var origEvent = e.originalEvent; var touchData = { 'position': { @@ -190,6 +202,10 @@ end_y = 0; $this.on(settings.startevent, function tapHoldFunc1(e) { + if (! e.originalEvent) { + return; + } + if (e.which && e.which !== 1) { return false; } else { @@ -262,6 +278,10 @@ }) .on(settings.moveevent, function tapHoldFunc3(e) { $this.data('callee3', tapHoldFunc3); + + if (! e.originalEvent) { + return; + } end_x = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageX : e.pageX; end_y = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageY : e.pageY; @@ -286,6 +306,10 @@ cooling = false; $this.on(settings.startevent, function doubleTapFunc1(e) { + if (! e.originalEvent) { + return; + } + if (e.which && e.which !== 1) { return false; } @@ -314,7 +338,10 @@ return true; }).on(settings.endevent, function doubleTapFunc2(e) { - + if (! e.originalEvent) { + return; + } + var now = Date.now(); var lastTouch = $this.data('lastTouch') || now + 1; var delta = now - lastTouch; @@ -387,6 +414,10 @@ }; $this.on(settings.startevent, function singleTapFunc1(e) { + if (! e.originalEvent) { + return; + } + if (e.which && e.which !== 1) { return false; } else { @@ -402,6 +433,11 @@ } }).on(settings.endevent, function singleTapFunc2(e) { $this.data('callee2', singleTapFunc2); + + if (! e.originalEvent) { + return; + } + if (e.target == origTarget) { // Get the end point: @@ -463,6 +499,10 @@ $this.on(settings.startevent, function tapFunc1(e) { $this.data('callee1', tapFunc1); + if (! e.originalEvent) { + return; + } + if( e.which && e.which !== 1 ) { return false; @@ -481,6 +521,10 @@ }).on(settings.endevent, function tapFunc2(e) { $this.data('callee2', tapFunc2); + if (! e.originalEvent) { + return; + } + // 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, @@ -540,6 +584,10 @@ // Screen touched, store the original coordinate function touchStart(e) { + if (! e.originalEvent) { + return; + } + $this = $(e.currentTarget); $this.data('callee1', touchStart); originalCoord.x = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageX : e.pageX; @@ -566,6 +614,10 @@ // Store coordinates as finger is swiping function touchMove(e) { + if (! e.originalEvent) { + return; + } + $this = $(e.currentTarget); $this.data('callee2', touchMove); finalCoord.x = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageX : e.pageX; @@ -631,6 +683,10 @@ } function touchEnd(e) { + if (! e.originalEvent) { + return; + } + $this = $(e.currentTarget); var swipedir = ""; $this.data('callee3', touchEnd); From 133b1b63baac294ca2b1be225fd5b37773734c90 Mon Sep 17 00:00:00 2001 From: Paul Date: Wed, 10 Jan 2018 13:42:55 +0100 Subject: [PATCH 118/149] Fix removing event handlers --- src/jquery.mobile-events.js | 171 ++++++++++++++++++++---------------- 1 file changed, 94 insertions(+), 77 deletions(-) diff --git a/src/jquery.mobile-events.js b/src/jquery.mobile-events.js index 13f60fa..77ff122 100644 --- a/src/jquery.mobile-events.js +++ b/src/jquery.mobile-events.js @@ -77,13 +77,11 @@ // tapstart Event: $.event.special.tapstart = { setup: function () { - + var thisObject = this, $this = $(thisObject); - - $this.on(settings.startevent, function tapStartFunc(e) { - $this.data('callee', tapStartFunc); - + + function tapStartFunc(e) { if (! e.originalEvent) { return; } @@ -105,26 +103,26 @@ 'time': Date.now(), 'target': e.target }; - + triggerCustomEvent(thisObject, 'tapstart', e, touchData); return true; - }); + }; + + $this.on(settings.startevent, $this.data.tapStartFunc = tapStartFunc); }, remove: function () { - $(this).off(settings.startevent, $(this).data.callee); + $(this).off(settings.startevent, $(this).data.tapStartFunc); } }; - + // tapmove Event: $.event.special.tapmove = { - setup: function() { + setup: function() { var thisObject = this, $this = $(thisObject); - - $this.on(settings.moveevent, function tapMoveFunc(e) { - $this.data('callee', tapMoveFunc); + function tapMoveFunc(e) { if (! e.originalEvent) { return; } @@ -137,18 +135,20 @@ }, 'offset': { 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) }, 'time': Date.now(), 'target': e.target }; - + triggerCustomEvent(thisObject, 'tapmove', e, touchData); return true; - }); + } + + $this.on(settings.moveevent, $this.data.tapMoveFunc = tapMoveFunc); }, remove: function() { - $(this).off(settings.moveevent, $(this).data.callee); + $(this).off(settings.moveevent, $(this).data.tapMoveFunc); } }; @@ -158,10 +158,7 @@ var thisObject = this, $this = $(thisObject); - $this.on(settings.endevent, function tapEndFunc(e) { - // Touch event data: - $this.data('callee', tapEndFunc); - + function tapEndFunc(e) { if (! e.originalEvent) { return; } @@ -181,10 +178,12 @@ }; triggerCustomEvent(thisObject, 'tapend', e, touchData); return true; - }); + } + + $this.on(settings.endevent, $this.data.tapEndFunc = tapEndFunc); }, remove: function () { - $(this).off(settings.endevent, $(this).data.callee); + $(this).off(settings.endevent, $(this).data.tapEndFunc); } }; @@ -201,7 +200,7 @@ end_x = 0, end_y = 0; - $this.on(settings.startevent, function tapHoldFunc1(e) { + function tapHoldFunc1(e) { if (! e.originalEvent) { return; } @@ -249,7 +248,7 @@ }, endOffset = { 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) }; var duration = end_time - start_time; @@ -264,32 +263,37 @@ 'duration': duration, 'target': e.target }; - $this.data('callee1', tapHoldFunc1); triggerCustomEvent(thisObject, 'taphold', e, touchData); } }, threshold); return true; } - }).on(settings.endevent, function tapHoldFunc2() { - $this.data('callee2', tapHoldFunc2); + } + + function tapHoldFunc2() { $this.data('tapheld', false); window.clearTimeout(settings.hold_timer); - }) - .on(settings.moveevent, function tapHoldFunc3(e) { - $this.data('callee3', tapHoldFunc3); + } + function tapHoldFunc3(e) { if (! e.originalEvent) { return; } - + end_x = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageX : e.pageX; end_y = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageY : e.pageY; - }); + } + + $this.on(settings.startevent, $this.data.tapHoldFunc1 = tapHoldFunc1) + .on(settings.endevent, $this.data.tapHoldFunc2 = tapHoldFunc2) + .on(settings.moveevent, $this.data.tapHoldFunc3 = tapHoldFunc3); }, remove: function () { - $(this).off(settings.startevent, $(this).data.callee1).off(settings.endevent, $(this).data.callee2).off(settings.moveevent, $(this).data.callee3); + $(this).off(settings.startevent, $(this).data.tapHoldFunc1) + .off(settings.endevent, $(this).data.tapHoldFunc2) + .off(settings.moveevent, $(this).data.tapHoldFunc3); } }; @@ -305,7 +309,7 @@ cooloff, cooling = false; - $this.on(settings.startevent, function doubleTapFunc1(e) { + function doubleTapFunc1(e) { if (! e.originalEvent) { return; } @@ -316,7 +320,6 @@ $this.data('doubletapped', false); origTarget = e.target; - $this.data('callee1', doubleTapFunc1); origEvent = e.originalEvent; if (!firstTap) { @@ -337,7 +340,9 @@ } return true; - }).on(settings.endevent, function doubleTapFunc2(e) { + } + + function doubleTapFunc2(e) { if (! e.originalEvent) { return; } @@ -346,7 +351,6 @@ 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); @@ -375,16 +379,16 @@ }; if (!cooling) { - triggerCustomEvent(thisObject, 'doubletap', e, touchData); + triggerCustomEvent(thisObject, 'doubletap', e, touchData); firstTap = null; } cooling = true; cooloff = window.setTimeout(function () { - cooling = false; + cooling = false; }, settings.doubletap_int); - + } else { $this.data('lastTouch', now); action = window.setTimeout(function () { @@ -393,10 +397,14 @@ }, settings.doubletap_int, [e]); } $this.data('lastTouch', now); - }); + } + + $this.on(settings.startevent, $this.data.doubleTapFunc1 = doubleTapFunc1) + .on(settings.endevent, $this.data.doubleTapFunc2 = doubleTapFunc2); }, remove: function () { - $(this).off(settings.startevent, $(this).data.callee1).off(settings.endevent, $(this).data.callee2); + $(this).off(settings.startevent, $(this).data.doubleTapFunc1) + .off(settings.endevent, $(this).data.doubleTapFunc2); } }; @@ -413,7 +421,7 @@ y: 0 }; - $this.on(settings.startevent, function singleTapFunc1(e) { + function singleTapFunc1(e) { if (! e.originalEvent) { return; } @@ -423,7 +431,6 @@ } 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; @@ -431,9 +438,9 @@ return true; } - }).on(settings.endevent, function singleTapFunc2(e) { - $this.data('callee2', singleTapFunc2); + } + function singleTapFunc2(e) { if (! e.originalEvent) { return; } @@ -460,7 +467,7 @@ }, 'offset': { 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) }, 'time': Date.now(), 'target': e.target @@ -474,11 +481,15 @@ } }, settings.doubletap_int); } - }); + } + + $this.on(settings.startevent, $this.data.singleTapFunc1 = singleTapFunc1) + .on(settings.endevent, $this.data.singleTapFunc2 = singleTapFunc2); }, remove: function () { - $(this).off(settings.startevent, $(this).data.callee1).off(settings.endevent, $(this).data.callee2); + $(this).off(settings.startevent, $(this).data.singleTapFunc1) + .off(settings.endevent, $(this).data.singleTapFunc2); } }; @@ -496,31 +507,29 @@ }, touches; - $this.on(settings.startevent, function tapFunc1(e) { - $this.data('callee1', tapFunc1); - + function tapFunc1(e) { if (! e.originalEvent) { return; } if( e.which && e.which !== 1 ) - { + { return false; } - else - { + 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); + } + function tapFunc2(e) { if (! e.originalEvent) { return; } @@ -531,11 +540,11 @@ 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 origEvent = e.originalEvent; var touchData = [ ]; - + for( var i = 0; i < touches.length; i++) { var touch = { @@ -550,17 +559,21 @@ 'time': Date.now(), 'target': e.target }; - + touchData.push( touch ); } triggerCustomEvent(thisObject, 'tap', e, touchData); } - }); + } + + $this.on(settings.startevent, $this.data.tapFunc1 = tapFunc1) + .on(settings.endevent, $this.data.tapFunc2 = tapFunc2); }, remove: function () { - $(this).off(settings.startevent, $(this).data.callee1).off(settings.endevent, $(this).data.callee2); + $(this).off(settings.startevent, $(this).data.tapFunc1) + .off(settings.endevent, $(this).data.tapFunc2); } }; @@ -589,7 +602,6 @@ } $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; @@ -619,7 +631,6 @@ } $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; @@ -689,7 +700,6 @@ $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'), @@ -744,13 +754,15 @@ hasSwiped = false; } - $this.on(settings.startevent, touchStart); - $this.on(settings.moveevent, touchMove); - $this.on(settings.endevent, touchEnd); + $this.on(settings.startevent, $this.data.touchStart = touchStart); + $this.on(settings.moveevent, $this.data.touchMove = touchMove); + $this.on(settings.endevent, $this.data.touchEnd = touchEnd); }, remove: function () { - $(this).off(settings.startevent, $(this).data.callee1).off(settings.moveevent, $(this).data.callee2).off(settings.endevent, $(this).data.callee3); + $(this).off(settings.startevent, $(this).data.touchStart) + .off(settings.moveevent, $(this).data.touchMove) + .off(settings.endevent, $(this).data.touchEnd); } }; @@ -768,9 +780,7 @@ } // iPhone triggers scroll after a small delay; use touchmove instead - $this.on(settings.scrollevent, function scrollFunc(event) { - $this.data('callee', scrollFunc); - + function scrollFunc(event) { if (!scrolling) { trigger(event, true); } @@ -779,11 +789,13 @@ timer = setTimeout(function () { trigger(event, false); }, 50); - }); + } + + $this.on(settings.scrollevent, $this.data.scrollFunc = scrollFunc); }, remove: function () { - $(this).off(settings.scrollevent, $(this).data.callee); + $(this).off(settings.scrollevent, $(this).data.scrollFunc); } }; @@ -928,9 +940,14 @@ swipeend: 'swipe', tap2: 'tap' }, function (e, srcE) { + var emptyFunc = function () {}; + $.event.special[e] = { setup: function () { - $(this).on(srcE, $.noop); + $(this).on(srcE, emptyFunc); + }, + teardown: function () { + $(this).off(srcE, emptyFunc); } }; }); From 6381080fcb0e4edf4682aa09ac6c581ac7a28ea4 Mon Sep 17 00:00:00 2001 From: Paul Date: Wed, 10 Jan 2018 14:35:14 +0100 Subject: [PATCH 119/149] Trim lines --- src/jquery.mobile-events.js | 64 ++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/jquery.mobile-events.js b/src/jquery.mobile-events.js index 77ff122..003ebd2 100644 --- a/src/jquery.mobile-events.js +++ b/src/jquery.mobile-events.js @@ -4,7 +4,7 @@ * * Copyright 2011-2017, 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 @@ -22,7 +22,7 @@ * 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"; @@ -36,7 +36,7 @@ // purports support for touch events even if the underlying hardware // does not! var touchCapable = ('ontouchstart' in window), - + settings = { tap_pixel_range: 5, swipe_h_threshold: 50, @@ -56,7 +56,7 @@ hold_timer: null, tap_timer: null }; - + // Convenience functions: $.isTouchCapable = function() { return settings.touch_capable; }; $.getStartEvent = function() { return settings.startevent; }; @@ -64,7 +64,7 @@ $.getMoveEvent = function() { return settings.moveevent; }; $.getTapEvent = function() { return settings.tapevent; }; $.getScrollEvent = function() { return settings.scrollevent; }; - + // Add Event shortcuts: $.each(['tapstart', 'tapend', 'tapmove', 'tap', 'tap2', 'tap3', 'tap4', 'singletap', 'doubletap', 'taphold', 'swipe', 'swipeup', 'swiperight', 'swipedown', 'swipeleft', 'swipeend', 'scrollstart', 'scrollend', 'orientationchange'], function (i, name) { $.fn[name] = function (fn) { @@ -77,10 +77,10 @@ // tapstart Event: $.event.special.tapstart = { setup: function () { - + var thisObject = this, $this = $(thisObject); - + function tapStartFunc(e) { if (! e.originalEvent) { return; @@ -103,7 +103,7 @@ 'time': Date.now(), 'target': e.target }; - + triggerCustomEvent(thisObject, 'tapstart', e, touchData); return true; }; @@ -115,7 +115,7 @@ $(this).off(settings.startevent, $(this).data.tapStartFunc); } }; - + // tapmove Event: $.event.special.tapmove = { setup: function() { @@ -140,11 +140,11 @@ 'time': Date.now(), 'target': e.target }; - + triggerCustomEvent(thisObject, 'tapmove', e, touchData); return true; } - + $this.on(settings.moveevent, $this.data.tapMoveFunc = tapMoveFunc); }, remove: function() { @@ -227,11 +227,11 @@ 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; + threshold = (typeof ele_threshold !== 'undefined' && ele_threshold !== false && parseInt(ele_threshold)) ? parseInt(ele_threshold) : settings.taphold_threshold; settings.hold_timer = window.setTimeout(function () { @@ -280,7 +280,7 @@ if (! e.originalEvent) { return; } - + end_x = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageX : e.pageX; end_y = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageY : e.pageY; } @@ -317,7 +317,7 @@ if (e.which && e.which !== 1) { return false; } - + $this.data('doubletapped', false); origTarget = e.target; @@ -382,13 +382,13 @@ 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 () { @@ -435,7 +435,7 @@ // 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; } } @@ -446,17 +446,17 @@ } 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 origEvent = e.originalEvent; @@ -472,7 +472,7 @@ 'time': Date.now(), 'target': e.target }; - + // Was it a taphold? if((touchData.time - startTime) < settings.taphold_threshold) { @@ -523,7 +523,7 @@ 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; } @@ -540,11 +540,11 @@ 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 origEvent = e.originalEvent; var touchData = [ ]; - + for( var i = 0; i < touches.length; i++) { var touch = { @@ -559,10 +559,10 @@ 'time': Date.now(), 'target': e.target }; - + touchData.push( touch ); } - + triggerCustomEvent(thisObject, 'tap', e, touchData); } } @@ -640,8 +640,8 @@ 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; - + 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'; } From 1289de464625d00dac4bd3b5c7a3909155d66353 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Sun, 20 May 2018 14:01:43 +0100 Subject: [PATCH 120/149] Create jquery.mobile-events.js --- src/2.0.0/jquery.mobile-events.js | 920 ++++++++++++++++++++++++++++++ 1 file changed, 920 insertions(+) create mode 100644 src/2.0.0/jquery.mobile-events.js diff --git a/src/2.0.0/jquery.mobile-events.js b/src/2.0.0/jquery.mobile-events.js new file mode 100644 index 0000000..d0bcca8 --- /dev/null +++ b/src/2.0.0/jquery.mobile-events.js @@ -0,0 +1,920 @@ +/*! + * jQuery Mobile Events + * by Ben Major + * + * Copyright 2011-2017, 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 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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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; + + settings.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 = [ ]; + + 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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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(settings.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) { + 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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 (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 (originalCoord.x > finalCoord.x && (originalCoord.x - finalCoord.x > h_threshold)) { + swipedir = 'swipeleft'; + } + 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 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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + 'time': Date.now(), + '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); + + 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)); From 8cbaed748d61da88d367a7e19ed08f4b7707c300 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Sun, 20 May 2018 14:02:01 +0100 Subject: [PATCH 121/149] Sync to 2.0.0 --- src/jquery.mobile-events.js | 411 +++++++++++++++++------------------- 1 file changed, 188 insertions(+), 223 deletions(-) diff --git a/src/jquery.mobile-events.js b/src/jquery.mobile-events.js index 003ebd2..d0bcca8 100644 --- a/src/jquery.mobile-events.js +++ b/src/jquery.mobile-events.js @@ -4,7 +4,7 @@ * * Copyright 2011-2017, 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 @@ -22,7 +22,7 @@ * 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"; @@ -30,19 +30,15 @@ (function ($) { $.attrFn = $.attrFn || {}; - // navigator.userAgent.toLowerCase() isn't reliable for Chrome installs - // on mobile devices. As such, we will create a boolean isChromeDesktop - // The reason that we need to do this is because Chrome annoyingly - // purports support for touch events even if the underlying hardware - // does not! - var touchCapable = ('ontouchstart' in window), - + 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), @@ -56,7 +52,10 @@ hold_timer: null, tap_timer: null }; - + + // Declare touch namespace: + $.touch = { }; + // Convenience functions: $.isTouchCapable = function() { return settings.touch_capable; }; $.getStartEvent = function() { return settings.startevent; }; @@ -64,9 +63,40 @@ $.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', 'tap2', 'tap3', 'tap4', 'singletap', 'doubletap', 'taphold', 'swipe', 'swipeup', 'swiperight', 'swipedown', 'swipeleft', 'swipeend', 'scrollstart', 'scrollend', 'orientationchange'], function (i, name) { + $.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); }; @@ -77,15 +107,13 @@ // tapstart Event: $.event.special.tapstart = { setup: function () { - + var thisObject = this, $this = $(thisObject); - - function tapStartFunc(e) { - if (! e.originalEvent) { - return; - } - + + $this.on(settings.startevent, function tapStartFunc(e) { + + $this.data('callee', tapStartFunc); if (e.which && e.which !== 1) { return false; } @@ -93,8 +121,8 @@ var origEvent = e.originalEvent, touchData = { 'position': { - 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), - 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + '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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), @@ -103,52 +131,46 @@ 'time': Date.now(), 'target': e.target }; - + triggerCustomEvent(thisObject, 'tapstart', e, touchData); return true; - }; - - $this.on(settings.startevent, $this.data.tapStartFunc = tapStartFunc); + }); }, remove: function () { - $(this).off(settings.startevent, $(this).data.tapStartFunc); + $(this).off(settings.startevent, $(this).data.callee); } }; - + // tapmove Event: $.event.special.tapmove = { - setup: function() { + setup: function() { var thisObject = this, $this = $(thisObject); - - function tapMoveFunc(e) { - if (! e.originalEvent) { - return; - } - + + $this.on(settings.moveevent, function tapMoveFunc(e) { + $this.data('callee', tapMoveFunc); + var origEvent = e.originalEvent, touchData = { 'position': { - 'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX), - 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + '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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) }, 'time': Date.now(), 'target': e.target }; - + triggerCustomEvent(thisObject, 'tapmove', e, touchData); return true; - } - - $this.on(settings.moveevent, $this.data.tapMoveFunc = tapMoveFunc); + }); }, remove: function() { - $(this).off(settings.moveevent, $(this).data.tapMoveFunc); + $(this).off(settings.moveevent, $(this).data.callee); } }; @@ -158,16 +180,15 @@ var thisObject = this, $this = $(thisObject); - function tapEndFunc(e) { - if (! e.originalEvent) { - return; - } + $this.on(settings.endevent, function tapEndFunc(e) { + // Touch event data: + $this.data('callee', tapEndFunc); var origEvent = e.originalEvent; var touchData = { 'position': { - 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + '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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), @@ -178,12 +199,10 @@ }; triggerCustomEvent(thisObject, 'tapend', e, touchData); return true; - } - - $this.on(settings.endevent, $this.data.tapEndFunc = tapEndFunc); + }); }, remove: function () { - $(this).off(settings.endevent, $(this).data.tapEndFunc); + $(this).off(settings.endevent, $(this).data.callee); } }; @@ -200,11 +219,7 @@ end_x = 0, end_y = 0; - function tapHoldFunc1(e) { - if (! e.originalEvent) { - return; - } - + $this.on(settings.startevent, function tapHoldFunc1(e) { if (e.which && e.which !== 1) { return false; } else { @@ -214,8 +229,8 @@ var origEvent = e.originalEvent; var start_time = Date.now(), startPosition = { - 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + '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, @@ -227,11 +242,10 @@ 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; + threshold = (typeof ele_threshold !== 'undefined' && ele_threshold !== false && parseInt(ele_threshold)) ? parseInt(ele_threshold) : settings.taphold_threshold; settings.hold_timer = window.setTimeout(function () { @@ -241,59 +255,56 @@ 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(), - endPosition = { - 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY - }, - endOffset = { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) - }; - var duration = end_time - start_time; - - // Build the touch data: - var touchData = { - 'startTime': start_time, - 'endTime': end_time, - 'startPosition': startPosition, - 'startOffset': startOffset, - 'endPosition': endPosition, - 'endOffset': endOffset, - 'duration': duration, - 'target': e.target - }; - triggerCustomEvent(thisObject, 'taphold', e, touchData); + var end_time = Date.now(); + + var duration = end_time - start_time, + touches = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches : [ e ], + 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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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; } - } - - function tapHoldFunc2() { + }).on(settings.endevent, function tapHoldFunc2() { + $this.data('callee2', tapHoldFunc2); $this.data('tapheld', false); window.clearTimeout(settings.hold_timer); - } - - function tapHoldFunc3(e) { - if (! e.originalEvent) { - return; - } - + }) + .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; - } - - $this.on(settings.startevent, $this.data.tapHoldFunc1 = tapHoldFunc1) - .on(settings.endevent, $this.data.tapHoldFunc2 = tapHoldFunc2) - .on(settings.moveevent, $this.data.tapHoldFunc3 = tapHoldFunc3); + }); }, remove: function () { - $(this).off(settings.startevent, $(this).data.tapHoldFunc1) - .off(settings.endevent, $(this).data.tapHoldFunc2) - .off(settings.moveevent, $(this).data.tapHoldFunc3); + $(this).off(settings.startevent, $(this).data.callee1).off(settings.endevent, $(this).data.callee2).off(settings.moveevent, $(this).data.callee3); } }; @@ -309,24 +320,21 @@ cooloff, cooling = false; - function doubleTapFunc1(e) { - if (! e.originalEvent) { - return; - } - + $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) { firstTap = { 'position': { - 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + '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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), @@ -340,17 +348,13 @@ } return true; - } - - function doubleTapFunc2(e) { - if (! e.originalEvent) { - return; - } - + }).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); @@ -359,8 +363,8 @@ // Now get the current event: var lastTap = { 'position': { - 'x': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenX : e.screenX, - 'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenY : e.screenY + '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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), @@ -379,16 +383,16 @@ }; if (!cooling) { - triggerCustomEvent(thisObject, 'doubletap', e, touchData); + triggerCustomEvent(thisObject, 'doubletap', e, touchData); firstTap = null; } - + cooling = true; - + cooloff = window.setTimeout(function () { - cooling = false; + cooling = false; }, settings.doubletap_int); - + } else { $this.data('lastTouch', now); action = window.setTimeout(function () { @@ -397,14 +401,10 @@ }, settings.doubletap_int, [e]); } $this.data('lastTouch', now); - } - - $this.on(settings.startevent, $this.data.doubleTapFunc1 = doubleTapFunc1) - .on(settings.endevent, $this.data.doubleTapFunc2 = doubleTapFunc2); + }); }, remove: function () { - $(this).off(settings.startevent, $(this).data.doubleTapFunc1) - .off(settings.endevent, $(this).data.doubleTapFunc2); + $(this).off(settings.startevent, $(this).data.callee1).off(settings.endevent, $(this).data.callee2); } }; @@ -421,58 +421,50 @@ y: 0 }; - function singleTapFunc1(e) { - if (! e.originalEvent) { - return; - } - + $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; } - } - - function singleTapFunc2(e) { - if (! e.originalEvent) { - return; - } - + }).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 origEvent = e.originalEvent; var touchData = { 'position': { - 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + '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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) }, 'time': Date.now(), 'target': e.target }; - + // Was it a taphold? if((touchData.time - startTime) < settings.taphold_threshold) { @@ -481,15 +473,11 @@ } }, settings.doubletap_int); } - } - - $this.on(settings.startevent, $this.data.singleTapFunc1 = singleTapFunc1) - .on(settings.endevent, $this.data.singleTapFunc2 = singleTapFunc2); + }); }, remove: function () { - $(this).off(settings.startevent, $(this).data.singleTapFunc1) - .off(settings.endevent, $(this).data.singleTapFunc2); + $(this).off(settings.startevent, $(this).data.callee1).off(settings.endevent, $(this).data.callee2); } }; @@ -507,32 +495,26 @@ }, touches; - function tapFunc1(e) { - if (! e.originalEvent) { - return; - } + $this.on(settings.startevent, function tapFunc1(e) { + $this.data('callee1', tapFunc1); if( e.which && e.which !== 1 ) - { + { return false; } - else - { + 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; } - } - - function tapFunc2(e) { - if (! e.originalEvent) { - return; - } + }).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, @@ -540,17 +522,17 @@ 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 origEvent = e.originalEvent; var touchData = [ ]; - + for( var i = 0; i < touches.length; i++) { var touch = { 'position': { - 'x': (settings.touch_capable) ? origEvent.changedTouches[i].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.changedTouches[i].screenY : e.screenY + '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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), @@ -559,21 +541,19 @@ 'time': Date.now(), 'target': e.target }; - + touchData.push( touch ); } - - triggerCustomEvent(thisObject, 'tap', e, touchData); + + var evt_name = ( touches.length == 2 ) ? 'tap2' : 'tap'; + + triggerCustomEvent(thisObject, evt_name, e, touchData); } - } - - $this.on(settings.startevent, $this.data.tapFunc1 = tapFunc1) - .on(settings.endevent, $this.data.tapFunc2 = tapFunc2); + }); }, remove: function () { - $(this).off(settings.startevent, $(this).data.tapFunc1) - .off(settings.endevent, $(this).data.tapFunc2); + $(this).off(settings.startevent, $(this).data.callee1).off(settings.endevent, $(this).data.callee2); } }; @@ -597,11 +577,8 @@ // Screen touched, store the original coordinate function touchStart(e) { - if (! e.originalEvent) { - return; - } - $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; @@ -611,8 +588,8 @@ // Read event data into our startEvt: startEvnt = { 'position': { - 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + '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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), @@ -626,11 +603,8 @@ // Store coordinates as finger is swiping function touchMove(e) { - if (! e.originalEvent) { - return; - } - $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; @@ -640,8 +614,8 @@ 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; - + 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'; } @@ -665,8 +639,8 @@ var origEvent = e.originalEvent; var endEvnt = { 'position': { - 'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY + '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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), @@ -694,12 +668,9 @@ } function touchEnd(e) { - if (! e.originalEvent) { - return; - } - $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'), @@ -710,8 +681,8 @@ var origEvent = e.originalEvent; var endEvnt = { 'position': { - 'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX, - 'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY + '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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), @@ -754,15 +725,13 @@ hasSwiped = false; } - $this.on(settings.startevent, $this.data.touchStart = touchStart); - $this.on(settings.moveevent, $this.data.touchMove = touchMove); - $this.on(settings.endevent, $this.data.touchEnd = touchEnd); + $this.on(settings.startevent, touchStart); + $this.on(settings.moveevent, touchMove); + $this.on(settings.endevent, touchEnd); }, remove: function () { - $(this).off(settings.startevent, $(this).data.touchStart) - .off(settings.moveevent, $(this).data.touchMove) - .off(settings.endevent, $(this).data.touchEnd); + $(this).off(settings.startevent, $(this).data.callee1).off(settings.moveevent, $(this).data.callee2).off(settings.endevent, $(this).data.callee3); } }; @@ -780,7 +749,9 @@ } // iPhone triggers scroll after a small delay; use touchmove instead - function scrollFunc(event) { + $this.on(settings.scrollevent, function scrollFunc(event) { + $this.data('callee', scrollFunc); + if (!scrolling) { trigger(event, true); } @@ -789,13 +760,11 @@ timer = setTimeout(function () { trigger(event, false); }, 50); - } - - $this.on(settings.scrollevent, $this.data.scrollFunc = scrollFunc); + }); }, remove: function () { - $(this).off(settings.scrollevent, $(this).data.scrollFunc); + $(this).off(settings.scrollevent, $(this).data.callee); } }; @@ -938,16 +907,12 @@ swipedown: 'swipe', swipeleft: 'swipe', swipeend: 'swipe', - tap2: 'tap' + tap2: 'tap', + taphold2: 'taphold' }, function (e, srcE) { - var emptyFunc = function () {}; - $.event.special[e] = { setup: function () { - $(this).on(srcE, emptyFunc); - }, - teardown: function () { - $(this).off(srcE, emptyFunc); + $(this).on(srcE, $.noop); } }; }); From e56462b576940d415d2c3e5a6621834ae58d8ed9 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Sun, 20 May 2018 14:02:51 +0100 Subject: [PATCH 122/149] Create jquery.mobile-events.min.js --- src/2.0.0/jquery.mobile-events.min.js | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/2.0.0/jquery.mobile-events.min.js diff --git a/src/2.0.0/jquery.mobile-events.min.js b/src/2.0.0/jquery.mobile-events.min.js new file mode 100644 index 0000000..36a20fb --- /dev/null +++ b/src/2.0.0/jquery.mobile-events.min.js @@ -0,0 +1,28 @@ +/*! + * jQuery Mobile Events + * by Ben Major + * + * Copyright 2011-2017, 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=n.originalEvent,r={position:{x:a.touch_capable?i.touches[0].pageX:n.pageX,y:a.touch_capable?i.touches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(i.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(n.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(i.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(n.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:n.target};return w(t,"tapstart",n,r),!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=n.originalEvent,r={position:{x:a.touch_capable?i.touches[0].pageX:n.pageX,y:a.touch_capable?i.touches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(i.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(n.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(i.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(n.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:n.target};return w(t,"tapmove",n,r),!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=n.originalEvent,r={position:{x:a.touch_capable?i.changedTouches[0].pageX:n.pageX,y:a.touch_capable?i.changedTouches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(i.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(n.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(i.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(n.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:n.target};return w(t,"tapend",n,r),!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,s=0;n.on(a.startevent,function e(p){if(p.which&&1!==p.which)return!1;n.data("tapheld",!1),t=p.target;var h=p.originalEvent,c=Date.now();a.touch_capable?h.touches[0].pageX:p.pageX,a.touch_capable?h.touches[0].pageY:p.pageY,a.touch_capable?(h.touches[0].pageX,h.touches[0].target.offsetLeft):p.offsetX,a.touch_capable?(h.touches[0].pageY,h.touches[0].target.offsetTop):p.offsetY;i.x=p.originalEvent.targetTouches?p.originalEvent.targetTouches[0].pageX:p.pageX,i.y=p.originalEvent.targetTouches?p.originalEvent.targetTouches[0].pageY:p.pageY,r=i.x,s=i.y;var u=n.parent().data("threshold")?n.parent().data("threshold"):n.data("threshold"),f=void 0!==u&&!1!==u&&parseInt(u)?parseInt(u):a.taphold_threshold;return a.hold_timer=window.setTimeout(function(){var u=i.x-r,f=i.y-s;if(p.target==t&&(i.x==r&&i.y==s||u>=-a.tap_pixel_range&&u<=a.tap_pixel_range&&f>=-a.tap_pixel_range&&f<=a.tap_pixel_range)){n.data("tapheld",!0);for(var l=Date.now()-c,g=p.originalEvent.targetTouches?p.originalEvent.targetTouches:[p],d=[],v=0;v100){i.data("doubletapped",!0),window.clearTimeout(a.tap_timer);var f={position:{x:a.touch_capable?h.originalEvent.changedTouches[0].pageX:h.pageX,y:a.touch_capable?h.originalEvent.changedTouches[0].pageY:h.pageY},offset:{x:a.touch_capable?Math.round(o.changedTouches[0].pageX-(i.offset()?i.offset().left:0)):Math.round(h.pageX-(i.offset()?i.offset().left:0)),y:a.touch_capable?Math.round(o.changedTouches[0].pageY-(i.offset()?i.offset().top:0)):Math.round(h.pageY-(i.offset()?i.offset().top:0))},time:Date.now(),target:h.target,element:h.originalEvent.srcElement,index:e(h.target).index()},l={firstTap:r,secondTap:f,interval:f.time-r.time};s||(w(n,"doubletap",h,l),r=null),s=!0,window.setTimeout(function(){s=!1},a.doubletap_int)}else i.data("lastTouch",c),t=window.setTimeout(function(){r=null,window.clearTimeout(t)},a.doubletap_int,[h]);i.data("lastTouch",c)})},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(s){if(o.data("callee2",e),s.target==n){var p=s.originalEvent.changedTouches?s.originalEvent.changedTouches[0].pageX:s.pageX,h=s.originalEvent.changedTouches?s.originalEvent.changedTouches[0].pageY:s.pageY;a.tap_timer=window.setTimeout(function(){var e=r.x-p,n=r.y-h;if(!o.data("doubletapped")&&!o.data("tapheld")&&(r.x==p&&r.y==h||e>=-a.tap_pixel_range&&e<=a.tap_pixel_range&&n>=-a.tap_pixel_range&&n<=a.tap_pixel_range)){var c=s.originalEvent,u={position:{x:a.touch_capable?c.changedTouches[0].pageX:s.pageX,y:a.touch_capable?c.changedTouches[0].pageY:s.pageY},offset:{x:a.touch_capable?Math.round(c.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(s.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(c.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(s.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:s.target};u.time-i=-a.tap_pixel_range&&f<=a.tap_pixel_range&&l>=-a.tap_pixel_range&&l<=a.tap_pixel_range)){for(var g=h.originalEvent,d=[],v=0;vs.y&&r.y-s.y>g&&(c="swipeup"),r.xl&&(c="swiperight"),r.yg&&(c="swipedown"),r.x>s.x&&r.x-s.x>l&&(c="swipeleft"),void 0!=c&&n){r.x=0,r.y=0,s.x=0,s.y=0,n=!1;var d=h.originalEvent,v={position:{x:a.touch_capable?d.touches[0].pageX:h.pageX,y:a.touch_capable?d.touches[0].pageY:h.pageY},offset:{x:a.touch_capable?Math.round(d.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(h.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(d.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(h.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:h.target},w=Math.abs(t.position.x-v.position.x),_=Math.abs(t.position.y-v.position.y),T={startEvnt:t,endEvnt:v,direction:c.replace("swipe",""),xAmount:w,yAmount:_,duration:v.time-t.time};i=!0,o.trigger("swipe",T).trigger(c,T)}}),o.on(a.endevent,function r(s){var p="";if((o=e(s.currentTarget)).data("callee3",r),i){var h=o.data("xthreshold"),c=o.data("ythreshold"),u=void 0!==h&&!1!==h&&parseInt(h)?parseInt(h):a.swipe_h_threshold,f=void 0!==c&&!1!==c&&parseInt(c)?parseInt(c):a.swipe_v_threshold,l=s.originalEvent,g={position:{x:a.touch_capable?l.changedTouches[0].pageX:s.pageX,y:a.touch_capable?l.changedTouches[0].pageY:s.pageY},offset:{x:a.touch_capable?Math.round(l.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(s.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(l.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(s.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:s.target};t.position.y>g.position.y&&t.position.y-g.position.y>f&&(p="swipeup"),t.position.xu&&(p="swiperight"),t.position.yf&&(p="swipedown"),t.position.x>g.position.x&&t.position.x-g.position.x>u&&(p="swipeleft");var d=Math.abs(t.position.x-g.position.x),v=Math.abs(t.position.y-g.position.y),w={startEvnt:t,endEvnt:g,direction:p.replace("swipe",""),xAmount:d,yAmount:v,duration:g.time-t.time};o.trigger("swipeend",w)}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,s=e(window),p={0:!0,180:!0};if(a.orientation_support){var h=window.innerWidth||s.width(),c=window.innerHeight||s.height();i=h>c&&h-c>50,r=p[window.orientation],(i&&r||!i&&!r)&&(p={"-90":!0,90:!0})}function u(){var e=o();e!==n&&(n=e,s.trigger("orientationchange"))}e.event.special.orientationchange={setup:function(){return!a.orientation_support&&(n=o(),s.on("throttledresize",u),!0)},teardown:function(){return!a.orientation_support&&(s.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?p[window.orientation]:e&&e.clientWidth/e.clientHeight<1.1)?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",d)},teardown:function(){e(this).off("resize",d)}};var f,l,g,d=function(){l=Date.now(),(g=l-v)>=250?(v=l,e(this).trigger("throttledresize")):(f&&window.clearTimeout(f),f=window.setTimeout(u,250-g))},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); From 96771542eebc115e694e0f0df08dfda6103d9b70 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Sun, 20 May 2018 14:03:05 +0100 Subject: [PATCH 123/149] Sync to 2.0.0 --- src/jquery.mobile-events.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jquery.mobile-events.min.js b/src/jquery.mobile-events.min.js index 0269098..36a20fb 100644 --- a/src/jquery.mobile-events.min.js +++ b/src/jquery.mobile-events.min.js @@ -25,4 +25,4 @@ * */ -'use strict';(function(a){function b(){var x=j();x!==k&&(k=x,g.trigger('orientationchange'))}function c(x,y,z,A){var B=z.type;z.type=y,a.event.dispatch.call(x,z,A),z.type=B}a.attrFn=a.attrFn||{};var d='ontouchstart'in window,f={tap_pixel_range:5,swipe_h_threshold:50,swipe_v_threshold:50,taphold_threshold:750,doubletap_int:500,touch_capable:d,orientation_support:'orientation'in window&&'onorientationchange'in window,startevent:d?'touchstart':'mousedown',endevent:d?'touchend':'mouseup',moveevent:d?'touchmove':'mousemove',tapevent:d?'tap':'click',scrollevent:d?'touchmove':'scroll',hold_timer:null,tap_timer:null};a.isTouchCapable=function(){return f.touch_capable},a.getStartEvent=function(){return f.startevent},a.getEndEvent=function(){return f.endevent},a.getMoveEvent=function(){return f.moveevent},a.getTapEvent=function(){return f.tapevent},a.getScrollEvent=function(){return f.scrollevent},a.each(['tapstart','tapend','tapmove','tap','tap2','tap3','tap4','singletap','doubletap','taphold','swipe','swipeup','swiperight','swipedown','swipeleft','swipeend','scrollstart','scrollend','orientationchange'],function(x,y){a.fn[y]=function(z){return z?this.on(y,z):this.trigger(y)},a.attrFn[y]=!0}),a.event.special.tapstart={setup:function(){var x=this,y=a(x);y.on(f.startevent,function z(A){if(y.data('callee',z),A.which&&1!==A.which)return!1;var B=A.originalEvent,C={position:{x:f.touch_capable?B.touches[0].screenX:A.screenX,y:f.touch_capable?B.touches[0].screenY:A.screenY},offset:{x:f.touch_capable?Math.round(B.changedTouches[0].pageX-(y.offset()?y.offset().left:0)):Math.round(A.pageX-(y.offset()?y.offset().left:0)),y:f.touch_capable?Math.round(B.changedTouches[0].pageY-(y.offset()?y.offset().top:0)):Math.round(A.pageY-(y.offset()?y.offset().top:0))},time:Date.now(),target:A.target};return c(x,'tapstart',A,C),!0})},remove:function(){a(this).off(f.startevent,a(this).data.callee)}},a.event.special.tapmove={setup:function(){var x=this,y=a(x);y.on(f.moveevent,function z(A){y.data('callee',z);var B=A.originalEvent,C={position:{x:f.touch_capable?B.touches[0].screenX:A.screenX,y:f.touch_capable?B.touches[0].screenY:A.screenY},offset:{x:f.touch_capable?Math.round(B.changedTouches[0].pageX-(y.offset()?y.offset().left:0)):Math.round(A.pageX-(y.offset()?y.offset().left:0)),y:f.touch_capable?Math.round(B.changedTouches[0].pageY-(y.offset()?y.offset().top:0)):Math.round(A.pageY-(y.offset()?y.offset().top:0))},time:Date.now(),target:A.target};return c(x,'tapmove',A,C),!0})},remove:function(){a(this).off(f.moveevent,a(this).data.callee)}},a.event.special.tapend={setup:function(){var x=this,y=a(x);y.on(f.endevent,function z(A){y.data('callee',z);var B=A.originalEvent,C={position:{x:f.touch_capable?B.changedTouches[0].screenX:A.screenX,y:f.touch_capable?B.changedTouches[0].screenY:A.screenY},offset:{x:f.touch_capable?Math.round(B.changedTouches[0].pageX-(y.offset()?y.offset().left:0)):Math.round(A.pageX-(y.offset()?y.offset().left:0)),y:f.touch_capable?Math.round(B.changedTouches[0].pageY-(y.offset()?y.offset().top:0)):Math.round(A.pageY-(y.offset()?y.offset().top:0))},time:Date.now(),target:A.target};return c(x,'tapend',A,C),!0})},remove:function(){a(this).off(f.endevent,a(this).data.callee)}},a.event.special.taphold={setup:function(){var z,x=this,y=a(x),A={x:0,y:0},B=0,C=0;y.on(f.startevent,function D(E){if(E.which&&1!==E.which)return!1;y.data('tapheld',!1),z=E.target;var F=E.originalEvent,G=Date.now(),H={x:f.touch_capable?F.touches[0].screenX:E.screenX,y:f.touch_capable?F.touches[0].screenY:E.screenY},I={x:f.touch_capable?F.touches[0].pageX-F.touches[0].target.offsetLeft:E.offsetX,y:f.touch_capable?F.touches[0].pageY-F.touches[0].target.offsetTop:E.offsetY};A.x=E.originalEvent.targetTouches?E.originalEvent.targetTouches[0].pageX:E.pageX,A.y=E.originalEvent.targetTouches?E.originalEvent.targetTouches[0].pageY:E.pageY,B=A.x,C=A.y;var J=y.parent().data('threshold')?y.parent().data('threshold'):y.data('threshold'),K='undefined'!=typeof J&&!1!==J&&parseInt(J)?parseInt(J):f.taphold_threshold;return f.hold_timer=window.setTimeout(function(){var L=A.x-B,M=A.y-C;if(E.target==z&&(A.x==B&&A.y==C||L>=-f.tap_pixel_range&&L<=f.tap_pixel_range&&M>=-f.tap_pixel_range&&M<=f.tap_pixel_range)){y.data('tapheld',!0);var N=Date.now(),O={x:f.touch_capable?F.touches[0].screenX:E.screenX,y:f.touch_capable?F.touches[0].screenY:E.screenY},P={x:f.touch_capable?Math.round(F.changedTouches[0].pageX-(y.offset()?y.offset().left:0)):Math.round(E.pageX-(y.offset()?y.offset().left:0)),y:f.touch_capable?Math.round(F.changedTouches[0].pageY-(y.offset()?y.offset().top:0)):Math.round(E.pageY-(y.offset()?y.offset().top:0))},R={startTime:G,endTime:N,startPosition:H,startOffset:I,endPosition:O,endOffset:P,duration:N-G,target:E.target};y.data('callee1',D),c(x,'taphold',E,R)}},K),!0}).on(f.endevent,function D(){y.data('callee2',D),y.data('tapheld',!1),window.clearTimeout(f.hold_timer)}).on(f.moveevent,function D(E){y.data('callee3',D),B=E.originalEvent.targetTouches?E.originalEvent.targetTouches[0].pageX:E.pageX,C=E.originalEvent.targetTouches?E.originalEvent.targetTouches[0].pageY:E.pageY})},remove:function(){a(this).off(f.startevent,a(this).data.callee1).off(f.endevent,a(this).data.callee2).off(f.moveevent,a(this).data.callee3)}},a.event.special.doubletap={setup:function(){var z,A,C,D,x=this,y=a(x),B=null,E=!1;y.on(f.startevent,function F(G){return G.which&&1!==G.which?!1:(y.data('doubletapped',!1),z=G.target,y.data('callee1',F),C=G.originalEvent,B||(B={position:{x:f.touch_capable?C.touches[0].screenX:G.screenX,y:f.touch_capable?C.touches[0].screenY:G.screenY},offset:{x:f.touch_capable?Math.round(C.changedTouches[0].pageX-(y.offset()?y.offset().left:0)):Math.round(G.pageX-(y.offset()?y.offset().left:0)),y:f.touch_capable?Math.round(C.changedTouches[0].pageY-(y.offset()?y.offset().top:0)):Math.round(G.pageY-(y.offset()?y.offset().top:0))},time:Date.now(),target:G.target,element:G.originalEvent.srcElement,index:a(G.target).index()}),!0)}).on(f.endevent,function F(G){var H=Date.now(),I=y.data('lastTouch')||H+1,J=H-I;if(window.clearTimeout(A),y.data('callee2',F),J=-f.tap_pixel_range&&G<=f.tap_pixel_range&&H>=-f.tap_pixel_range&&H<=f.tap_pixel_range)){var I=D.originalEvent,J={position:{x:f.touch_capable?I.changedTouches[0].screenX:D.screenX,y:f.touch_capable?I.changedTouches[0].screenY:D.screenY},offset:{x:f.touch_capable?Math.round(I.changedTouches[0].pageX-(y.offset()?y.offset().left:0)):Math.round(D.pageX-(y.offset()?y.offset().left:0)),y:f.touch_capable?Math.round(I.changedTouches[0].pageY-(y.offset()?y.offset().top:0)):Math.round(D.pageY-(y.offset()?y.offset().top:0))},time:Date.now(),target:D.target};J.time-A=-f.tap_pixel_range&&I<=f.tap_pixel_range&&J>=-f.tap_pixel_range&&J<=f.tap_pixel_range)){for(var O,L=F.originalEvent,M=[],N=0;NF.y&&E.y-F.y>M&&(I='swipeup'),E.xL&&(I='swiperight'),E.yM&&(I='swipedown'),E.x>F.x&&E.x-F.x>L&&(I='swipeleft'),void 0!=I&&C){E.x=0,E.y=0,F.x=0,F.y=0,C=!1;var N=H.originalEvent,O={position:{x:f.touch_capable?N.touches[0].screenX:H.screenX,y:f.touch_capable?N.touches[0].screenY:H.screenY},offset:{x:f.touch_capable?Math.round(N.changedTouches[0].pageX-(B.offset()?B.offset().left:0)):Math.round(H.pageX-(B.offset()?B.offset().left:0)),y:f.touch_capable?Math.round(N.changedTouches[0].pageY-(B.offset()?B.offset().top:0)):Math.round(H.pageY-(B.offset()?B.offset().top:0))},time:Date.now(),target:H.target},P=Math.abs(G.position.x-O.position.x),Q=Math.abs(G.position.y-O.position.y),R={startEvnt:G,endEvnt:O,direction:I.replace('swipe',''),xAmount:P,yAmount:Q,duration:O.time-G.time};D=!0,B.trigger('swipe',R).trigger(I,R)}}function z(H){B=a(H.currentTarget);var I='';if(B.data('callee3',z),D){var J=B.data('xthreshold'),K=B.data('ythreshold'),L='undefined'!=typeof J&&!1!==J&&parseInt(J)?parseInt(J):f.swipe_h_threshold,M='undefined'!=typeof K&&!1!==K&&parseInt(K)?parseInt(K):f.swipe_v_threshold,N=H.originalEvent,O={position:{x:f.touch_capable?N.changedTouches[0].screenX:H.screenX,y:f.touch_capable?N.changedTouches[0].screenY:H.screenY},offset:{x:f.touch_capable?Math.round(N.changedTouches[0].pageX-(B.offset()?B.offset().left:0)):Math.round(H.pageX-(B.offset()?B.offset().left:0)),y:f.touch_capable?Math.round(N.changedTouches[0].pageY-(B.offset()?B.offset().top:0)):Math.round(H.pageY-(B.offset()?B.offset().top:0))},time:Date.now(),target:H.target};G.position.y>O.position.y&&G.position.y-O.position.y>M&&(I='swipeup'),G.position.xL&&(I='swiperight'),G.position.yM&&(I='swipedown'),G.position.x>O.position.x&&G.position.x-O.position.x>L&&(I='swipeleft');var P=Math.abs(G.position.x-O.position.x),Q=Math.abs(G.position.y-O.position.y),R={startEvnt:G,endEvnt:O,direction:I.replace('swipe',''),xAmount:P,yAmount:Q,duration:O.time-G.time};B.trigger('swipeend',R)}C=!1,D=!1}var G,A=this,B=a(A),C=!1,D=!1,E={x:0,y:0},F={x:0,y:0};B.on(f.startevent,x),B.on(f.moveevent,y),B.on(f.endevent,z)},remove:function(){a(this).off(f.startevent,a(this).data.callee1).off(f.moveevent,a(this).data.callee2).off(f.endevent,a(this).data.callee3)}},a.event.special.scrollstart={setup:function(){function x(C,D){A=D,c(y,A?'scrollstart':'scrollend',C)}var A,B,y=this,z=a(y);z.on(f.scrollevent,function C(D){z.data('callee',C),A||x(D,!0),clearTimeout(B),B=setTimeout(function(){x(D,!1)},50)})},remove:function(){a(this).off(f.scrollevent,a(this).data.callee)}};var h,j,k,l,m,g=a(window),n={0:!0,180:!0};if(f.orientation_support){var o=window.innerWidth||g.width(),p=window.innerHeight||g.height();l=o>p&&o-p>50,m=n[window.orientation],(l&&m||!l&&!m)&&(n={90:!0,'-90':!0})}a.event.special.orientationchange=h={setup:function(){return!f.orientation_support&&(k=j(),g.on('throttledresize',b),!0)},teardown:function(){return!f.orientation_support&&(g.off('throttledresize',b),!0)},add:function(x){var y=x.handler;x.handler=function(z){return z.orientation=j(),y.apply(this,arguments)}}},a.event.special.orientationchange.orientation=j=function(){var x=!0,y=document.documentElement;return x=f.orientation_support?n[window.orientation]:y&&1.1>y.clientWidth/y.clientHeight,x?'portrait':'landscape'},a.event.special.throttledresize={setup:function(){a(this).on('resize',s)},teardown:function(){a(this).off('resize',s)}};var u,v,w,r=250,s=function(){v=Date.now(),w=v-t,w>=r?(t=v,a(this).trigger('throttledresize')):(u&&window.clearTimeout(u),u=window.setTimeout(b,r-w))},t=0;a.each({scrollend:'scrollstart',swipeup:'swipe',swiperight:'swipe',swipedown:'swipe',swipeleft:'swipe',swipeend:'swipe',tap2:'tap'},function(x,y){a.event.special[x]={setup:function(){a(this).on(y,a.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=n.originalEvent,r={position:{x:a.touch_capable?i.touches[0].pageX:n.pageX,y:a.touch_capable?i.touches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(i.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(n.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(i.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(n.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:n.target};return w(t,"tapstart",n,r),!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=n.originalEvent,r={position:{x:a.touch_capable?i.touches[0].pageX:n.pageX,y:a.touch_capable?i.touches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(i.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(n.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(i.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(n.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:n.target};return w(t,"tapmove",n,r),!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=n.originalEvent,r={position:{x:a.touch_capable?i.changedTouches[0].pageX:n.pageX,y:a.touch_capable?i.changedTouches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(i.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(n.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(i.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(n.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:n.target};return w(t,"tapend",n,r),!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,s=0;n.on(a.startevent,function e(p){if(p.which&&1!==p.which)return!1;n.data("tapheld",!1),t=p.target;var h=p.originalEvent,c=Date.now();a.touch_capable?h.touches[0].pageX:p.pageX,a.touch_capable?h.touches[0].pageY:p.pageY,a.touch_capable?(h.touches[0].pageX,h.touches[0].target.offsetLeft):p.offsetX,a.touch_capable?(h.touches[0].pageY,h.touches[0].target.offsetTop):p.offsetY;i.x=p.originalEvent.targetTouches?p.originalEvent.targetTouches[0].pageX:p.pageX,i.y=p.originalEvent.targetTouches?p.originalEvent.targetTouches[0].pageY:p.pageY,r=i.x,s=i.y;var u=n.parent().data("threshold")?n.parent().data("threshold"):n.data("threshold"),f=void 0!==u&&!1!==u&&parseInt(u)?parseInt(u):a.taphold_threshold;return a.hold_timer=window.setTimeout(function(){var u=i.x-r,f=i.y-s;if(p.target==t&&(i.x==r&&i.y==s||u>=-a.tap_pixel_range&&u<=a.tap_pixel_range&&f>=-a.tap_pixel_range&&f<=a.tap_pixel_range)){n.data("tapheld",!0);for(var l=Date.now()-c,g=p.originalEvent.targetTouches?p.originalEvent.targetTouches:[p],d=[],v=0;v100){i.data("doubletapped",!0),window.clearTimeout(a.tap_timer);var f={position:{x:a.touch_capable?h.originalEvent.changedTouches[0].pageX:h.pageX,y:a.touch_capable?h.originalEvent.changedTouches[0].pageY:h.pageY},offset:{x:a.touch_capable?Math.round(o.changedTouches[0].pageX-(i.offset()?i.offset().left:0)):Math.round(h.pageX-(i.offset()?i.offset().left:0)),y:a.touch_capable?Math.round(o.changedTouches[0].pageY-(i.offset()?i.offset().top:0)):Math.round(h.pageY-(i.offset()?i.offset().top:0))},time:Date.now(),target:h.target,element:h.originalEvent.srcElement,index:e(h.target).index()},l={firstTap:r,secondTap:f,interval:f.time-r.time};s||(w(n,"doubletap",h,l),r=null),s=!0,window.setTimeout(function(){s=!1},a.doubletap_int)}else i.data("lastTouch",c),t=window.setTimeout(function(){r=null,window.clearTimeout(t)},a.doubletap_int,[h]);i.data("lastTouch",c)})},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(s){if(o.data("callee2",e),s.target==n){var p=s.originalEvent.changedTouches?s.originalEvent.changedTouches[0].pageX:s.pageX,h=s.originalEvent.changedTouches?s.originalEvent.changedTouches[0].pageY:s.pageY;a.tap_timer=window.setTimeout(function(){var e=r.x-p,n=r.y-h;if(!o.data("doubletapped")&&!o.data("tapheld")&&(r.x==p&&r.y==h||e>=-a.tap_pixel_range&&e<=a.tap_pixel_range&&n>=-a.tap_pixel_range&&n<=a.tap_pixel_range)){var c=s.originalEvent,u={position:{x:a.touch_capable?c.changedTouches[0].pageX:s.pageX,y:a.touch_capable?c.changedTouches[0].pageY:s.pageY},offset:{x:a.touch_capable?Math.round(c.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(s.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(c.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(s.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:s.target};u.time-i=-a.tap_pixel_range&&f<=a.tap_pixel_range&&l>=-a.tap_pixel_range&&l<=a.tap_pixel_range)){for(var g=h.originalEvent,d=[],v=0;vs.y&&r.y-s.y>g&&(c="swipeup"),r.xl&&(c="swiperight"),r.yg&&(c="swipedown"),r.x>s.x&&r.x-s.x>l&&(c="swipeleft"),void 0!=c&&n){r.x=0,r.y=0,s.x=0,s.y=0,n=!1;var d=h.originalEvent,v={position:{x:a.touch_capable?d.touches[0].pageX:h.pageX,y:a.touch_capable?d.touches[0].pageY:h.pageY},offset:{x:a.touch_capable?Math.round(d.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(h.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(d.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(h.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:h.target},w=Math.abs(t.position.x-v.position.x),_=Math.abs(t.position.y-v.position.y),T={startEvnt:t,endEvnt:v,direction:c.replace("swipe",""),xAmount:w,yAmount:_,duration:v.time-t.time};i=!0,o.trigger("swipe",T).trigger(c,T)}}),o.on(a.endevent,function r(s){var p="";if((o=e(s.currentTarget)).data("callee3",r),i){var h=o.data("xthreshold"),c=o.data("ythreshold"),u=void 0!==h&&!1!==h&&parseInt(h)?parseInt(h):a.swipe_h_threshold,f=void 0!==c&&!1!==c&&parseInt(c)?parseInt(c):a.swipe_v_threshold,l=s.originalEvent,g={position:{x:a.touch_capable?l.changedTouches[0].pageX:s.pageX,y:a.touch_capable?l.changedTouches[0].pageY:s.pageY},offset:{x:a.touch_capable?Math.round(l.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(s.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(l.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(s.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:s.target};t.position.y>g.position.y&&t.position.y-g.position.y>f&&(p="swipeup"),t.position.xu&&(p="swiperight"),t.position.yf&&(p="swipedown"),t.position.x>g.position.x&&t.position.x-g.position.x>u&&(p="swipeleft");var d=Math.abs(t.position.x-g.position.x),v=Math.abs(t.position.y-g.position.y),w={startEvnt:t,endEvnt:g,direction:p.replace("swipe",""),xAmount:d,yAmount:v,duration:g.time-t.time};o.trigger("swipeend",w)}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,s=e(window),p={0:!0,180:!0};if(a.orientation_support){var h=window.innerWidth||s.width(),c=window.innerHeight||s.height();i=h>c&&h-c>50,r=p[window.orientation],(i&&r||!i&&!r)&&(p={"-90":!0,90:!0})}function u(){var e=o();e!==n&&(n=e,s.trigger("orientationchange"))}e.event.special.orientationchange={setup:function(){return!a.orientation_support&&(n=o(),s.on("throttledresize",u),!0)},teardown:function(){return!a.orientation_support&&(s.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?p[window.orientation]:e&&e.clientWidth/e.clientHeight<1.1)?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",d)},teardown:function(){e(this).off("resize",d)}};var f,l,g,d=function(){l=Date.now(),(g=l-v)>=250?(v=l,e(this).trigger("throttledresize")):(f&&window.clearTimeout(f),f=window.setTimeout(u,250-g))},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); From fa36710f20b9932aebd6a20c07087b90f8d77802 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Sun, 20 May 2018 14:04:21 +0100 Subject: [PATCH 124/149] Create LICENSE --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e227233 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Ben Major + +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. From 75bf264c07e5863ac548ec892a90e87f785dddce Mon Sep 17 00:00:00 2001 From: Ben Major Date: Sun, 20 May 2018 14:06:34 +0100 Subject: [PATCH 125/149] Update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 7295feb..75becd6 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,11 @@ 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.0** (2018-05-20) + + Added two-finger tap event (`tap2`). + + Added two-finger taphold event (`taphold2`). + + Added setter functions to easily set thresholds globally. + + **Version 1.0.9** (2017-06-07) + Fixes a bug where binding to multiple elements with the same selector caused issues with `doubletap`. From 2a69a61d2471c3e2f9ffb42de51d98bc918c5116 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Sun, 20 May 2018 14:06:57 +0100 Subject: [PATCH 126/149] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 75becd6..658b568 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,8 @@ After almost 2 years in public beta, I am pleased to announce that the library i + Added two-finger tap event (`tap2`). + Added two-finger taphold event (`taphold2`). + Added setter functions to easily set thresholds globally. + + Fixed a bug where the offset position of elements was sometimes incorrect. + + Other minor bug fixes. + **Version 1.0.9** (2017-06-07) + Fixes a bug where binding to multiple elements with the same selector caused issues with `doubletap`. From 05c3931d207069e324aaf908ca87f12257310392 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Tue, 11 Sep 2018 09:37:26 +0100 Subject: [PATCH 127/149] Add 2.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 99e8e45..d50b19f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jquery-touch-events", - "version": "1.0.9", + "version": "2.0.0", "description": "Polyfill to remove click delays on browsers with touch UIs.", "maintainers": [ { From a99d1d8a6b3139f10292916063253e4115227680 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Mon, 2 Dec 2019 09:25:10 +0000 Subject: [PATCH 128/149] 2.0.1 launch Fix for # 156. --- src/2.0.1/jquery.mobile-events.js | 920 ++++++++++++++++++++++++++++++ 1 file changed, 920 insertions(+) create mode 100644 src/2.0.1/jquery.mobile-events.js diff --git a/src/2.0.1/jquery.mobile-events.js b/src/2.0.1/jquery.mobile-events.js new file mode 100644 index 0000000..206ad4a --- /dev/null +++ b/src/2.0.1/jquery.mobile-events.js @@ -0,0 +1,920 @@ +/*! + * jQuery Mobile Events + * by Ben Major + * + * Copyright 2011-2017, 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 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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 = [ ]; + + 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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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) { + 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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 (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 (originalCoord.x > finalCoord.x && (originalCoord.x - finalCoord.x > h_threshold)) { + swipedir = 'swipeleft'; + } + 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 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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + '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 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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), + 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + }, + 'time': Date.now(), + '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); + + 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)); From cec0d4dfe36c6a305394abeb86f0f4d918ff064e Mon Sep 17 00:00:00 2001 From: Ben Major Date: Mon, 2 Dec 2019 09:26:22 +0000 Subject: [PATCH 129/149] Create jquery.mobile-events.min.js Sync to 2.0.1 --- src/2.0.1/jquery.mobile-events.min.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/2.0.1/jquery.mobile-events.min.js diff --git a/src/2.0.1/jquery.mobile-events.min.js b/src/2.0.1/jquery.mobile-events.min.js new file mode 100644 index 0000000..10b8c00 --- /dev/null +++ b/src/2.0.1/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=n.originalEvent,r={position:{x:a.touch_capable?i.touches[0].pageX:n.pageX,y:a.touch_capable?i.touches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(i.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(n.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(i.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(n.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:n.target};return w(t,"tapstart",n,r),!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=n.originalEvent,r={position:{x:a.touch_capable?i.touches[0].pageX:n.pageX,y:a.touch_capable?i.touches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(i.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(n.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(i.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(n.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:n.target};return w(t,"tapmove",n,r),!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=n.originalEvent,r={position:{x:a.touch_capable?i.changedTouches[0].pageX:n.pageX,y:a.touch_capable?i.changedTouches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(i.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(n.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(i.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(n.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:n.target};return w(t,"tapend",n,r),!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,s=0;n.on(a.startevent,function e(p){if(p.which&&1!==p.which)return!1;n.data("tapheld",!1),t=p.target;var h=p.originalEvent,c=Date.now();a.touch_capable?h.touches[0].pageX:p.pageX,a.touch_capable?h.touches[0].pageY:p.pageY,a.touch_capable?(h.touches[0].pageX,h.touches[0].target.offsetLeft):p.offsetX,a.touch_capable?(h.touches[0].pageY,h.touches[0].target.offsetTop):p.offsetY;i.x=p.originalEvent.targetTouches?p.originalEvent.targetTouches[0].pageX:p.pageX,i.y=p.originalEvent.targetTouches?p.originalEvent.targetTouches[0].pageY:p.pageY,r=i.x,s=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-s;if(p.target==t&&(i.x==r&&i.y==s||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 f=Date.now()-c,g=p.originalEvent.targetTouches?p.originalEvent.targetTouches:[p],d=[],v=0;v100){i.data("doubletapped",!0),window.clearTimeout(a.tap_timer);var l={position:{x:a.touch_capable?h.originalEvent.changedTouches[0].pageX:h.pageX,y:a.touch_capable?h.originalEvent.changedTouches[0].pageY:h.pageY},offset:{x:a.touch_capable?Math.round(o.changedTouches[0].pageX-(i.offset()?i.offset().left:0)):Math.round(h.pageX-(i.offset()?i.offset().left:0)),y:a.touch_capable?Math.round(o.changedTouches[0].pageY-(i.offset()?i.offset().top:0)):Math.round(h.pageY-(i.offset()?i.offset().top:0))},time:Date.now(),target:h.target,element:h.originalEvent.srcElement,index:e(h.target).index()},f={firstTap:r,secondTap:l,interval:l.time-r.time};s||(w(n,"doubletap",h,f),r=null),s=!0,window.setTimeout(function(){s=!1},a.doubletap_int)}else i.data("lastTouch",c),t=window.setTimeout(function(){r=null,window.clearTimeout(t)},a.doubletap_int,[h]);i.data("lastTouch",c)})},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(s){if(o.data("callee2",e),s.target==n){var p=s.originalEvent.changedTouches?s.originalEvent.changedTouches[0].pageX:s.pageX,h=s.originalEvent.changedTouches?s.originalEvent.changedTouches[0].pageY:s.pageY;a.tap_timer=window.setTimeout(function(){var e=r.x-p,n=r.y-h;if(!o.data("doubletapped")&&!o.data("tapheld")&&(r.x==p&&r.y==h||e>=-a.tap_pixel_range&&e<=a.tap_pixel_range&&n>=-a.tap_pixel_range&&n<=a.tap_pixel_range)){var c=s.originalEvent,u={position:{x:a.touch_capable?c.changedTouches[0].pageX:s.pageX,y:a.touch_capable?c.changedTouches[0].pageY:s.pageY},offset:{x:a.touch_capable?Math.round(c.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(s.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(c.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(s.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:s.target};u.time-i=-a.tap_pixel_range&&l<=a.tap_pixel_range&&f>=-a.tap_pixel_range&&f<=a.tap_pixel_range)){for(var g=h.originalEvent,d=[],v=0;vs.y&&r.y-s.y>g&&(c="swipeup"),r.xf&&(c="swiperight"),r.yg&&(c="swipedown"),r.x>s.x&&r.x-s.x>f&&(c="swipeleft"),null!=c&&n){r.x=0,r.y=0,s.x=0,s.y=0,n=!1;var d=h.originalEvent,v={position:{x:a.touch_capable?d.touches[0].pageX:h.pageX,y:a.touch_capable?d.touches[0].pageY:h.pageY},offset:{x:a.touch_capable?Math.round(d.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(h.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(d.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(h.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:h.target},w=Math.abs(t.position.x-v.position.x),_=Math.abs(t.position.y-v.position.y),T={startEvnt:t,endEvnt:v,direction:c.replace("swipe",""),xAmount:w,yAmount:_,duration:v.time-t.time};i=!0,o.trigger("swipe",T).trigger(c,T)}}),o.on(a.endevent,function r(s){var p="";if((o=e(s.currentTarget)).data("callee3",r),i){var h=o.data("xthreshold"),c=o.data("ythreshold"),u=void 0!==h&&!1!==h&&parseInt(h)?parseInt(h):a.swipe_h_threshold,l=void 0!==c&&!1!==c&&parseInt(c)?parseInt(c):a.swipe_v_threshold,f=s.originalEvent,g={position:{x:a.touch_capable?f.changedTouches[0].pageX:s.pageX,y:a.touch_capable?f.changedTouches[0].pageY:s.pageY},offset:{x:a.touch_capable?Math.round(f.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(s.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(f.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(s.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:s.target};t.position.y>g.position.y&&t.position.y-g.position.y>l&&(p="swipeup"),t.position.xu&&(p="swiperight"),t.position.yl&&(p="swipedown"),t.position.x>g.position.x&&t.position.x-g.position.x>u&&(p="swipeleft");var d=Math.abs(t.position.x-g.position.x),v=Math.abs(t.position.y-g.position.y),w={startEvnt:t,endEvnt:g,direction:p.replace("swipe",""),xAmount:d,yAmount:v,duration:g.time-t.time};o.trigger("swipeend",w)}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,s=e(window),p={0:!0,180:!0};if(a.orientation_support){var h=window.innerWidth||s.width(),c=window.innerHeight||s.height();i=h>c&&h-c>50,r=p[window.orientation],(i&&r||!i&&!r)&&(p={"-90":!0,90:!0})}function u(){var e=o();e!==n&&(n=e,s.trigger("orientationchange"))}e.event.special.orientationchange={setup:function(){return!a.orientation_support&&(n=o(),s.on("throttledresize",u),!0)},teardown:function(){return!a.orientation_support&&(s.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?p[window.orientation]:e&&e.clientWidth/e.clientHeight<1.1)?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",d)},teardown:function(){e(this).off("resize",d)}};var l,f,g,d=function(){f=Date.now(),(g=f-v)>=250?(v=f,e(this).trigger("throttledresize")):(l&&window.clearTimeout(l),l=window.setTimeout(u,250-g))},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); From 3473aaa426243aca3e84894862f465bdf9f01f50 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Mon, 2 Dec 2019 09:26:45 +0000 Subject: [PATCH 130/149] Fix copyright date. --- src/2.0.1/jquery.mobile-events.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/2.0.1/jquery.mobile-events.js b/src/2.0.1/jquery.mobile-events.js index 206ad4a..ef7630c 100644 --- a/src/2.0.1/jquery.mobile-events.js +++ b/src/2.0.1/jquery.mobile-events.js @@ -2,7 +2,7 @@ * jQuery Mobile Events * by Ben Major * - * Copyright 2011-2017, 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 From 9a6e4c6a8a184b4c02a8381b7adf7796e702aaaa Mon Sep 17 00:00:00 2001 From: Ben Major Date: Mon, 2 Dec 2019 09:30:24 +0000 Subject: [PATCH 131/149] Sync to 2.0.1 --- src/jquery.mobile-events.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/jquery.mobile-events.js b/src/jquery.mobile-events.js index d0bcca8..ef7630c 100644 --- a/src/jquery.mobile-events.js +++ b/src/jquery.mobile-events.js @@ -2,7 +2,7 @@ * jQuery Mobile Events * by Ben Major * - * Copyright 2011-2017, 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 @@ -247,7 +247,7 @@ 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; - settings.hold_timer = window.setTimeout(function () { + $this.data('hold_timer', window.setTimeout(function () { var diff_x = (start_pos.x - end_x), diff_y = (start_pos.y - end_y); @@ -286,14 +286,14 @@ triggerCustomEvent(thisObject, evt_name, e, touchData); } - }, threshold); + }, threshold) ); return true; } }).on(settings.endevent, function tapHoldFunc2() { $this.data('callee2', tapHoldFunc2); $this.data('tapheld', false); - window.clearTimeout(settings.hold_timer); + window.clearTimeout( $this.data('hold_timer') ); }) .on(settings.moveevent, function tapHoldFunc3(e) { $this.data('callee3', tapHoldFunc3); From 115e0a123f5035227b0ec23eb1ed786c7417d981 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Mon, 2 Dec 2019 09:30:58 +0000 Subject: [PATCH 132/149] Sync to 2.0.1 --- src/jquery.mobile-events.min.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/jquery.mobile-events.min.js b/src/jquery.mobile-events.min.js index 36a20fb..10b8c00 100644 --- a/src/jquery.mobile-events.min.js +++ b/src/jquery.mobile-events.min.js @@ -2,7 +2,7 @@ * jQuery Mobile Events * by Ben Major * - * Copyright 2011-2017, 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 @@ -24,5 +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=n.originalEvent,r={position:{x:a.touch_capable?i.touches[0].pageX:n.pageX,y:a.touch_capable?i.touches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(i.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(n.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(i.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(n.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:n.target};return w(t,"tapstart",n,r),!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=n.originalEvent,r={position:{x:a.touch_capable?i.touches[0].pageX:n.pageX,y:a.touch_capable?i.touches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(i.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(n.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(i.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(n.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:n.target};return w(t,"tapmove",n,r),!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=n.originalEvent,r={position:{x:a.touch_capable?i.changedTouches[0].pageX:n.pageX,y:a.touch_capable?i.changedTouches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(i.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(n.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(i.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(n.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:n.target};return w(t,"tapend",n,r),!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,s=0;n.on(a.startevent,function e(p){if(p.which&&1!==p.which)return!1;n.data("tapheld",!1),t=p.target;var h=p.originalEvent,c=Date.now();a.touch_capable?h.touches[0].pageX:p.pageX,a.touch_capable?h.touches[0].pageY:p.pageY,a.touch_capable?(h.touches[0].pageX,h.touches[0].target.offsetLeft):p.offsetX,a.touch_capable?(h.touches[0].pageY,h.touches[0].target.offsetTop):p.offsetY;i.x=p.originalEvent.targetTouches?p.originalEvent.targetTouches[0].pageX:p.pageX,i.y=p.originalEvent.targetTouches?p.originalEvent.targetTouches[0].pageY:p.pageY,r=i.x,s=i.y;var u=n.parent().data("threshold")?n.parent().data("threshold"):n.data("threshold"),f=void 0!==u&&!1!==u&&parseInt(u)?parseInt(u):a.taphold_threshold;return a.hold_timer=window.setTimeout(function(){var u=i.x-r,f=i.y-s;if(p.target==t&&(i.x==r&&i.y==s||u>=-a.tap_pixel_range&&u<=a.tap_pixel_range&&f>=-a.tap_pixel_range&&f<=a.tap_pixel_range)){n.data("tapheld",!0);for(var l=Date.now()-c,g=p.originalEvent.targetTouches?p.originalEvent.targetTouches:[p],d=[],v=0;v100){i.data("doubletapped",!0),window.clearTimeout(a.tap_timer);var f={position:{x:a.touch_capable?h.originalEvent.changedTouches[0].pageX:h.pageX,y:a.touch_capable?h.originalEvent.changedTouches[0].pageY:h.pageY},offset:{x:a.touch_capable?Math.round(o.changedTouches[0].pageX-(i.offset()?i.offset().left:0)):Math.round(h.pageX-(i.offset()?i.offset().left:0)),y:a.touch_capable?Math.round(o.changedTouches[0].pageY-(i.offset()?i.offset().top:0)):Math.round(h.pageY-(i.offset()?i.offset().top:0))},time:Date.now(),target:h.target,element:h.originalEvent.srcElement,index:e(h.target).index()},l={firstTap:r,secondTap:f,interval:f.time-r.time};s||(w(n,"doubletap",h,l),r=null),s=!0,window.setTimeout(function(){s=!1},a.doubletap_int)}else i.data("lastTouch",c),t=window.setTimeout(function(){r=null,window.clearTimeout(t)},a.doubletap_int,[h]);i.data("lastTouch",c)})},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(s){if(o.data("callee2",e),s.target==n){var p=s.originalEvent.changedTouches?s.originalEvent.changedTouches[0].pageX:s.pageX,h=s.originalEvent.changedTouches?s.originalEvent.changedTouches[0].pageY:s.pageY;a.tap_timer=window.setTimeout(function(){var e=r.x-p,n=r.y-h;if(!o.data("doubletapped")&&!o.data("tapheld")&&(r.x==p&&r.y==h||e>=-a.tap_pixel_range&&e<=a.tap_pixel_range&&n>=-a.tap_pixel_range&&n<=a.tap_pixel_range)){var c=s.originalEvent,u={position:{x:a.touch_capable?c.changedTouches[0].pageX:s.pageX,y:a.touch_capable?c.changedTouches[0].pageY:s.pageY},offset:{x:a.touch_capable?Math.round(c.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(s.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(c.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(s.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:s.target};u.time-i=-a.tap_pixel_range&&f<=a.tap_pixel_range&&l>=-a.tap_pixel_range&&l<=a.tap_pixel_range)){for(var g=h.originalEvent,d=[],v=0;vs.y&&r.y-s.y>g&&(c="swipeup"),r.xl&&(c="swiperight"),r.yg&&(c="swipedown"),r.x>s.x&&r.x-s.x>l&&(c="swipeleft"),void 0!=c&&n){r.x=0,r.y=0,s.x=0,s.y=0,n=!1;var d=h.originalEvent,v={position:{x:a.touch_capable?d.touches[0].pageX:h.pageX,y:a.touch_capable?d.touches[0].pageY:h.pageY},offset:{x:a.touch_capable?Math.round(d.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(h.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(d.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(h.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:h.target},w=Math.abs(t.position.x-v.position.x),_=Math.abs(t.position.y-v.position.y),T={startEvnt:t,endEvnt:v,direction:c.replace("swipe",""),xAmount:w,yAmount:_,duration:v.time-t.time};i=!0,o.trigger("swipe",T).trigger(c,T)}}),o.on(a.endevent,function r(s){var p="";if((o=e(s.currentTarget)).data("callee3",r),i){var h=o.data("xthreshold"),c=o.data("ythreshold"),u=void 0!==h&&!1!==h&&parseInt(h)?parseInt(h):a.swipe_h_threshold,f=void 0!==c&&!1!==c&&parseInt(c)?parseInt(c):a.swipe_v_threshold,l=s.originalEvent,g={position:{x:a.touch_capable?l.changedTouches[0].pageX:s.pageX,y:a.touch_capable?l.changedTouches[0].pageY:s.pageY},offset:{x:a.touch_capable?Math.round(l.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(s.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(l.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(s.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:s.target};t.position.y>g.position.y&&t.position.y-g.position.y>f&&(p="swipeup"),t.position.xu&&(p="swiperight"),t.position.yf&&(p="swipedown"),t.position.x>g.position.x&&t.position.x-g.position.x>u&&(p="swipeleft");var d=Math.abs(t.position.x-g.position.x),v=Math.abs(t.position.y-g.position.y),w={startEvnt:t,endEvnt:g,direction:p.replace("swipe",""),xAmount:d,yAmount:v,duration:g.time-t.time};o.trigger("swipeend",w)}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,s=e(window),p={0:!0,180:!0};if(a.orientation_support){var h=window.innerWidth||s.width(),c=window.innerHeight||s.height();i=h>c&&h-c>50,r=p[window.orientation],(i&&r||!i&&!r)&&(p={"-90":!0,90:!0})}function u(){var e=o();e!==n&&(n=e,s.trigger("orientationchange"))}e.event.special.orientationchange={setup:function(){return!a.orientation_support&&(n=o(),s.on("throttledresize",u),!0)},teardown:function(){return!a.orientation_support&&(s.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?p[window.orientation]:e&&e.clientWidth/e.clientHeight<1.1)?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",d)},teardown:function(){e(this).off("resize",d)}};var f,l,g,d=function(){l=Date.now(),(g=l-v)>=250?(v=l,e(this).trigger("throttledresize")):(f&&window.clearTimeout(f),f=window.setTimeout(u,250-g))},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=n.originalEvent,r={position:{x:a.touch_capable?i.touches[0].pageX:n.pageX,y:a.touch_capable?i.touches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(i.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(n.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(i.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(n.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:n.target};return w(t,"tapstart",n,r),!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=n.originalEvent,r={position:{x:a.touch_capable?i.touches[0].pageX:n.pageX,y:a.touch_capable?i.touches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(i.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(n.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(i.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(n.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:n.target};return w(t,"tapmove",n,r),!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=n.originalEvent,r={position:{x:a.touch_capable?i.changedTouches[0].pageX:n.pageX,y:a.touch_capable?i.changedTouches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(i.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(n.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(i.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(n.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:n.target};return w(t,"tapend",n,r),!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,s=0;n.on(a.startevent,function e(p){if(p.which&&1!==p.which)return!1;n.data("tapheld",!1),t=p.target;var h=p.originalEvent,c=Date.now();a.touch_capable?h.touches[0].pageX:p.pageX,a.touch_capable?h.touches[0].pageY:p.pageY,a.touch_capable?(h.touches[0].pageX,h.touches[0].target.offsetLeft):p.offsetX,a.touch_capable?(h.touches[0].pageY,h.touches[0].target.offsetTop):p.offsetY;i.x=p.originalEvent.targetTouches?p.originalEvent.targetTouches[0].pageX:p.pageX,i.y=p.originalEvent.targetTouches?p.originalEvent.targetTouches[0].pageY:p.pageY,r=i.x,s=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-s;if(p.target==t&&(i.x==r&&i.y==s||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 f=Date.now()-c,g=p.originalEvent.targetTouches?p.originalEvent.targetTouches:[p],d=[],v=0;v100){i.data("doubletapped",!0),window.clearTimeout(a.tap_timer);var l={position:{x:a.touch_capable?h.originalEvent.changedTouches[0].pageX:h.pageX,y:a.touch_capable?h.originalEvent.changedTouches[0].pageY:h.pageY},offset:{x:a.touch_capable?Math.round(o.changedTouches[0].pageX-(i.offset()?i.offset().left:0)):Math.round(h.pageX-(i.offset()?i.offset().left:0)),y:a.touch_capable?Math.round(o.changedTouches[0].pageY-(i.offset()?i.offset().top:0)):Math.round(h.pageY-(i.offset()?i.offset().top:0))},time:Date.now(),target:h.target,element:h.originalEvent.srcElement,index:e(h.target).index()},f={firstTap:r,secondTap:l,interval:l.time-r.time};s||(w(n,"doubletap",h,f),r=null),s=!0,window.setTimeout(function(){s=!1},a.doubletap_int)}else i.data("lastTouch",c),t=window.setTimeout(function(){r=null,window.clearTimeout(t)},a.doubletap_int,[h]);i.data("lastTouch",c)})},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(s){if(o.data("callee2",e),s.target==n){var p=s.originalEvent.changedTouches?s.originalEvent.changedTouches[0].pageX:s.pageX,h=s.originalEvent.changedTouches?s.originalEvent.changedTouches[0].pageY:s.pageY;a.tap_timer=window.setTimeout(function(){var e=r.x-p,n=r.y-h;if(!o.data("doubletapped")&&!o.data("tapheld")&&(r.x==p&&r.y==h||e>=-a.tap_pixel_range&&e<=a.tap_pixel_range&&n>=-a.tap_pixel_range&&n<=a.tap_pixel_range)){var c=s.originalEvent,u={position:{x:a.touch_capable?c.changedTouches[0].pageX:s.pageX,y:a.touch_capable?c.changedTouches[0].pageY:s.pageY},offset:{x:a.touch_capable?Math.round(c.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(s.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(c.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(s.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:s.target};u.time-i=-a.tap_pixel_range&&l<=a.tap_pixel_range&&f>=-a.tap_pixel_range&&f<=a.tap_pixel_range)){for(var g=h.originalEvent,d=[],v=0;vs.y&&r.y-s.y>g&&(c="swipeup"),r.xf&&(c="swiperight"),r.yg&&(c="swipedown"),r.x>s.x&&r.x-s.x>f&&(c="swipeleft"),null!=c&&n){r.x=0,r.y=0,s.x=0,s.y=0,n=!1;var d=h.originalEvent,v={position:{x:a.touch_capable?d.touches[0].pageX:h.pageX,y:a.touch_capable?d.touches[0].pageY:h.pageY},offset:{x:a.touch_capable?Math.round(d.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(h.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(d.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(h.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:h.target},w=Math.abs(t.position.x-v.position.x),_=Math.abs(t.position.y-v.position.y),T={startEvnt:t,endEvnt:v,direction:c.replace("swipe",""),xAmount:w,yAmount:_,duration:v.time-t.time};i=!0,o.trigger("swipe",T).trigger(c,T)}}),o.on(a.endevent,function r(s){var p="";if((o=e(s.currentTarget)).data("callee3",r),i){var h=o.data("xthreshold"),c=o.data("ythreshold"),u=void 0!==h&&!1!==h&&parseInt(h)?parseInt(h):a.swipe_h_threshold,l=void 0!==c&&!1!==c&&parseInt(c)?parseInt(c):a.swipe_v_threshold,f=s.originalEvent,g={position:{x:a.touch_capable?f.changedTouches[0].pageX:s.pageX,y:a.touch_capable?f.changedTouches[0].pageY:s.pageY},offset:{x:a.touch_capable?Math.round(f.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(s.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(f.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(s.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:s.target};t.position.y>g.position.y&&t.position.y-g.position.y>l&&(p="swipeup"),t.position.xu&&(p="swiperight"),t.position.yl&&(p="swipedown"),t.position.x>g.position.x&&t.position.x-g.position.x>u&&(p="swipeleft");var d=Math.abs(t.position.x-g.position.x),v=Math.abs(t.position.y-g.position.y),w={startEvnt:t,endEvnt:g,direction:p.replace("swipe",""),xAmount:d,yAmount:v,duration:g.time-t.time};o.trigger("swipeend",w)}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,s=e(window),p={0:!0,180:!0};if(a.orientation_support){var h=window.innerWidth||s.width(),c=window.innerHeight||s.height();i=h>c&&h-c>50,r=p[window.orientation],(i&&r||!i&&!r)&&(p={"-90":!0,90:!0})}function u(){var e=o();e!==n&&(n=e,s.trigger("orientationchange"))}e.event.special.orientationchange={setup:function(){return!a.orientation_support&&(n=o(),s.on("throttledresize",u),!0)},teardown:function(){return!a.orientation_support&&(s.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?p[window.orientation]:e&&e.clientWidth/e.clientHeight<1.1)?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",d)},teardown:function(){e(this).off("resize",d)}};var l,f,g,d=function(){f=Date.now(),(g=f-v)>=250?(v=f,e(this).trigger("throttledresize")):(l&&window.clearTimeout(l),l=window.setTimeout(u,250-g))},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); From ba490fa79ad59e7897557de88bb217efc5a1bbd9 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Mon, 2 Dec 2019 09:32:00 +0000 Subject: [PATCH 133/149] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 658b568..f053197 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,9 @@ 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.1** (2019-12-02) + + Fix for bug [#156](https://github.com/benmajor/jQuery-Touch-Events/issues/156) + + **Version 2.0.0** (2018-05-20) + Added two-finger tap event (`tap2`). + Added two-finger taphold event (`taphold2`). From f97119ab14bf67121f656cc2e6c87116f9e58337 Mon Sep 17 00:00:00 2001 From: Pascal Garber Date: Mon, 16 Dec 2019 13:58:53 +0100 Subject: [PATCH 134/149] Fix setTapRange method Commit self-explanatory --- src/jquery.mobile-events.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jquery.mobile-events.js b/src/jquery.mobile-events.js index ef7630c..cf16e59 100644 --- a/src/jquery.mobile-events.js +++ b/src/jquery.mobile-events.js @@ -92,7 +92,7 @@ // 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; + settings.tap_pixel_range = range; }; // Add Event shortcuts: From bfa28997f6b7e6b09fd1576cd5a3d84ff2f023b0 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Fri, 14 Feb 2020 16:31:55 +0000 Subject: [PATCH 135/149] Update package.json --- package.json | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index d50b19f..91b6925 100644 --- a/package.json +++ b/package.json @@ -2,12 +2,10 @@ "name": "jquery-touch-events", "version": "2.0.0", "description": "Polyfill to remove click delays on browsers with touch UIs.", - "maintainers": [ - { - "name": "Ben Major", - "email": "ben.major88@gmail.com" - } - ], + "maintainers": [{ + "name": "Ben Major", + "email": "ben.major88@gmail.com" + }], "author": { "name": "Ben Major", "email": "ben.major88@gmail.com" @@ -23,10 +21,8 @@ "mobile", "touch" ], - "licenses": [ - { - "type": "MIT", - "url": "http://opensource.org/licenses/MIT" - } - ] + "licenses": [{ + "type": "MIT", + "url": "http://opensource.org/licenses/MIT" + } ] } From bf1ebb1c87fe593e87713aeed3a514cf77f1c280 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 1 Apr 2020 19:24:00 +0100 Subject: [PATCH 136/149] Fixes for npm --- .DS_Store | Bin 0 -> 6148 bytes package.json | 36 ++++++++++++++++-------------------- 2 files changed, 16 insertions(+), 20 deletions(-) create mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 Date: Wed, 1 Apr 2020 19:24:33 +0100 Subject: [PATCH 137/149] Update bower.json --- bower.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bower.json b/bower.json index 8dc90b7..5b0f9e7 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jquery-touch-events", - "version": "1.0.9", + "version": "2.0.1", "main": "src/jquery.mobile-events.js", "ignore": [ "bower.json" From 739e52309d404c91b94b5a28dee684b593b58259 Mon Sep 17 00:00:00 2001 From: Philip Date: Tue, 21 Apr 2020 06:20:51 +0200 Subject: [PATCH 138/149] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f053197..7d39bb4 100644 --- a/README.md +++ b/README.md @@ -242,7 +242,7 @@ Each event provides different callback data. The following shows the numerous da ## 6. Defining Thresholds: -You can also define custom thresholds to be used for ``swipe`` events (``swipeup``, ``swiperight``, ``swipedown`` and ``swipeleft``) to prevent interference with scrolling and other events. To do so, simply assign a `data-xthreshold` or `date-ythreshold` to the target element as follows: +You can also define custom thresholds to be used for ``swipe`` events (``swipeup``, ``swiperight``, ``swipedown`` and ``swipeleft``) to prevent interference with scrolling and other events. To do so, simply assign a `data-xthreshold` or `data-ythreshold` to the target element as follows: ``
`` From 1cb0d6e8a42268064ee58979ca8a11d0d4cd0026 Mon Sep 17 00:00:00 2001 From: Philip Date: Tue, 21 Apr 2020 06:25:26 +0200 Subject: [PATCH 139/149] Bugfix: Illegal `.offset()` call + indentation typos * Bugfix: fixed illegal calls to `.offset()` is event's caller is `window` or `document` * Indentation: replaced some tabs for spaces --- src/jquery.mobile-events.js | 231 +++++++++++++++++++----------------- 1 file changed, 121 insertions(+), 110 deletions(-) diff --git a/src/jquery.mobile-events.js b/src/jquery.mobile-events.js index cf16e59..1e11ee7 100644 --- a/src/jquery.mobile-events.js +++ b/src/jquery.mobile-events.js @@ -31,14 +31,14 @@ $.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, + shake_threshold: 15, touch_capable: touchCapable, orientation_support: ('orientation' in window && 'onorientationchange' in window), @@ -53,9 +53,9 @@ tap_timer: null }; - // Declare touch namespace: - $.touch = { }; - + // Declare touch namespace: + $.touch = { }; + // Convenience functions: $.isTouchCapable = function() { return settings.touch_capable; }; $.getStartEvent = function() { return settings.startevent; }; @@ -64,37 +64,37 @@ $.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 = range; - }; - + // 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) { @@ -107,17 +107,18 @@ // 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': { @@ -125,13 +126,13 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].pageY : e.pageY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + '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; }); @@ -141,16 +142,17 @@ $(this).off(settings.startevent, $(this).data.callee); } }; - + // tapmove Event: $.event.special.tapmove = { - setup: function() { + 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': { @@ -158,13 +160,13 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].pageY : e.pageY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + '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; }); @@ -184,6 +186,7 @@ // 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': { @@ -191,8 +194,8 @@ 'y': (settings.touch_capable) ? origEvent.changedTouches[0].pageY : e.pageY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + '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 @@ -256,34 +259,35 @@ $this.data('tapheld', true); var end_time = Date.now(); - + var duration = end_time - start_time, - touches = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches : [ e ], - 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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) - }, - 'time': Date.now(), - 'target': e.target, - 'duration': duration - }; - - touchData.push( touch ); - } - - var evt_name = ( touches.length == 2 ) ? 'taphold2' : 'taphold'; - - $this.data('callee1', tapHoldFunc1); - + 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) ); @@ -297,7 +301,7 @@ }) .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; }); @@ -317,8 +321,8 @@ action, firstTap = null, origEvent, - cooloff, - cooling = false; + cooloff, + cooling = false; $this.on(settings.startevent, function doubleTapFunc1(e) { if (e.which && e.which !== 1) { @@ -331,14 +335,15 @@ 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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + '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, @@ -349,7 +354,7 @@ return true; }).on(settings.endevent, function doubleTapFunc2(e) { - + var now = Date.now(); var lastTouch = $this.data('lastTouch') || now + 1; var delta = now - lastTouch; @@ -361,14 +366,15 @@ 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 - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + '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, @@ -383,16 +389,16 @@ }; if (!cooling) { - triggerCustomEvent(thisObject, 'doubletap', e, touchData); + triggerCustomEvent(thisObject, 'doubletap', e, touchData); firstTap = null; } cooling = true; cooloff = window.setTimeout(function () { - cooling = false; + cooling = false; }, settings.doubletap_int); - + } else { $this.data('lastTouch', now); action = window.setTimeout(function () { @@ -451,6 +457,7 @@ 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': { @@ -458,8 +465,8 @@ 'y': (settings.touch_capable) ? origEvent.changedTouches[0].pageY : e.pageY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + '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 @@ -499,17 +506,17 @@ $this.data('callee1', tapFunc1); if( e.which && e.which !== 1 ) - { + { return false; } - else - { + 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; } @@ -522,11 +529,12 @@ 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 = { @@ -535,18 +543,18 @@ 'y': (settings.touch_capable) ? origEvent.changedTouches[i].pageY : e.pageY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + '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'; - + var evt_name = ( touches.length == 2 ) ? 'tap2' : 'tap'; + triggerCustomEvent(thisObject, evt_name, e, touchData); } }); @@ -584,6 +592,7 @@ 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 = { @@ -592,8 +601,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].pageY : e.pageY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + '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 @@ -636,6 +645,7 @@ 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': { @@ -643,8 +653,8 @@ 'y': (settings.touch_capable) ? origEvent.touches[0].pageY : e.pageY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + '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 @@ -678,6 +688,7 @@ 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': { @@ -685,8 +696,8 @@ 'y': (settings.touch_capable) ? origEvent.changedTouches[0].pageY : e.pageY }, 'offset': { - 'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)), - 'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0)) + '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 @@ -907,8 +918,8 @@ swipedown: 'swipe', swipeleft: 'swipe', swipeend: 'swipe', - tap2: 'tap', - taphold2: 'taphold' + tap2: 'tap', + taphold2: 'taphold' }, function (e, srcE) { $.event.special[e] = { setup: function () { From 7728baf06ffedd5a1b1b08d1eec71705b0a986c5 Mon Sep 17 00:00:00 2001 From: Philip Date: Tue, 21 Apr 2020 06:30:47 +0200 Subject: [PATCH 140/149] Update jquery.mobile-events.min.js Updated .min version accordingly --- src/jquery.mobile-events.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jquery.mobile-events.min.js b/src/jquery.mobile-events.min.js index 10b8c00..6ac0a92 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=n.originalEvent,r={position:{x:a.touch_capable?i.touches[0].pageX:n.pageX,y:a.touch_capable?i.touches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(i.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(n.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(i.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(n.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:n.target};return w(t,"tapstart",n,r),!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=n.originalEvent,r={position:{x:a.touch_capable?i.touches[0].pageX:n.pageX,y:a.touch_capable?i.touches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(i.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(n.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(i.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(n.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:n.target};return w(t,"tapmove",n,r),!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=n.originalEvent,r={position:{x:a.touch_capable?i.changedTouches[0].pageX:n.pageX,y:a.touch_capable?i.changedTouches[0].pageY:n.pageY},offset:{x:a.touch_capable?Math.round(i.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(n.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(i.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(n.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:n.target};return w(t,"tapend",n,r),!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,s=0;n.on(a.startevent,function e(p){if(p.which&&1!==p.which)return!1;n.data("tapheld",!1),t=p.target;var h=p.originalEvent,c=Date.now();a.touch_capable?h.touches[0].pageX:p.pageX,a.touch_capable?h.touches[0].pageY:p.pageY,a.touch_capable?(h.touches[0].pageX,h.touches[0].target.offsetLeft):p.offsetX,a.touch_capable?(h.touches[0].pageY,h.touches[0].target.offsetTop):p.offsetY;i.x=p.originalEvent.targetTouches?p.originalEvent.targetTouches[0].pageX:p.pageX,i.y=p.originalEvent.targetTouches?p.originalEvent.targetTouches[0].pageY:p.pageY,r=i.x,s=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-s;if(p.target==t&&(i.x==r&&i.y==s||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 f=Date.now()-c,g=p.originalEvent.targetTouches?p.originalEvent.targetTouches:[p],d=[],v=0;v100){i.data("doubletapped",!0),window.clearTimeout(a.tap_timer);var l={position:{x:a.touch_capable?h.originalEvent.changedTouches[0].pageX:h.pageX,y:a.touch_capable?h.originalEvent.changedTouches[0].pageY:h.pageY},offset:{x:a.touch_capable?Math.round(o.changedTouches[0].pageX-(i.offset()?i.offset().left:0)):Math.round(h.pageX-(i.offset()?i.offset().left:0)),y:a.touch_capable?Math.round(o.changedTouches[0].pageY-(i.offset()?i.offset().top:0)):Math.round(h.pageY-(i.offset()?i.offset().top:0))},time:Date.now(),target:h.target,element:h.originalEvent.srcElement,index:e(h.target).index()},f={firstTap:r,secondTap:l,interval:l.time-r.time};s||(w(n,"doubletap",h,f),r=null),s=!0,window.setTimeout(function(){s=!1},a.doubletap_int)}else i.data("lastTouch",c),t=window.setTimeout(function(){r=null,window.clearTimeout(t)},a.doubletap_int,[h]);i.data("lastTouch",c)})},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(s){if(o.data("callee2",e),s.target==n){var p=s.originalEvent.changedTouches?s.originalEvent.changedTouches[0].pageX:s.pageX,h=s.originalEvent.changedTouches?s.originalEvent.changedTouches[0].pageY:s.pageY;a.tap_timer=window.setTimeout(function(){var e=r.x-p,n=r.y-h;if(!o.data("doubletapped")&&!o.data("tapheld")&&(r.x==p&&r.y==h||e>=-a.tap_pixel_range&&e<=a.tap_pixel_range&&n>=-a.tap_pixel_range&&n<=a.tap_pixel_range)){var c=s.originalEvent,u={position:{x:a.touch_capable?c.changedTouches[0].pageX:s.pageX,y:a.touch_capable?c.changedTouches[0].pageY:s.pageY},offset:{x:a.touch_capable?Math.round(c.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(s.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(c.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(s.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:s.target};u.time-i=-a.tap_pixel_range&&l<=a.tap_pixel_range&&f>=-a.tap_pixel_range&&f<=a.tap_pixel_range)){for(var g=h.originalEvent,d=[],v=0;vs.y&&r.y-s.y>g&&(c="swipeup"),r.xf&&(c="swiperight"),r.yg&&(c="swipedown"),r.x>s.x&&r.x-s.x>f&&(c="swipeleft"),null!=c&&n){r.x=0,r.y=0,s.x=0,s.y=0,n=!1;var d=h.originalEvent,v={position:{x:a.touch_capable?d.touches[0].pageX:h.pageX,y:a.touch_capable?d.touches[0].pageY:h.pageY},offset:{x:a.touch_capable?Math.round(d.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(h.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(d.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(h.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:h.target},w=Math.abs(t.position.x-v.position.x),_=Math.abs(t.position.y-v.position.y),T={startEvnt:t,endEvnt:v,direction:c.replace("swipe",""),xAmount:w,yAmount:_,duration:v.time-t.time};i=!0,o.trigger("swipe",T).trigger(c,T)}}),o.on(a.endevent,function r(s){var p="";if((o=e(s.currentTarget)).data("callee3",r),i){var h=o.data("xthreshold"),c=o.data("ythreshold"),u=void 0!==h&&!1!==h&&parseInt(h)?parseInt(h):a.swipe_h_threshold,l=void 0!==c&&!1!==c&&parseInt(c)?parseInt(c):a.swipe_v_threshold,f=s.originalEvent,g={position:{x:a.touch_capable?f.changedTouches[0].pageX:s.pageX,y:a.touch_capable?f.changedTouches[0].pageY:s.pageY},offset:{x:a.touch_capable?Math.round(f.changedTouches[0].pageX-(o.offset()?o.offset().left:0)):Math.round(s.pageX-(o.offset()?o.offset().left:0)),y:a.touch_capable?Math.round(f.changedTouches[0].pageY-(o.offset()?o.offset().top:0)):Math.round(s.pageY-(o.offset()?o.offset().top:0))},time:Date.now(),target:s.target};t.position.y>g.position.y&&t.position.y-g.position.y>l&&(p="swipeup"),t.position.xu&&(p="swiperight"),t.position.yl&&(p="swipedown"),t.position.x>g.position.x&&t.position.x-g.position.x>u&&(p="swipeleft");var d=Math.abs(t.position.x-g.position.x),v=Math.abs(t.position.y-g.position.y),w={startEvnt:t,endEvnt:g,direction:p.replace("swipe",""),xAmount:d,yAmount:v,duration:g.time-t.time};o.trigger("swipeend",w)}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,s=e(window),p={0:!0,180:!0};if(a.orientation_support){var h=window.innerWidth||s.width(),c=window.innerHeight||s.height();i=h>c&&h-c>50,r=p[window.orientation],(i&&r||!i&&!r)&&(p={"-90":!0,90:!0})}function u(){var e=o();e!==n&&(n=e,s.trigger("orientationchange"))}e.event.special.orientationchange={setup:function(){return!a.orientation_support&&(n=o(),s.on("throttledresize",u),!0)},teardown:function(){return!a.orientation_support&&(s.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?p[window.orientation]:e&&e.clientWidth/e.clientHeight<1.1)?"portrait":"landscape"},e.event.special.throttledresize={setup:function(){e(this).on("resize",d)},teardown:function(){e(this).off("resize",d)}};var l,f,g,d=function(){f=Date.now(),(g=f-v)>=250?(v=f,e(this).trigger("throttledresize")):(l&&window.clearTimeout(l),l=window.setTimeout(u,250-g))},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,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); From ae451ac55166b4bcf6e0b918d5b884ac0eb3ca1b Mon Sep 17 00:00:00 2001 From: Philip Date: Tue, 21 Apr 2020 06:32:07 +0200 Subject: [PATCH 141/149] Rename src/jquery.mobile-events.js to src/2.0.2/jquery.mobile-events.js --- src/{ => 2.0.2}/jquery.mobile-events.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{ => 2.0.2}/jquery.mobile-events.js (100%) diff --git a/src/jquery.mobile-events.js b/src/2.0.2/jquery.mobile-events.js similarity index 100% rename from src/jquery.mobile-events.js rename to src/2.0.2/jquery.mobile-events.js From 588ba24c82e9c41d9fe064d08cb6f967c4a9170a Mon Sep 17 00:00:00 2001 From: Philip Date: Tue, 21 Apr 2020 06:32:35 +0200 Subject: [PATCH 142/149] Rename src/jquery.mobile-events.min.js to src/2.0.2/jquery.mobile-events.min.js --- src/{ => 2.0.2}/jquery.mobile-events.min.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{ => 2.0.2}/jquery.mobile-events.min.js (100%) diff --git a/src/jquery.mobile-events.min.js b/src/2.0.2/jquery.mobile-events.min.js similarity index 100% rename from src/jquery.mobile-events.min.js rename to src/2.0.2/jquery.mobile-events.min.js From 3af1ef9bbe5b54ddd39f94a9dfd098788fa63ea3 Mon Sep 17 00:00:00 2001 From: Philip Date: Tue, 21 Apr 2020 06:33:18 +0200 Subject: [PATCH 143/149] Create jquery.mobile-events.js --- src/jquery.mobile-events.js | 931 ++++++++++++++++++++++++++++++++++++ 1 file changed, 931 insertions(+) create mode 100644 src/jquery.mobile-events.js diff --git a/src/jquery.mobile-events.js b/src/jquery.mobile-events.js new file mode 100644 index 0000000..1e11ee7 --- /dev/null +++ b/src/jquery.mobile-events.js @@ -0,0 +1,931 @@ +/*! + * 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 (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 (originalCoord.x > finalCoord.x && (originalCoord.x - finalCoord.x > h_threshold)) { + swipedir = 'swipeleft'; + } + 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 + }; + + // 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); + + 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)); From fbcd26c3c1714f8a3402e7a75254b12f1e545ccc Mon Sep 17 00:00:00 2001 From: Philip Date: Tue, 21 Apr 2020 06:33:53 +0200 Subject: [PATCH 144/149] Create jquery.mobile-events.min.js --- src/jquery.mobile-events.min.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/jquery.mobile-events.min.js diff --git a/src/jquery.mobile-events.min.js b/src/jquery.mobile-events.min.js new file mode 100644 index 0000000..6ac0a92 --- /dev/null +++ b/src/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,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); From f2069aa2f4c1a58703b870719ea997b5538d140b Mon Sep 17 00:00:00 2001 From: Ben Major Date: Wed, 22 Apr 2020 09:49:04 +0100 Subject: [PATCH 145/149] 2.0.2 release updates --- README.md | 18 +++++------------- bower.json | 2 +- package.json | 2 +- 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 7d39bb4..bbfd2e2 100644 --- a/README.md +++ b/README.md @@ -23,49 +23,41 @@ 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.2** (2020-04-21) + + Fix for binding events to `document` and `window`. ++ Update NPM repo so that latest releases are detected. + **Version 2.0.1** (2019-12-02) + Fix for bug [#156](https://github.com/benmajor/jQuery-Touch-Events/issues/156) - + **Version 2.0.0** (2018-05-20) + Added two-finger tap event (`tap2`). + Added two-finger taphold event (`taphold2`). + Added setter functions to easily set thresholds globally. + Fixed a bug where the offset position of elements was sometimes incorrect. + Other minor bug fixes. - + **Version 1.0.9** (2017-06-07) + Fixes a bug where binding to multiple elements with the same selector caused issues with `doubletap`. - + **Version 1.0.8** (2017-02-01) + Fixes a bug where certain instances of Chrome on touch devices did not correctly fire events. + Added license info to minified script. - + **Version 1.0.7** (2017-02-01) + Added threshold support for `taphold` - + **Version 1.0.6** (2016-11-16) + Added slop factor for `singletap` + Fixed a bug where `offset()` was sometimes called on `null` (instead of `window`). - + **Version 1.0.5** (2015-11-13) + Fixed a major bug where the reported `offset` position of events was incorrect when inside of a parent element. - + **Version 1.0.4** (2015-11-12) + Regressed from `MSPointerEvent` for compatibility with IE11 and Edge + Removed multi-name event for `tap`. - + **Version 1.0.3** (2015-11-10) + Numerous minor bug fixes + Fixes a bug where the offset position returned by events relative to the **current target**, not the bound target. - + **Version 1.0.2** (2015-08-26) + Numerous bug fixes + Added support for `MSPointerEvent` - + **Version 1.0.1** (2015-08-21) + Added Bower package for easy install + Fixed a bug where Internet Explorer under Windows Mobile did not trigger certain events. - + **Version 1.0.0** (2015-07-18) + The library officially entered 1.0.0 after minor bug fixes and final adjustments. @@ -97,7 +89,7 @@ $ bower install jquery-touch-events jQuery Touch Events can also be installed using NPM as follows: ``` -$ npm install git+https://github.com/benmajor/jQuery-Touch-Events.git +$ npm i @benmajor/jquery-touch-events ``` ### 3. Usage: @@ -123,7 +115,7 @@ $('#myElement').trigger('tap'); **Removing the event:** ``` $('#myElement').off('tap', handler); -``` +``` **Using method wrapper:** ``` diff --git a/bower.json b/bower.json index 5b0f9e7..8676901 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jquery-touch-events", - "version": "2.0.1", + "version": "2.0.2", "main": "src/jquery.mobile-events.js", "ignore": [ "bower.json" diff --git a/package.json b/package.json index 315a2d1..622a6bd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@benmajor/jquery-touch-events", - "version": "2.0.1", + "version": "2.0.2", "description": "Polyfill to remove click delays and unify pointer device events.", "main": "src/jquery.mobile-events.js", "scripts": { From 5db124d1c0ec506d48ff76789e471538d5f26497 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Thu, 23 Apr 2020 18:53:29 +0100 Subject: [PATCH 146/149] 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 From 9b3aa4cfd13dade5a26981126ab4412cef363ed3 Mon Sep 17 00:00:00 2001 From: Philip Date: Wed, 18 Nov 2020 01:39:58 +0100 Subject: [PATCH 147/149] Wrong function attribute name --- src/jquery.mobile-events.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/jquery.mobile-events.js b/src/jquery.mobile-events.js index 627afdd..341fce2 100644 --- a/src/jquery.mobile-events.js +++ b/src/jquery.mobile-events.js @@ -90,8 +90,8 @@ }; // 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'); } + $.touch.setTapRange = function( threshold ) { + if( typeof threshold !== 'number' ) { throw new Error('Ranger parameter must be a type of number'); } settings.tap_pixel_range = threshold; }; @@ -937,4 +937,4 @@ }; }); -}(jQuery)); \ No newline at end of file +}(jQuery)); From ead9fa8504af288fab3ae088b8ee5213cde27f9a Mon Sep 17 00:00:00 2001 From: Philip Date: Wed, 18 Nov 2020 01:42:45 +0100 Subject: [PATCH 148/149] Wrong function attribute name --- src/jquery.mobile-events.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jquery.mobile-events.min.js b/src/jquery.mobile-events.min.js index 1a8870d..3b76e55 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,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 +"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=e},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); From fd11720fcfa89ecd5666e5de9e60f9dff684e8b5 Mon Sep 17 00:00:00 2001 From: Ben Major Date: Thu, 6 Apr 2023 08:57:09 +0100 Subject: [PATCH 149/149] Update NPM installation instructions Closes https://github.com/benmajor/jQuery-Touch-Events/issues/167 --- README.md | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 22e29bc..26599ed 100644 --- a/README.md +++ b/README.md @@ -72,13 +72,13 @@ jQuery Touch Events, as the name suggests, require only the jQuery library (vers Once you have downloaded the JS files from the master branch, you should include them using the following code: -``` +```html ``` The awesome guys over at [cdnjs](https://cdnjs.com/libraries/jquery-touch-events) have kindly added the library to their CDN so you can include it as follows directly into your application: -``` +```html ``` @@ -94,6 +94,12 @@ jQuery Touch Events can also be installed using NPM as follows: $ npm i @benmajor/jquery-touch-events ``` +If you are installing the library via NPM, after running the `npm i` command above, you'll also need to ensure that you import the modules into you project files wherever you wish to use the events. Place the following line alongside your other imports: + +```js +import "@benmajor/jquery-touch-events"; +``` + ### 3. Usage: All of the events outlined above have been written using jQuery's ``event.special`` object, and so can be used in conjunction with jQuery's event handling functions, as well as shortcut wrappers. As a result, all of the events that are supported by this library may be handled using any of jQuery's own event-specific methods, such as `on()` and `one()`. @@ -103,24 +109,24 @@ The following code snippets showcase some basic usage with jQuery: When binding, you should use jQuery's `on()` function as follows (avoid the use of `live()` and `bind()` as these are now deprecated and will be removed from future versions of jQuery). -``` +```js $('#myElement').on('tap', function(e) { console.log('User tapped #myElement'); }); ``` **Triggering the event:** -``` +```js $('#myElement').trigger('tap'); ``` **Removing the event:** -``` +```js $('#myElement').off('tap', handler); ``` **Using method wrapper:** -``` +```js $('#myElement').tap(function(e) { console.log('User tapped #myElement'); }); @@ -128,7 +134,7 @@ $('#myElement').tap(function(e) { **Method chaining:** Chaining has also been preserved, so you can easily use these events in conjunction with other jQuery functions, or attach multiple events in a single, chained LOC: -``` +```js $('#myElement').singletap(function() { console.log('singletap'); }).doubletap(function() { @@ -176,7 +182,7 @@ This event is triggered when the orientation of the device is changed. Please no ## 5. Callback Data: Each event now features a second argument that can be passed to the specified callback function. This argument includes some basic data relating specifically to the event, and can be accessed as a standard JavaScript object. To hook into this parameter, you should use the following code: -``` +```js $(element).swipeend(function(e, touch) { }); ```