Best JavaScript code snippet using playwright-internal
jquery.gestures.js
Source:jquery.gestures.js  
1(function(jQuery, $, window){2                                          /*jslint undef: true, browser: true, continue: true, eqeq: true, vars: true, forin: true, white: true, newcap: false, nomen: true, plusplus: true, maxerr: 50, indent: 4 */3/**4 * jGestures: a jQuery plugin for gesture events5 * Copyright 2010-2011 Neue Digitale / Razorfish GmbH6 * Copyright 2011-2012, Razorfish GmbH7 *8 * Licensed under the Apache License, Version 2.0 (the "License");9 * you may not use this file except in compliance with the License.10 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.011 * Unless required by applicable law or agreed to in writing, software12 * distributed under the License is distributed on an "AS IS" BASIS,13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.14 * See the License for the specific language governing permissions and15 * limitations under the License.16 *17 * @fileOverview18 * Razorfish GmbH javascript library: add touch events such as 'pinch',19 * 'rotate', 'swipe', 'tap' and 'orientationchange' on capable user agents.20 * For incapable devices there's a basic event substitution: a "tapone" event21 * can be triggered by "clicking", a "swipeone" by performing a swipe-ish22 * gesture using the mouse (buttondown - mousemove - buttonup).23 *24 * This is still a beta version, bugfixes and improvements appreciated.25 *26 * @author martin.krause@razorfish.de27 * @version 0.90-shake28 *29 * @requires30 * jQuery JavaScript Library v1.4.2 - http://jquery.com/31 *	Copyright 2010, John Resig32 *	Dual licensed under the MIT or GPL Version 2 licenses.33 *	http://jquery.org/license34 *35 * @example	jQuery('#swipe').bind('swipeone',eventHandler);36 *37 * Notification on native events:38 * On every native touchstart, touchend, gesturestart and gestureend-event,39 * jgestures triggers a corresponding custom event40 * ('jGestures.touchstart', 'jGestures.touchend;start', 'jGestures.touchend;processed',41 * 'jGestures.gesturestart', 'jGestures.gestureend;start', 'jGestures.gestureend;processed') on the event-element.42 * The  eventhandler's second argument represents the original touch event (yes: including all touchpoints).43 * Use this if you need very detailed control e.g. kinetic scrolling or implementing additional gestures.44 *45 * Every jGesture-eventhandler receives a custom object as second argument46 * containing the original event (originalEvent property) and processed47 * information (such as delta values and timesptamp).48 * Example:{49 *				type: eventtype e.g. "swipe","pinch",50 *				originalEvent: {DOM-Event},51 *				// default: just one entry on the delta-array - the first touchpoint52 *				// the first touchpoint is the reference point for every gesture,53 *				// because moving touchpoints in various directions would result in54 *				// a gesture.55 *				// delta and direction details are just provided for touch not for gesture / motion events56 *				delta : [57 *					{58 *						lastX:{Number} , // x-axis: relative to the last touchevent (e.g. touchmove!)59 *						lastY:{Number}, // y-axis: relative to the last touchevent (e.g. touchmove!)60 *						moved: {Number},  // distance: relative to the original touchpoint61 *						startX: {Number} , // relative to the original touchpoint62 *						startY: {Number} ,// relative to the original touchpoint63 *					} ],64 *				// based on the first touchpoint65 *				direction : { // relative to the last touchevent (e.g. touchmove!)66 *					vector: {Number}, // -1|+1, indicates the direction if necessary(pinch/rotate)67 *					orientation: {Number} // window.orientation: -90,0,90,180 || null (window.orienntation)68 *					lastX : {Number}, // -1,0,+1 || null (orientationchange) // relative to the last touchevent (e.g. touchmove!)69 *					lastY : {Number}, // -1,0,+1 || null (orientationchange)// relative to the last touchevent (e.g. touchmove!)70 *					startX: {Number} , // relative to the original touchpoint71 *					startY: {Number} ,// relative to the original touchpoint72 *				},73 *				rotation: {Number} || null, // gestureonly: amount of rotation relative to the current position NOT the original74 *				scale: {Number} || null, // gestureonly: amount of scaling relative to the current position NOT the original75 *				duration: {Number}, // ms: relative to the original touchpoint76 *				description : {String} // details as String: {TYPE *}:{TOUCHES 1|2|3|4}:{X-AXIS 'right'|'left'|'steady'}:{Y-AXIS 'down'|'up'|'steady'} e.g. "swipe:1:left:steady" relative to the last touchpoint77 *			};78 *79 * Available jGesture-events can be grouped into:80 *81 *82 * Device events:83 *	The jGesture-Events in this group are triggered by the device.84 *85 * @event 'orientationchange'86 *		The device is turned clockwise or counterclockwise. This event is triggered87 *		by the device and might use an internal gyroscope.88 *	obj.description:89 *		orientationchange:landscape:clockwise:-9090 *		orientationchange:portrait:default:091 *		orientationchange:landscape:counterclockwise|portrait:9092 *		orientationchange:portrait:upsidedown:18093 *94 *95 * Move events:96 *	The jGesture-Events in this group are triggered during the touch/gesture97 *	execution whenever a touchpoint changes.98 *	In contrast to touchend/gestureend-events which are triggered after99 *	the touch/gesture has completed.100 *101 * @event 'pinch'102 *		Is triggered during a pinch gesture (two fingers moving away from or103 *		towards each other).104 *	obj.description:105 *		pinch:-1:close106 *		pinch:+1:open107 *108 * @event 'rotate'109 *		Is triggered during a rotation gesture (two fingers rotating clockwise110 *		or counterclockwise).111 *	obj.description:112 *		rotate:-1:counterclockwise113 *		rotate:+1:+clockwise114 *115 * @event 'swipemove'116 *		Is triggered during a swipe move gesture (finger(s) being moved around117 *		the device, e.g. dragging)118 *	obj.description:119 *		swipemove:1:left:down120 *		swipemove:1:left:up121 *		swipemove:1:left:steady122 *		swipemove:1:right:down123 *		swipemove:1:right:up124 *		swipemove:1:right:steady125 *		swipemove:2:left:down126 *		swipemove:2:left:up127 *		swipemove:2:left:steady128 *		swipemove:2:right:down129 *		swipemove:2:right:up130 *		swipemove:2:right:steady131 *		swipemove:2:left:down132 *		swipemove:3:left:up133 *		swipemove:3:left:steady134 *		swipemove:3:right:down135 *		swipemove:3:right:up136 *		swipemove:3:right:steady137 *		swipemove:3:left:down138 *		swipemove:4:left:up139 *		swipemove:4:left:steady140 *		swipemove:4:right:down141 *		swipemove:4:right:up142 *		swipemove:4:right:steady143 *144 *145 * Toucheend events:146 *	The jGesture-Events in this group are triggered after the touch/gesture147 *	has completed.148 *	In contrast to touchmove-events which are triggered during the touch/gesture149 *	execution whenever a touchpoint changes.150 *151 * @event 'swipeone'152 *		Is triggered after a swipe move gesture with one touchpoint (one finger153 *		was moved around the device)154 *	obj.description:155 *		swipeone:1:left:down156 *		swipeone:1:left:up157 *		swipeone:1:left:steady158 *		swipeone:1:right:down159 *		swipeone:1:right:up160 *		swipeone:1:right:steady161 *162 * @event 'swipetwo'163 *		Is triggered after a swipe move gesture with two touchpoints (two fingers164 *		were moved around the device)165 *	obj.description:166 *		swipetwo:2:left:down167 *		swipetwo:2:left:up168 *		swipetwo:2:left:steady169 *		swipetwo:2:right:down170 *		swipetwo:2:right:up171 *		swipetwo:2:right:steady172 *173 * @event 'swipethree'174 *		Is triggered after a swipe move gesture with three touchpoints (three175 *		fingers were moved around the device)176 *	obj.description:177 *		swipethree:3:left:down178 *		swipethree:3:left:up179 *		swipethree:3:left:steady180 *		swipethree:3:right:down181 *		swipethree:3:right:up182 *		swipethree:3:right:steady183 *184 * @event 'swipefour'185 *		Is triggered after a swipe move gesture with four touchpoints (four186 *		fingers were moved around the device)187 *	obj.description:188 *		swipefour:4:left:down189 *		swipefour:4:left:up190 *		swipefour:4:left:steady191 *		swipefour:4:right:down192 *		swipefour:4:right:up193 *		swipefour:4:right:steady194 *195 *196 * @event 'swipeup'197 *		Is triggered after an  strict upwards swipe move gesture198 *	obj.description:199 *		swipe:1:steady:up200 *		swipe:2:steady:up201 *		swipe:3:steady:up202 *		swipe:4:steady:up203 *204 * @event 'swiperightup'205 *		Is triggered after a rightwards and upwards swipe move gesture206 *	obj.description:207 *		swipe:1:right:up208 *		swipe:2:right:up209 *		swipe:3:right:up210 *		swipe:4:right:up211 *212 * @event 'swiperight'213 *		Is triggered after a  strict rightwards swipe move gesture214 *	obj.description:215 *		swipe:1:right:steady216 *		swipe:2:right:steady217 *		swipe:3:right:steady218 *		swipe:4:right:steady219 *220 * @event 'swiperightdown'221 *		Is triggered after a rightwards and downwards swipe move gesture222 *	obj.description:223 *		swipe:1:right:down224 *		swipe:2:right:down225 *		swipe:3:right:down226 *		swipe:4:right:down227 *228 * @event 'swipedown'229 *		Is triggered after a  strict downwards swipe move gesture230 *	obj.description:231 *		swipe:1:steady:down232 *		swipe:2:steady:down233 *		swipe:3:steady:down234 *		swipe:4:steady:down235 *236 * @event 'swipeleftdown'237 *		Is triggered after a leftwards and downwards swipe move gesture238 *	obj.description:239 *		swipe:1:left:down240 *		swipe:2:left:down241 *		swipe:3:left:down242 *		swipe:4:left:down243 *244 * @event 'swipeleft'245 *		Is triggered after a strict leftwards swipe move gesture246 *	obj.description:247 *		swipe:1:left:steady248 *		swipe:2:left:steady249 *		swipe:3:left:steady250 *		swipe:4:left:steady251 *252 * @event 'swipeleftup'253 *		Is triggered after a leftwards and upwards swipe move gesture254 *	obj.description:255 *		swipe:1:left:up256 *		swipe:2:left:up257 *		swipe:3:left:up258 *		swipe:4:left:up259 *260 * @event 'tapone'261 *		Is triggered after a single (one finger) tap gesture262 *	obj.description:263 *		tapone264 *265 * @event 'taptwo'266 *		Is triggered after a double (two finger) tap gesture267 *	obj.description:268 *		taptwo269 * *270 * @event 'tapthree'271 *		Is triggered after a tripple (three finger) tap gesture272 *	obj.description:273 *		tapthree274 *275 *276 * Gestureend events:277 *	A gesture is an interpretation of different touchpoints.278 *	The jGesture-Events in this group are triggered when a gesture has finished279 *	and the touchpoints are removed from the device.280 *281 * @event 'pinchopen'282 *		Is triggered when a pinchopen gesture (two fingers moving away from each283 *		other) occured and the touchpoints (fingers) are removed the device.284 *	obj.description:285 *		pinch:+1:open286 *287 * @event 'pinchclose'288 *		Is triggered when a pinchclose gesture (two fingers moving towards each289 *		other) occured and the touchpoints (fingers) are removed the device.290 *	obj.description:291 *		pinch:-1:close292 *293 * @event 'rotatecw'294 *		Is triggered when a clockwise rotation gesture (two fingers rotating295 *		clockwise) occured and the touchpoints (fingers) are removed the device.296 *	obj.description:297 *		rotate:+1:+clockwise298 *299 * @event 'rotateccw'300 *		Is triggered when a counterclockwise rotation gesture (two fingers301 *		rotating counterclockwise) occured and the touchpoints (fingers) are302 *		removed the device.303 *	obj.description:304 *		rotate:-1:+counterclockwise305 *306 *307 * Motion events:308 *  A "motion event" is an interpretation of changes in space, e.g. a "shaking motion"309 *  consists of a specified number of acceleration changes in a given interval.310 * For understanding "directions", place your mobile device on a table with the bottom311 * (home button) close to you:312 *  - x-axis: horizontal left / right313 *  - y-axis: horizontal front / back (through the home button)314 *  - z-axis: vertical through your device315 *316 *  Note: Devicemotion / deviceorientation don't send custom event (such as: jGestures.touchstart).317 *  Note: Devicemotion should be bound on the "window-element" - because the whole device moves318 *319 * @event 'shake'320 *		Is triggered when a shaking motion is detected321 *	obj.description:322 *		shake:leftright:x-axisfrontback:y-axis:updown:z-axis323 *324 * @event 'shakefrontback'325 *		Is triggered when a shaking motion is detected and the gesture can be interpreted as a mainly front-back movement.326  *	obj.description:327 *		shakefrontback:shakefrontback:y-axis328 *329 * @event 'shakeleftright'330 *		Is triggered when a shaking motion is detected and the gesture can be interpreted as a mainly left-right movement.331 *		Additional major movements are mentioned in the obj.description.332 *	obj.description:333 *		shakeleftright:leftright:x-axis334 *335 * @event 'shakeupdown'336 *		Is triggered when a shaking motion is detected and the gesture can be interpreted as a mainly up-down movement.337 *		Additional major movements are mentioned in the obj.description.338 *	obj.description:339 *		shake:shakeupdown:updown:z-axis340 *341 * @example342 *		.bind( eventType, [ eventData ], handler(eventObject) )343 * jQuery('body').bind('tapone',function(){alert(arguments[1].description);})344 *345 */346 (function($) {347	/**348	* General thresholds.349	*/350	// @TODO: move to $...defaults351	// @TODO: shake to defaults freeze etc352	// change of x deg in y ms353	$.jGestures = {};354	$.jGestures.defaults = {};355	$.jGestures.defaults.thresholdShake =  {356		requiredShakes : 10,357		freezeShakes: 100,358		frontback : {359			sensitivity: 10360		 },361		leftright : {362			sensitivity: 10363		},364		updown : {365			sensitivity: 10366		}367	};368	$.jGestures.defaults.thresholdPinchopen = 0.05;369	$.jGestures.defaults.thresholdPinchmove = 0.05;370	$.jGestures.defaults.thresholdPinch = 0.05;371	$.jGestures.defaults.thresholdPinchclose = 0.05;372	$.jGestures.defaults.thresholdRotatecw = 5; //deg373	$.jGestures.defaults.thresholdRotateccw = 5; // deg374	// a tap becomes a swipe if x/y values changes are above this threshold375	$.jGestures.defaults.thresholdMove = 20;376	$.jGestures.defaults.thresholdSwipe = 100;377	// get capable user agents378	$.jGestures.data = {};379	$.jGestures.data.capableDevicesInUserAgentString = ['iPad','iPhone','iPod','Mobile Safari']; // basic functionality such as swipe, pinch, rotate, tap should work on every mobile safari, e.g. GalaxyTab380	$.jGestures.data.hasGestures = (function () { var _i; for(_i = 0; _i < $.jGestures.data.capableDevicesInUserAgentString.length; _i++ ) {  if (navigator.userAgent.indexOf($.jGestures.data.capableDevicesInUserAgentString[_i]) !== -1 ) {return true;} } return false; } )();381	$.hasGestures = $.jGestures.data.hasGestures;382	$.jGestures.events = {383		touchstart : 'jGestures.touchstart',384		touchendStart: 'jGestures.touchend;start',385		touchendProcessed: 'jGestures.touchend;processed',386		gesturestart: 'jGestures.gesturestart',387		gestureendStart: 'jGestures.gestureend;start',388		gestureendProcessed: 'jGestures.gestureend;processed'389	};390	jQuery391		.each({392			// "first domevent necessary"_"touch event+counter" : "exposed as"393			// event: orientationchange394			orientationchange_orientationchange01: "orientationchange",395			// event: gestures396			gestureend_pinchopen01: "pinchopen",397			gestureend_pinchclose01: "pinchclose",398			gestureend_rotatecw01 : 'rotatecw',399			gestureend_rotateccw01 : 'rotateccw',400			// move events401			gesturechange_pinch01: 'pinch',402			gesturechange_rotate01: 'rotate',403			touchstart_swipe13: 'swipemove',404			// event: touches405			touchstart_swipe01: "swipeone",406			touchstart_swipe02: "swipetwo",407			touchstart_swipe03: "swipethree",408			touchstart_swipe04: "swipefour",409			touchstart_swipe05: 'swipeup',410			touchstart_swipe06: 'swiperightup',411			touchstart_swipe07: 'swiperight',412			touchstart_swipe08: 'swiperightdown',413			touchstart_swipe09: 'swipedown',414			touchstart_swipe10: 'swipeleftdown',415			touchstart_swipe11: 'swipeleft',416			touchstart_swipe12: 'swipeleftup',417			touchstart_tap01: 'tapone',418			touchstart_tap02: 'taptwo',419			touchstart_tap03: 'tapthree',420			touchstart_tap04: 'tapfour',421			devicemotion_shake01: 'shake',422			devicemotion_shake02: 'shakefrontback',423			devicemotion_shake03: 'shakeleftright',424			devicemotion_shake04: 'shakeupdown'425		},426		/**427		* Add gesture events inside the jQuery.event.special namespace428		*/429		function( sInternal_, sPublicFN_ ) {430			// add as funciton to jQuery.event.special.sPublicFN_431			jQuery.event.special[ sPublicFN_ ] = {432				/**433				* When the first event handler is bound, jQuery executes the setup function.434				* This plugin just uses one eventhandler per element, regardless of the number of bound events.435				* All Events are stored internally as properties on the dom-element using the $.data api.436				* The setup-function adds the eventlistener, acting as a proxy function for the internal events.437				* $.data.ojQueryGestures[_sDOMEvent ('tap') ] = {Boolean}438				* @return {Void}439				*/440				setup: function () {441					// split the arguments to necessary controll arguements442					var _aSplit = sInternal_.split('_');443					var _sDOMEvent = _aSplit[0]; //444					// get the associated gesture event and strip the counter: necessary for distinguisihng similliar events such as tapone-tapfour445					var _sGestureEvent = _aSplit[1].slice(0,_aSplit[1].length-2);446					var _$element = jQuery(this);447					var _oDatajQueryGestures ;448					var oObj;449					// bind the event handler on the first $.bind() for a gestureend-event, set marker450					if (!_$element.data('ojQueryGestures') || !_$element.data('ojQueryGestures')[_sDOMEvent])  {451						// setup pseudo event452						_oDatajQueryGestures = _$element.data('ojQueryGestures') || {};453						oObj = {};454						// marker for:  domEvent being set on this element455						// e.g.: $.data.oGestureInternals['touchstart'] = true;456						// since they're grouped, i'm just marking the first one being added457						oObj[_sDOMEvent] = true;458						$.extend(true,_oDatajQueryGestures,oObj);459						_$element.data('ojQueryGestures' ,_oDatajQueryGestures);460						// add gesture events461						if($.hasGestures) {462							switch(_sGestureEvent) {463								// event: orientationchange464								case 'orientationchange':465									_$element.get(0).addEventListener('orientationchange', _onOrientationchange, false);466								break;467								// event:468								// - shake469								// - tilt470								case 'shake':471								case 'shakefrontback':472								case 'shakeleftright':473								case 'shakeupdown':474								case 'tilt':475									//$.hasGyroscope = true //!window.DeviceOrientationEvent;476									//_$element.get(0).addEventListener('devicemotion', _onDevicemotion, false);477									//_$element.get(0).addEventListener('deviceorientation', _onDeviceorientation, false);478									_$element.get(0).addEventListener('devicemotion', _onDevicemotion, false);479								break;480								// event:481								// - touchstart482								// - touchmove483								// - touchend484								case 'tap':485								case 'swipe':486								case 'swipeup':487								case 'swiperightup':488								case 'swiperight':489								case 'swiperightdown':490								case 'swipedown':491								case 'swipeleftdown':492								case 'swipeleft':493									_$element.get(0).addEventListener('touchstart', _onTouchstart, false);494								break;495								// event: gestureend496								case 'pinchopen':497								case 'pinchclose' :498								case 'rotatecw' :499								case 'rotateccw' :500									_$element.get(0).addEventListener('gesturestart', _onGesturestart, false);501									_$element.get(0).addEventListener('gestureend', _onGestureend, false);502								break;503								// event: gesturechange504								case 'pinch':505								case 'rotate':506									_$element.get(0).addEventListener('gesturestart', _onGesturestart, false);507									_$element.get(0).addEventListener('gesturechange', _onGesturechange, false);508								break;509							}510						}511						// create substitute for gesture events512						else {513							switch(_sGestureEvent) {514								// event substitutes:515								// - touchstart: mousedown516								// - touchmove: none517								// - touchend: mouseup518								case 'tap':519								case 'swipe':520									// _$element.get(0).addEventListener('mousedown', _onTouchstart, false);521									 _$element.bind('mousedown', _onTouchstart);522								break;523								// no substitution524								case 'orientationchange':525								case 'pinchopen':526								case 'pinchclose' :527								case 'rotatecw' :528								case 'rotateccw' :529								case 'pinch':530								case 'rotate':531								case 'shake':532								case 'tilt':533								break;534							}535						}536					}537					return false;538				},539				/**540				* For every $.bind(GESTURE) the add-function will be called.541				* Instead of binding an actual eventlister, the event is stored as $.data on the element.542				* The handler will be triggered using $.triggerHandler(GESTURE) if the internal543				* eventhandler (proxy being bound on setup()) detects a GESTURE event544				* @param {Object} event_ jQuery-Event-Object being passed by $.bind()545				* @return {Void}546				*/547				add : function(event_) {548					// add pseudo event: properties on $.data549					var _$element = jQuery(this);550					var _oDatajQueryGestures = _$element.data('ojQueryGestures');551//					_oDatajQueryGestures[event_.type] = { 'originalType' : event_.type , 'threshold' : event_.data.threshold, 'preventDefault' : event_.data.preventDefault } ;552					_oDatajQueryGestures[event_.type] = { 'originalType' : event_.type } ;553					return false;554				},555				/**556				* For every $.unbind(GESTURE) the remove-function will be called.557				* Instead of removing the actual eventlister, the event is removed from $.data on the element.558				* @param {Object} event_ jQuery-Event-Object being passed by $.bind()559				* @return {Void}560				*/561				remove : function(event_) {562					// remove pseudo event: properties on $.data563					var _$element = jQuery(this);564					var _oDatajQueryGestures = _$element.data('ojQueryGestures');565					_oDatajQueryGestures[event_.type] = false;566					_$element.data('ojQueryGestures' ,_oDatajQueryGestures );567					return false;568				},569				/**570				* The last $.unbind()-call on the domElement triggers the teardown function571				* removing the eventlistener572				* @return {Void}573				*/574				// @TODO: maybe rework teardown to work with event type?!575				teardown : function() {576					// split the arguments to necessary controll arguements577					var _aSplit = sInternal_.split('_');578					var _sDOMEvent = _aSplit[0]; //579					// get the associated gesture event and strip the counter: necessary for distinguisihng similliar events such as tapone-tapfour580					var _sGestureEvent = _aSplit[1].slice(0,_aSplit[1].length-2);581					var _$element = jQuery(this);582					var _oDatajQueryGestures;583					var oObj;584					// bind the event handler on the first $.bind() for a gestureend-event, set marker585					if (!_$element.data('ojQueryGestures') || !_$element.data('ojQueryGestures')[_sDOMEvent])  {586						// setup pseudo event587						_oDatajQueryGestures = _$element.data('ojQueryGestures') || {};588						oObj = {};589						// remove marker for:  domEvent being set on this element590						oObj[_sDOMEvent] = false;591						$.extend(true,_oDatajQueryGestures,oObj);592						_$element.data('ojQueryGestures' ,_oDatajQueryGestures);593						// remove gesture events594						if($.hasGestures) {595							switch(_sGestureEvent) {596								// event: orientationchange597								case 'orientationchange':598									_$element.get(0).removeEventListener('orientationchange', _onOrientationchange, false);599								break;600								case 'shake':601								case 'shakefrontback':602								case 'shakeleftright':603								case 'shakeupdown':604								case 'tilt':605									_$element.get(0).removeEventListener('devicemotion', _onDevicemotion, false);606								break;607								// event :608								// - touchstart609								// - touchmove610								// - touchend611								case 'tap':612								case 'swipe':613								case 'swipeup':614								case 'swiperightup':615								case 'swiperight':616								case 'swiperightdown':617								case 'swipedown':618								case 'swipeleftdown':619								case 'swipeleft':620								case 'swipeleftup':621									_$element.get(0).removeEventListener('touchstart', _onTouchstart, false);622									_$element.get(0).removeEventListener('touchmove', _onTouchmove, false);623									_$element.get(0).removeEventListener('touchend', _onTouchend, false);624								break;625								// event: gestureend626								case 'pinchopen':627								case 'pinchclose' :628								case 'rotatecw' :629								case 'rotateccw' :630									_$element.get(0).removeEventListener('gesturestart', _onGesturestart, false);631									_$element.get(0).removeEventListener('gestureend', _onGestureend, false);632								break;633								// event: gesturechange634								case 'pinch':635								case 'rotate':636									_$element.get(0).removeEventListener('gesturestart', _onGesturestart, false);637									_$element.get(0).removeEventListener('gesturechange', _onGesturechange, false);638								break;639							}640						}641						// remove substitute for gesture events642						else {643							switch(_sGestureEvent) {644								// event substitutes:645								// - touchstart: mousedown646								// - touchmove: none647								// - touchend: mouseup648								case 'tap':649								case 'swipe':650//									_$element.get(0).removeEventListener('mousedown', _onTouchstart, false);651//									_$element.get(0).removeEventListener('mousemove', _onTouchmove, false);652//									_$element.get(0).removeEventListener('mouseup', _onTouchend, false);653									_$element.unbind('mousedown', _onTouchstart);654									_$element.unbind('mousemove', _onTouchmove);655									_$element.unbind('mouseup', _onTouchend);656								break;657								// no substitution658								case 'orientationchange':659								case 'pinchopen':660								case 'pinchclose' :661								case 'rotatecw' :662								case 'rotateccw' :663								case 'pinch':664								case 'rotate':665								case 'shake':666								case 'tilt':667								break;668							}669						}670					}671				return false;672				}673			};674		});675	/**676	* Creates the object that ist passed as second argument to the $element.triggerHandler function.677	* This object contains detailed informations about the gesture event.678	* @param {Object} oOptions_  {type: {String}, touches: {String}, deltaY: {String},deltaX : {String}, startMove: {Object}, event:{DOM-Event}, timestamp:{String},vector: {Number}}679	* @example _createOptions (680	*				{681	*					type: 'swipemove',682	*					touches: '1',683	*					deltaY: _iDeltaY,684	*					deltaX : _iDeltaX,685	*					startMove: _oDatajQueryGestures.oStartTouch,686	*					event:event_,687	*					timestamp:_oEventData.timestamp,688	*					vector: -1689	*				}690	*			);691	* @returns {Object}692	*			{693	*				type: eventtype e.g. "swipe","pinch",694	*				originalEvent: {DOM-Event},695	*				// default: just one entry on the delta-array - the first touchpoint696	*				// the first touchpoint is the reference point for every gesture,697	*				// because moving touchpoints in various directions would result in698	*				// a gesture.699	*				// delta and direction details are just provided for touch not for gesture / motion events700	*				delta : [701	*					{702	*						lastX:{Number} , // x-axis: relative to the last touchevent (e.g. touchmove!)703	*						lastY:{Number}, // y-axis: relative to the last touchevent (e.g. touchmove!)704	*						moved: {Number},  // distance: relative to the original touchpoint705	*						startX: {Number} , // relative to the original touchpoint706	*						startY: {Number} ,// relative to the original touchpoint707	*					} ],708	*				// based on the first touchpoint709	*				direction : { // relative to the last touchevent (e.g. touchmove!)710	*					vector: {Number}, // -1|+1, indicates the direction if necessary(pinch/rotate)711	*					orientation: {Number} // window.orientation: -90,0,90,180 || null (window.orienntation)712	*					lastX : {Number}, // -1,0,+1 relative to the last touchevent (e.g. touchmove!)713	*					lastY : {Number}, // -1,0,+1 relative to the last touchevent (e.g. touchmove!)714	*					startX: {Number} , //-1,0,+1 relative to the original touchpoint715	*					startY: {Number} ,// -1,0,+1 relative to the original touchpoint716	*				},717	*				rotation: {Number} || null, // gestureonly: amount of rotation relative to the current position NOT the original718	*				scale: {Number} || null, // gestureonly: amount of scaling relative to the current position NOT the original719	*				duration: {Number}, // ms: relative to the original touchpoint720	*				description : {String} // details as String: {TYPE *}:{TOUCHES 1|2|3|4}:{X-AXIS 'right'|'left'|'steady'}:{Y-AXIS 'down'|'up'|'steady'} e.g. "swipe:1:left:steady" relative to the last touchpoint721	*			};722	*/723	function _createOptions(oOptions_) {724		// force properties725		oOptions_.startMove = (oOptions_.startMove) ? oOptions_.startMove : {startX: null,startY:null,timestamp:null}  ;726		var _iNow = new Date().getTime();727		var _oDirection;728		var _oDelta;729		// calculate touch differences730		if (oOptions_.touches) {731			// store delta values732			_oDelta = [733				{734					lastX: oOptions_.deltaX ,735					lastY: oOptions_.deltaY,736					moved: null,737					startX:  oOptions_.screenX - oOptions_.startMove.screenX ,738					startY: oOptions_.screenY - oOptions_.startMove.screenY739				}740			];741			_oDirection =  {742				vector: oOptions_.vector || null,743				orientation : window.orientation || null,744				lastX : ((_oDelta[0].lastX > 0) ? +1 : ( (_oDelta[0].lastX < 0) ? -1 : 0 ) ),745				lastY : ((_oDelta[0].lastY > 0) ? +1 : ( (_oDelta[0].lastY < 0) ? -1 : 0 ) ),746				startX : ((_oDelta[0].startX > 0) ? +1 : ( (_oDelta[0].startX < 0) ? -1 : 0 ) ),747				startY : ((_oDelta[0].startY > 0) ? +1 : ( (_oDelta[0].startY < 0) ? -1 : 0 ) )748			};749			// calculate distance traveled using the pythagorean theorem750			_oDelta[0].moved =  Math.sqrt(Math.pow(Math.abs(_oDelta[0].startX), 2) + Math.pow(Math.abs(_oDelta[0].startY), 2));751		}752		return {753			type: oOptions_.type || null,754			originalEvent: oOptions_.event || null,755			delta : _oDelta  || null,756			direction : _oDirection || { orientation : window.orientation || null, vector: oOptions_.vector || null},757			duration: (oOptions_.duration) ? oOptions_.duration : ( oOptions_.startMove.timestamp ) ? _iNow - oOptions_.timestamp : null,758			rotation: oOptions_.rotation || null,759			scale: oOptions_.scale || null,760			description : oOptions_.description || [761				oOptions_.type,762				':',763				oOptions_.touches,764				':',765				((_oDelta[0].lastX != 0) ? ((_oDelta[0].lastX > 0) ? 'right' : 'left') : 'steady'),766				':',767				((_oDelta[0].lastY != 0) ? ( (_oDelta[0].lastY > 0) ? 'down' : 'up') :'steady')768				].join('')769		};770	}771	/**772	* DOM-event handlers773	*/774	/**775	* Handler: orientationchange776	* Triggers the bound orientationchange handler on the window element777	* The "orientationchange" handler will receive an object with additional information778	* about the event.779	*  {780	*	direction : {781	*		orientation: {-90|0|90|180}782	*	},783	*	description : [784	*		'orientationchange:{landscape:clockwise:|portrait:default|landscape:counterclockwise|portrait:upsidedown}:{-90|0|90|180}' // e.g. 'orientation:landscape:clockwise:-90785	*	}786	* @param {DOM-Event} event_787	* @return {Void}788	*/789	function _onOrientationchange(event_) {790		// window.orientation: -90,0,90,180791		var _aDict = ['landscape:clockwise:','portrait:default:','landscape:counterclockwise:','portrait:upsidedown:'];792		$(window).triggerHandler('orientationchange',793			{794				direction : {orientation: window.orientation},795				description : [796					'orientationchange:',797					_aDict[( (window.orientation / 90) +1)],798					window.orientation799					].join('')800			});801	}802	/**803	* Handler: devicemotion804	* Calculates "motion events" such as shake, tilt, wiggle by observing "changes in space"805	* For understanding "directions", place your mobile device on a table with the bottom806	* (home button) close to you:807	*  - x-axis: horizontal left / right808	*  - y-axis: horizontal front / back (through the home button)809	*  - z-axis: vertical through your device810	* @param {DOM-Event} event_811	* @returns {Object}812	*			{813	*				type: eventtype e.g. "shake",814	*				originalEvent: {DOM-Event},815	*				// delta and direction details are just provided for touch not for gesture / motion events816	*				delta : null,817	*				direction :{818	*					vector: null,819	*					orientation: -90,0,90,180 || null (window.orienntation)820	*				}821	*				rotation: {Number} , //  amount of rotation relative to the current position NOT the original822	*				scale: {Number} , // amount of scaling relative to the current position NOT the original823	*				duration: {Number}, // ms: duration of the motion824	*				description : {String} // details as String: pinch:{'close'|'open'} e.g. "pinch:-1:close" ||  rotate:{'counterclockwise'|'clockwise'} e.g. "rotate:-1:counterclockwise"825	*			};826	* @param {DOM-Event} event_827	* @return {Void}828	*/829	function _onDevicemotion(event_) {830		var _sType;831		var _$element = jQuery(window);832		//var _bHasGyroscope = $.hasGyroscope;833		// skip custom notification: devicemotion is triggered every 0.05s regardlesse of any gesture834		// get options835		var _oDatajQueryGestures = _$element.data('ojQueryGestures');836		var _oThreshold = $.jGestures.defaults.thresholdShake;837		// get last position or set initital values838		var _oLastDevicePosition = _oDatajQueryGestures.oDeviceMotionLastDevicePosition || {839			accelerationIncludingGravity : {840				x: 0,841				y: 0,842				z: 0843			},844			shake : {845				eventCount: 0,846				intervalsPassed: 0,847				intervalsFreeze: 0848			},849			shakeleftright : {850				eventCount: 0,851				intervalsPassed: 0,852				intervalsFreeze: 0853			},854			shakefrontback : {855				eventCount: 0,856				intervalsPassed: 0,857				intervalsFreeze: 0858			},859			shakeupdown : {860				eventCount: 0,861				intervalsPassed: 0,862				intervalsFreeze: 0863			}864		};865		// cache current values866		var _oCurrentDevicePosition = {867			accelerationIncludingGravity : {868				x: event_.accelerationIncludingGravity.x,869				y: event_.accelerationIncludingGravity.y,870				z: event_.accelerationIncludingGravity.z871			},872			shake: {873				eventCount: _oLastDevicePosition.shake.eventCount,874				intervalsPassed: _oLastDevicePosition.shake.intervalsPassed,875				intervalsFreeze: _oLastDevicePosition.shake.intervalsFreeze876			 },877			 shakeleftright: {878				eventCount: _oLastDevicePosition.shakeleftright.eventCount,879				intervalsPassed: _oLastDevicePosition.shakeleftright.intervalsPassed,880				intervalsFreeze: _oLastDevicePosition.shakeleftright.intervalsFreeze881			 },882			 shakefrontback: {883				eventCount: _oLastDevicePosition.shakefrontback.eventCount,884				intervalsPassed: _oLastDevicePosition.shakefrontback.intervalsPassed,885				intervalsFreeze: _oLastDevicePosition.shakefrontback.intervalsFreeze886			 },887			 shakeupdown: {888				eventCount: _oLastDevicePosition.shakeupdown.eventCount,889				intervalsPassed: _oLastDevicePosition.shakeupdown.intervalsPassed,890				intervalsFreeze: _oLastDevicePosition.shakeupdown.intervalsFreeze891			 }892		};893		// options894		var _aType;895		var _aDescription;896		var _oObj;897		// trigger events for all bound pseudo events on this element898		for (_sType in _oDatajQueryGestures) {899			// get current pseudo event900			// trigger bound events on this element901			switch(_sType) {902				case 'shake':903				case 'shakeleftright':904				case 'shakefrontback':905				case 'shakeupdown':906					// options907					_aType = [];908					_aDescription = [];909					_aType.push(_sType);910					// freeze shake - prevent multiple shake events on one  shaking motion (user won't stop shaking immediately)911					if (++_oCurrentDevicePosition[_sType].intervalsFreeze > _oThreshold.freezeShakes && _oCurrentDevicePosition[_sType].intervalsFreeze < (2*_oThreshold.freezeShakes) ) { break;	}912					// set control values913					_oCurrentDevicePosition[_sType].intervalsFreeze  = 0;914					_oCurrentDevicePosition[_sType].intervalsPassed++;915					// check for shaking motions: massive acceleration changes in every direction916					if ( ( _sType === 'shake' ||_sType === 'shakeleftright' ) && ( _oCurrentDevicePosition.accelerationIncludingGravity.x > _oThreshold.leftright.sensitivity  || _oCurrentDevicePosition.accelerationIncludingGravity.x < (-1* _oThreshold.leftright.sensitivity) ) ) {917						_aType.push('leftright');918						_aType.push('x-axis');919					}920					if ( ( _sType === 'shake' ||_sType === 'shakefrontback' ) && (_oCurrentDevicePosition.accelerationIncludingGravity.y > _oThreshold.frontback.sensitivity  || _oCurrentDevicePosition.accelerationIncludingGravity.y < (-1 * _oThreshold.frontback.sensitivity) ) ) {921						_aType.push('frontback');922						_aType.push('y-axis');923					}924					if ( ( _sType === 'shake' ||_sType === 'shakeupdown' ) && ( _oCurrentDevicePosition.accelerationIncludingGravity.z+9.81 > _oThreshold.updown.sensitivity  || _oCurrentDevicePosition.accelerationIncludingGravity.z+9.81 < (-1 * _oThreshold.updown.sensitivity) ) ) {925						_aType.push('updown');926						_aType.push('z-axis');927					}928					// at least one successful shaking event929					if (_aType.length > 1) {930						// minimum number of shaking motions during  the defined "time" (messured by events - device event interval: 0.05s)931						if (++_oCurrentDevicePosition[_sType].eventCount == _oThreshold.requiredShakes && (_oCurrentDevicePosition[_sType].intervalsPassed) < _oThreshold.freezeShakes ) {932							// send event933							_$element.triggerHandler(_sType, _createOptions ({type: _sType, description: _aType.join(':'), event:event_,duration:_oCurrentDevicePosition[_sType].intervalsPassed*5 }) );934							// reset935							_oCurrentDevicePosition[_sType].eventCount = 0;936							_oCurrentDevicePosition[_sType].intervalsPassed = 0;937							// freeze shake938							_oCurrentDevicePosition[_sType].intervalsFreeze = _oThreshold.freezeShakes+1;939						}940						// too slow, reset941						else if (_oCurrentDevicePosition[_sType].eventCount == _oThreshold.requiredShakes && (_oCurrentDevicePosition[_sType].intervalsPassed) > _oThreshold.freezeShakes ) {942							_oCurrentDevicePosition[_sType].eventCount = 0 ;943							_oCurrentDevicePosition[_sType].intervalsPassed = 0;944						}945					}946				break;947			}948			// refresh pseudo events949			_oObj = {};950			_oObj.oDeviceMotionLastDevicePosition = _oCurrentDevicePosition;951			_$element.data('ojQueryGestures',$.extend(true,_oDatajQueryGestures,_oObj));952		}953	}954	/**955	* Handler: touchstart or mousedown956	* Setup pseudo-event by storing initial values such as :957	*	screenX : {Number}958	*	screenY : {Number}959	*	timestamp: {Number}960	*  on the pseudo gesture event and961	*  sets up additional eventlisteners for handling touchmove events.962	* @param {DOM-Event} event_963	* @return {Void}964	*/965	function _onTouchstart(event_) {966		// ignore bubbled handlers967		// if ( event_.currentTarget !== event_.target ) { return; }968		var _$element = jQuery(event_.currentTarget);969		// var _$element = jQuery(event_.target);970		// trigger custom notification971		_$element.triggerHandler($.jGestures.events.touchstart,event_);972		// set the necessary touch events973		if($.hasGestures) {974			event_.currentTarget.addEventListener('touchmove', _onTouchmove, false);975			event_.currentTarget.addEventListener('touchend', _onTouchend, false);976		}977		// event substitution978		else {979//			event_.currentTarget.addEventListener('mousemove', _onTouchmove, false);980//			event_.currentTarget.addEventListener('mouseup', _onTouchend, false);981			_$element.bind('mousemove', _onTouchmove);982			_$element.bind('mouseup', _onTouchend);983		}984		// get stored pseudo event985		var _oDatajQueryGestures = _$element.data('ojQueryGestures');986		// var _oEventData = _oDatajQueryGestures[_sType];987		var _eventBase = (event_.touches) ? event_.touches[0] : event_;988		// store current values for calculating relative values (changes between touchmoveevents)989		var _oObj = {};990		_oObj.oLastSwipemove = { screenX : _eventBase.screenX, screenY : _eventBase.screenY, timestamp:new Date().getTime()};991		_oObj.oStartTouch = { screenX : _eventBase.screenX, screenY : _eventBase.screenY, timestamp:new Date().getTime()};992		_$element.data('ojQueryGestures',$.extend(true,_oDatajQueryGestures,_oObj));993	}994	/**995	* Handler: touchmove or mousemove996	* Calculates the x/y changes since the last event,997	* compares it to $.jGestures.defaults.thresholdMove and triggers998	* an swipemove event if the distance exceed the999	* threshold.1000	* Custom-event argument object:1001	* {Object}1002	*			{1003	*				type: e.g. 'swipemove',1004	*				â: {DOM-Event},1005	*				// default: just one entry on the delta-array - the first touchpoint1006	*				// the first touchpoint is the reference point for every gesture,1007	*				// because moving touchpoints in various directions would result in1008	*				// a gesture.1009	*				// delta and direction details are just provided for touch not for gesture / motion events1010	*				delta : [1011	*					{1012	*						lastX:{Number} , // x-axis: relative to the last touchevent (e.g. touchmove!)1013	*						lastY:{Number}, // y-axis: relative to the last touchevent (e.g. touchmove!)1014	*						moved: {Number},  // distance: relative to the original touchpoint1015	*						startX: {Number} , // relative to the original touchpoint1016	*						startY: {Number} ,// relative to the original touchpoint1017	*					} ],1018	*				// based on the first touchpoint1019	*				direction : { // relative to the last touchevent (e.g. touchmove!)1020	*					vector: {Number}, // -1|+1, indicates the direction if necessary(pinch/rotate)1021	*					orientation: {Number} // window.orientation: -90,0,90,180 || null (window.orienntation)1022	*					lastX : {Number}, // -1,0,+1 relative to the last touchevent (e.g. touchmove!)1023	*					lastY : {Number}, // -1,0,+1 relative to the last touchevent (e.g. touchmove!)1024	*					startX: {Number} , //-1,0,+1 relative to the original touchpoint1025	*					startY: {Number} ,// -1,0,+1 relative to the original touchpoint1026	*				},1027	*				rotation: null, // gestureonly: amount of rotation relative to the current position NOT the original1028	*				scale: null, // gestureonly: amount of scaling relative to the current position NOT the original1029	*				duration: {Number}, // ms: relative to the original touchpoint1030	*				description : {String} // details as String: {TYPE *}:{TOUCHES 1|2|3|4}:{X-AXIS 'right'|'left'|'steady'}:{Y-AXIS 'down'|'up'|'steady'} e.g. "swipe:1:left:steady" relative to the last touchpoint1031	*			};1032	*1033	* @param {DOM-Event} event_1034	* @return {Void}1035	*/1036	function _onTouchmove(event_) {1037		var _$element = jQuery(event_.currentTarget);1038		// var _$element = jQuery(event_.target);1039		// get stored pseudo event1040		var _oDatajQueryGestures = _$element.data('ojQueryGestures');1041		var _bHasTouches = !!event_.touches;1042		var _iScreenX = (_bHasTouches) ? event_.changedTouches[0].screenX : event_.screenX;1043		var _iScreenY = (_bHasTouches) ? event_.changedTouches[0].screenY : event_.screenY;1044		//relative to the last event1045		var _oEventData = _oDatajQueryGestures.oLastSwipemove;1046		var _iDeltaX = _iScreenX - _oEventData.screenX   ;1047		var _iDeltaY = _iScreenY - _oEventData.screenY;1048		var _oDetails;1049			// there's a swipemove set (not the first occurance), trigger event1050		if (!!_oDatajQueryGestures.oLastSwipemove) {1051			// check1052			_oDetails = _createOptions({type: 'swipemove', touches: (_bHasTouches) ? event_.touches.length: '1', screenY: _iScreenY,screenX:_iScreenX ,deltaY: _iDeltaY,deltaX : _iDeltaX, startMove:_oEventData, event:event_, timestamp:_oEventData.timestamp});1053			_$element.triggerHandler(_oDetails.type,_oDetails);1054		}1055		// store the new values1056		var _oObj = {};1057		var _eventBase = (event_.touches) ? event_.touches[0] : event_;1058		_oObj.oLastSwipemove = { screenX : _eventBase.screenX, screenY : _eventBase.screenY, timestamp:new Date().getTime()};1059		_$element.data('ojQueryGestures',$.extend(true,_oDatajQueryGestures,_oObj));1060	}1061	/**1062	* Handler: touchend or mouseup1063	* Removes the additional handlers (move/end)1064	* Calculates the x/y changes since the touchstart event1065	* not in relation to the last move event.1066	* Triggers the1067	*	swipeone|swipetwo|swipethree|swipefour|1068	*	swipeup|swiperightup|swiperight|swiperightdown|swipedown|1069	*	swipeleftdown|swipeleft|swipeleftup|1070	*	tapone|taptwo|tapthree|tapfour1071	* event.1072	*		{Object}1073	*			{1074	*				type: eventtype e.g. "swipeone","swipeleftdown",1075	*				originalEvent: {DOM-Event},1076	*				// default: just one entry on the delta-array - the first touchpoint1077	*				// the first touchpoint is the reference point for every gesture,1078	*				// because moving touchpoints in various directions would result in1079	*				// a gesture.1080	*				// delta and direction details are just provided for touch not for gesture / motion events1081	*				delta : [1082	*					{1083	*						lastX:{Number} , // x-axis: relative to the last touchevent (e.g. touchmove!)1084	*						lastY:{Number}, // y-axis: relative to the last touchevent (e.g. touchmove!)1085	*						moved: {Number},  // distance: relative to the original touchpoint1086	*						startX: {Number} , // relative to the original touchpoint1087	*						startY: {Number} ,// relative to the original touchpoint1088	*					} ],1089	*				// based on the first touchpoint1090	*				direction : { // relative to the last touchevent (e.g. touchmove!)1091	*					vector: {Number}, // -1|+1, indicates the direction if necessary(pinch/rotate)1092	*					orientation: {Number} // window.orientation: -90,0,90,180 || null (window.orienntation)1093	*					lastX : {Number}, // -1,0,+1 relative to the last touchevent (e.g. touchmove!)1094	*					lastY : {Number}, // -1,0,+1 relative to the last touchevent (e.g. touchmove!)1095	*					startX: {Number} , //-1,0,+1 relative to the original touchpoint1096	*					startY: {Number} ,// -1,0,+1 relative to the original touchpoint1097	*				},1098	*				rotation: null,1099	*				scale: null ,1100	*				duration: {Number}, // ms: relative to the original touchpoint1101	*				description : {String} // details as String: {TYPE *}:{TOUCHES 1|2|3|4}:{X-AXIS 'right'|'left'|'steady'}:{Y-AXIS 'down'|'up'|'steady'} e.g. "swipe:1:left:steady" relative to the last touchpoint1102	*			};1103	* @param {DOM-Event} event_1104	* @return {Void}1105	*/1106	function _onTouchend(event_) {1107		// ignore bubbled handlers1108		// if ( event_.currentTarget !== event_.target ) { return; }1109		var _$element = jQuery(event_.currentTarget);1110		var _bHasTouches = !!event_.changedTouches;1111		var _iTouches = (_bHasTouches) ? event_.changedTouches.length : '1';1112		var _iScreenX = (_bHasTouches) ? event_.changedTouches[0].screenX : event_.screenX;1113		var _iScreenY = (_bHasTouches) ? event_.changedTouches[0].screenY : event_.screenY;1114		// trigger custom notification1115		_$element.triggerHandler($.jGestures.events.touchendStart,event_);1116		// var _$element = jQuery(event_.target);1117		// remove events1118		if($.hasGestures) {1119			event_.currentTarget.removeEventListener('touchmove', _onTouchmove, false);1120			event_.currentTarget.removeEventListener('touchend', _onTouchend, false);1121		}1122		// event substitution1123		else {1124//			event_.currentTarget.removeEventListener('mousemove', _onTouchmove, false);1125//			event_.currentTarget.removeEventListener('mouseup', _onTouchend, false);1126			_$element.unbind('mousemove', _onTouchmove);1127			_$element.unbind('mouseup', _onTouchend);1128		}1129		// get all bound pseudo events1130		var _oDatajQueryGestures = _$element.data('ojQueryGestures');1131		// if the current change on the x/y position is above the defined threshold for moving an element set the moved flag1132		// to distinguish between a moving gesture and a shaking finger trying to tap1133		var _bHasMoved = (1134			Math.abs(_oDatajQueryGestures.oStartTouch.screenX - _iScreenX) > $.jGestures.defaults.thresholdMove ||1135			Math.abs(_oDatajQueryGestures.oStartTouch.screenY - _iScreenY) > $.jGestures.defaults.thresholdMove1136		) ? true : false;1137		// if the current change on the x/y position is above the defined threshold for swiping set the moved flag1138		// to indicate we're dealing with a swipe gesture1139		var _bHasSwipeGesture = (1140			Math.abs(_oDatajQueryGestures.oStartTouch.screenX - _iScreenX) > $.jGestures.defaults.thresholdSwipe ||1141			Math.abs(_oDatajQueryGestures.oStartTouch.screenY - _iScreenY) > $.jGestures.defaults.thresholdSwipe1142		) ? true : false;1143		var _sType;1144		var _oEventData ;1145		var _oDelta;1146		// calculate distances in relation to the touchstart position not the last touchmove event!1147		var _iDeltaX;1148		var _iDeltaY;1149		var _oDetails;1150		var _aDict = ['zero','one','two','three','four'];1151		// swipe marker1152		var _bIsSwipe;1153		// trigger events for all bound pseudo events on this element1154		for (_sType in _oDatajQueryGestures) {1155			// get current pseudo event1156			_oEventData = _oDatajQueryGestures.oStartTouch;1157			_oDelta = {};1158			_iScreenX = (_bHasTouches) ? event_.changedTouches[0].screenX : event_.screenX;1159			_iScreenY = (_bHasTouches) ? event_.changedTouches[0].screenY : event_.screenY;1160			// calculate distances in relation to the touchstart position not the last touchmove event!1161			_iDeltaX = _iScreenX - _oEventData.screenX ;1162			_iDeltaY = _iScreenY - _oEventData.screenY;1163			_oDetails = _createOptions({type: 'swipe', touches: _iTouches, screenY: _iScreenY,screenX:_iScreenX ,deltaY: _iDeltaY,deltaX : _iDeltaX, startMove:_oEventData, event:event_, timestamp:  _oEventData.timestamp });1164			// swipe marker1165			_bIsSwipe = false;1166			// trigger bound events on this element1167			switch(_sType) {1168				case 'swipeone':1169					if( _bHasTouches === false && _iTouches == 1 && _bHasMoved === false){1170						// trigger tapone!1171						break;1172					}1173					if (_bHasTouches===false || ( _iTouches == 1  && _bHasMoved === true && _bHasSwipeGesture===true)) {1174						_bIsSwipe = true;1175						_oDetails.type = ['swipe',_aDict[_iTouches]].join('');1176						_$element.triggerHandler(_oDetails.type,_oDetails);1177					}1178				break;1179				case 'swipetwo':1180					if (( _bHasTouches && _iTouches== 2 && _bHasMoved === true && _bHasSwipeGesture===true)) {1181						_bIsSwipe = true;1182						_oDetails.type = ['swipe',_aDict[_iTouches]].join('');1183						_$element.triggerHandler(_oDetails.type,_oDetails);1184					}1185				break;1186				case 'swipethree':1187					if ( ( _bHasTouches && _iTouches == 3 && _bHasMoved === true && _bHasSwipeGesture===true)) {1188						_bIsSwipe = true;1189						_oDetails.type = ['swipe',_aDict[_iTouches]].join('');1190						_$element.triggerHandler(_oDetails.type,_oDetails);1191					}1192				break;1193				case 'swipefour':1194					if ( ( _bHasTouches && _iTouches == 4 && _bHasMoved === true && _bHasSwipeGesture===true)) {1195						_bIsSwipe = true;1196						_oDetails.type = ['swipe',_aDict[_iTouches]].join('');1197						_$element.triggerHandler(_oDetails.type,_oDetails);1198					}1199				break;1200				case 'swipeup':1201				case 'swiperightup':1202				case 'swiperight':1203				case 'swiperightdown':1204				case 'swipedown':1205				case 'swipeleftdown':1206				case 'swipeleft':1207				case 'swipeleftup':1208					if ( _bHasTouches && _bHasMoved === true && _bHasSwipeGesture===true) {1209						_bIsSwipe = true;1210						_oDetails.type = [1211									'swipe',1212								((_oDetails.delta[0].lastX != 0) ? ((_oDetails.delta[0].lastX > 0) ? 'right' : 'left') : ''),1213								((_oDetails.delta[0].lastY != 0) ? ((_oDetails.delta[0].lastY > 0) ? 'down' : 'up') :'')1214									].join('');1215						_$element.triggerHandler(_oDetails.type, _oDetails);1216					}1217				break;1218				case 'tapone':1219				case 'taptwo':1220				case 'tapthree':1221				case 'tapfour':1222					if (( /* _bHasTouches && */ _bHasMoved !== true && _bIsSwipe !==true) && (_aDict[_iTouches] ==_sType.slice(3)) ) {1223						_oDetails.description = ['tap',_aDict[_iTouches]].join('');1224						_oDetails.type = ['tap',_aDict[_iTouches]].join('');1225						_$element.triggerHandler(_oDetails.type,_oDetails);1226						}1227					break;1228			}1229			// refresh pseudo events1230			var _oObj = {};1231//			_oObj[_sType] = false;1232//			_oObj.hasTouchmoved = false;1233			_$element.data('ojQueryGestures',$.extend(true,_oDatajQueryGestures,_oObj));1234			_$element.data('ojQueryGestures',$.extend(true,_oDatajQueryGestures,_oObj));1235		}1236		_$element.triggerHandler($.jGestures.events.touchendProcessed,event_);1237	}1238	/**1239	* Handler: gesturestart1240	* Setup pseudo-event by storing initial values such as :1241	*	timestamp: {Number}1242	*  on the pseudo gesture event1243	* Since the gesture-event doesn't supply event.touches no tuchpoints will be calculated1244	* @param {DOM-Event} event_1245	* @return {Void}1246	*/1247	function _onGesturestart(event_) {1248		// ignore bubbled handlers1249		// if ( event_.currentTarget !== event_.target ) { return; }1250		var _$element = jQuery(event_.currentTarget);1251		// var _$element = jQuery(event_.target);1252		// trigger custom notification1253		_$element.triggerHandler($.jGestures.events.gesturestart,event_);1254		// get stored pseudo event1255		var _oDatajQueryGestures = _$element.data('ojQueryGestures');1256		// var _oEventData = _oDatajQueryGestures[_sType];1257		// store current values for calculating relative values (changes between touchmoveevents)1258		var _oObj = {};1259		_oObj.oStartTouch = {timestamp:new Date().getTime()};1260		_$element.data('ojQueryGestures',$.extend(true,_oDatajQueryGestures,_oObj));1261	}1262	/**1263	* Handler: gesturechange1264	* Read the event_.scale / event_.rotate values,1265	* an triggers a pinch|rotate event if necessary.1266	* Since the gesture-event doesn't supply event.touches no tuchpoints will be calculated1267	* @returns {Object}1268	*			{1269	*				type: eventtype e.g. "pinch","rotate",1270	*				originalEvent: {DOM-Event},1271	*				// delta and direction details are just provided for touch not for gesture / motion events1272	*				delta : null,1273	*				direction : {1274	*					vector: {Number}, // -1|+1, indicates the direction if necessary(pinch/rotate)1275	*					 orientation: {Number} // window.orientation: -90,0,90,180 || null (window.orienntation)1276	*				 },1277	*				rotation: {Number} , //  amount of rotation relative to the current position NOT the original1278	*				scale: {Number} , // amount of scaling relative to the current position NOT the original1279	*				duration: {Number}, // ms: relative to the original touchpoint1280	*				description : {String} // details as String: pinch:{'close'|'open'} e.g. "pinch:-1:close" ||  rotate:{'counterclockwise'|'clockwise'} e.g. "rotate:-1:counterclockwise"1281	*			};1282	* @param {DOM-Event} event_1283	* @return {Void}1284	*/1285	function _onGesturechange(event_) {1286		// ignore bubbled handlers1287		// if ( event_.currentTarget !== event_.target ) { return; }1288		var _$element = jQuery(event_.currentTarget);1289		// var _$element = jQuery(event_.target);1290		var _iDelta,_iDirection,_sDesc,_oDetails;1291		// get all pseudo events1292		var _oDatajQueryGestures = _$element.data('ojQueryGestures');1293		// trigger events for all bound pseudo events on this element1294		var _sType;1295		for (_sType in _oDatajQueryGestures) {1296			// trigger a specific bound event1297			switch(_sType) {1298				case 'pinch':1299					_iDelta = event_.scale;1300					if ( ( ( _iDelta < 1 ) && (_iDelta % 1) < (1 - $.jGestures.defaults.thresholdPinchclose) ) || ( ( _iDelta > 1 ) && (_iDelta % 1) > ($.jGestures.defaults.thresholdPinchopen) ) ) {1301						_iDirection = (_iDelta < 1 ) ? -1 : +1 ;1302						_oDetails = _createOptions({type: 'pinch', scale: _iDelta, touches: null,startMove:_oDatajQueryGestures.oStartTouch, event:event_, timestamp: _oDatajQueryGestures.oStartTouch.timestamp, vector:_iDirection, description: ['pinch:',_iDirection,':' , ( (_iDelta < 1 ) ? 'close' : 'open' )].join('') });1303						_$element.triggerHandler(_oDetails.type, _oDetails);1304					}1305				break;1306				case 'rotate':1307					_iDelta = event_.rotation;1308					if ( ( ( _iDelta < 1 ) &&  ( -1*(_iDelta) > $.jGestures.defaults.thresholdRotateccw ) ) || ( ( _iDelta > 1 ) && (_iDelta  > $.jGestures.defaults.thresholdRotatecw) ) ) {1309						_iDirection = (_iDelta < 1 ) ? -1 : +1 ;1310						_oDetails = _createOptions({type: 'rotate', rotation: _iDelta, touches: null, startMove:_oDatajQueryGestures.oStartTouch, event:event_, timestamp: _oDatajQueryGestures.oStartTouch.timestamp, vector:_iDirection, description: ['rotate:',_iDirection,':' , ( (_iDelta < 1 ) ? 'counterclockwise' : 'clockwise' )].join('') });1311						_$element.triggerHandler(_oDetails.type, _oDetails);1312					}1313				break;1314			}1315		}1316	}1317	/**1318	* Handler: gestureend1319	* Read the event_.scale / event_.rotate values,1320	* compares it to $.jGestures.defaults.threshold* and triggers1321	* a pinchclose|pinchclose|rotatecw|rotateccw event if the distance exceed the1322	* Since the gesture-event doesn't supply event.touches no tuchpoints will be calculated1323	* * Custom-event argument object:1324	* @returns {Object}1325	*			{1326	*				type: eventtype e.g. "pinchclose","pinchopen", "rotatecw", "rotateccw",1327	*				originalEvent: {DOM-Event},1328	*				// delta and direction details are just provided for touch not for gesture / motion events1329	*				delta : null,1330	*				// based on the first touchpoint1331	*				direction : {1332	*					vector: {Number}, // -1|+1, indicates the direction if necessary(pinch/rotate)1333	*					orientation: {Number} // window.orientation: -90,0,90,180 || null (window.orienntation)1334	*				},1335	*				rotation: {Number} , //  amount of rotation relative to the current position NOT the original1336	*				scale: {Number} , // amount of scaling relative to the current position NOT the original1337	*				duration: {Number}, // ms: relative to the original touchpoint1338	*				description : {String} // details as String: pinch:{'close'|'open'} e.g. "pinch:-1:close" ||  rotate:{'counterclockwise'|'clockwise'} e.g. "rotate:-1:counterclockwise"1339	*			};1340	* @param {DOM-Event} event_1341	* @return {Void}1342	*/1343	function _onGestureend(event_) {1344		// ignore bubbled handlers1345		// if ( event_.currentTarget !== event_.target ) { return; }1346		var _$element = jQuery(event_.currentTarget);1347		// var _$element = jQuery(event_.target);1348		// trigger custom notification1349		_$element.triggerHandler($.jGestures.events.gestureendStart,event_);1350		var _iDelta;1351		var _oDatajQueryGestures = _$element.data('ojQueryGestures');1352		// trigger handler for every bound event1353		var _sType;1354		for (_sType in _oDatajQueryGestures) {1355			switch(_sType) {1356				case 'pinchclose':1357					_iDelta = event_.scale;1358					if (( _iDelta < 1 ) && (_iDelta % 1) < (1 - $.jGestures.defaults.thresholdPinchclose)) {1359						_$element.triggerHandler('pinchclose', _createOptions ({type: 'pinchclose', scale:_iDelta, vector: -1, touches: null, startMove: _oDatajQueryGestures.oStartTouch, event:event_, timestamp:_oDatajQueryGestures.oStartTouch.timestamp,description: 'pinch:-1:close' }) );1360					}1361				break;1362				case 'pinchopen':1363					_iDelta = event_.scale;1364					if ( ( _iDelta > 1 ) && (_iDelta % 1) > ($.jGestures.defaults.thresholdPinchopen) ) {1365						_$element.triggerHandler('pinchopen', _createOptions ({type: 'pinchopen', scale:_iDelta, vector: +1, touches: null, startMove: _oDatajQueryGestures.oStartTouch, event:event_, timestamp:_oDatajQueryGestures.oStartTouch.timestamp,description: 'pinch:+1:open'}) );1366					}1367				break;1368				case 'rotatecw':1369					_iDelta = event_.rotation;1370					if ( ( _iDelta > 1 ) && (_iDelta  > $.jGestures.defaults.thresholdRotatecw) ) {1371						_$element.triggerHandler('rotatecw', _createOptions ({type: 'rotatecw', rotation:_iDelta, vector: +1, touches: null, startMove: _oDatajQueryGestures.oStartTouch, event:event_, timestamp:_oDatajQueryGestures.oStartTouch.timestamp,description: 'rotate:+1:clockwise'}) );1372					}1373				break;1374				case 'rotateccw':1375					_iDelta = event_.rotation;1376					if ( ( _iDelta < 1 ) &&  ( -1*(_iDelta) > $.jGestures.defaults.thresholdRotateccw ) ) {1377							_$element.triggerHandler('rotateccw', _createOptions ({type: 'rotateccw', rotation:_iDelta, vector: -1, touches: null, startMove: _oDatajQueryGestures.oStartTouch, event:event_, timestamp:_oDatajQueryGestures.oStartTouch.timestamp,description: 'rotate:-1:counterclockwise'}) );1378						}1379				break;1380				}1381			}1382			_$element.triggerHandler($.jGestures.events.gestureendProcessed,event_);1383		}1384	}1385)(jQuery);...jquery.jgestures.js
Source:jquery.jgestures.js  
1/**2 * jGestures: a jQuery plugin for gesture events 3 * Copyright 2010-2011, Neue Digitale / Razorfish GmbH4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 8 * Unless required by applicable law or agreed to in writing, software 9 * distributed under the License is distributed on an "AS IS" BASIS, 10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 * See the License for the specific language governing permissions and 12 * limitations under the License. 13 * 14 * @fileOverview15 * Neue Digitale / Razorfish GmbH javascript library: add touch events such as 'pinch', 16 * 'rotate', 'swipe', 'tap' and 'orientationchange' on capable user agents. 17 * For incapable devices there's a basic event substitution: a "tapone" event 18 * can be triggered by "clicking", a "swipeone" by performing a swipe-ish 19 * gesture using the mouse (buttondown - mousemove - buttonup).20 * 21 * This is still a beta version, bugfixes and improvements appreciated.22 * 23 * @author martin.krause@neue-digitale.de24 * @version 0.8725 *26 * @snvauthor				$Author: martinkr $27 * @svnversion				$Revision: 0 $28 *29 * @requires 30 * jQuery JavaScript Library v1.4.2 - http://jquery.com/31 *	Copyright 2010, John Resig32 *	Dual licensed under the MIT or GPL Version 2 licenses.33 *	http://jquery.org/license34 *35 * 36 * @copyright Neue Digitale / Razorfish GmbH37 * 38 * @example	jQuery('#swipe').bind('swipeone',eventHandler);39 *  40 * Notification on native events:41 * On every native touchstart, touchend, gesturestart and gestureend-event, 42 * jgestures triggers a corresponding custom event 43 * (jGestures.touchstart,jGestures.touchend,jGestures.gesturestart and jGestures.gestureend) on the event-element.44 * The  eventhandler's second argument represents the original touch event (yes: including all touchpoints).45 * Use this if you need very detailed control e.g. kinetic scrolling or implementing additional gestures.46 * 47 * Every jGesture-eventhandler receives a custom object as second argument 48 * containing the original event (originalEvent property) and processed 49 * information (such as delta values and timesptamp).50 * Example:{ 51 *				type: eventtype e.g. "swipe","pinch", 52				originalEvent: {DOM-Event},53*				// default: just one entry on the delta-array - the first touchpoint54*				// the first touchpoint is the reference point for every gesture, 55*				// because moving touchpoints in various directions would result in 56*				// a gesture.57*				// delta and direction details are just provided for touch not for gesture events58*				delta : [ 59*					{60*						lastX:{Number} , // x-axis: relative to the last touchevent (e.g. touchmove!)61*						lastY:{Number}, // y-axis: relative to the last touchevent (e.g. touchmove!)62*						moved: {Number},  // distance: relative to the original touchpoint 63*						startX: {Number} , // relative to the original touchpoint64*						startY: {Number} ,// relative to the original touchpoint65*					} ],66*				// based on the first touchpoint67*				direction : { // relative to the last touchevent (e.g. touchmove!)68*					vector: {Number}, // -1|+1, indicates the direction if necessary(pinch/rotate)69*					orientation: {Number} // window.orientation: -90,0,90,180 || null (window.orienntation)70*					lastX : {Number}, // -1,0,+1 || null (orientationchange) // relative to the last touchevent (e.g. touchmove!)71*					lastY : {Number}, // -1,0,+1 || null (orientationchange)// relative to the last touchevent (e.g. touchmove!)72*					startX: {Number} , // relative to the original touchpoint73*					startY: {Number} ,// relative to the original touchpoint74*				},75*				rotation: {Number} || {null}, // gestureonly: amount of rotation relative to the current position NOT the original 76*				scale: {Number} || {null}, // gestureonly: amount of scaling relative to the current position NOT the original 77*				duration: {Number}, // ms: relative to the original touchpoint 78*				description : {String} // details as String: {TYPE *}:{TOUCHES 1|2|3|4}:{X-AXIS 'right'|'left'|'steady'}:{Y-AXIS 'down'|'up'|'steady'} e.g. "swipe:1:left:steady" relative to the last touchpoint79*			};80 *  81 * Available jGesture-events can be grouped into: 82 *83 * 84 * Device events:85 *	The jGesture-Events in this group are triggered by the device.86 * 87 * @event 'orientationchange'88 *		The device is turned clockwise or counterclockwise. This event is triggered 89 *		by the device and might use an internal gyroscope.90 *	obj.description:91 *		orientationchange:landscape:clockwise:-9092 *		orientationchange:portrait:default:093 *		orientationchange:landscape:counterclockwise|portrait:9094 *		orientationchange:portrait:upsidedown:18095 *96 *97 * Move events:98 *	The jGesture-Events in this group are triggered during the touch/gesture 99 *	execution whenever a touchpoint changes. 100 *	In contrast to touchend/gestureend-events which are triggered after 101 *	the touch/gesture has completed. 102 *103 * @event 'pinch'104 *		Is triggered during a pinch gesture (two fingers moving away from or 105 *		towards each other).106 *	obj.description:107 *		pinch:-1:close108 *		pinch:+1:open109 * 110 * @event 'rotate'111 *		Is triggered during a rotation gesture (two fingers rotating clockwise 112 *		or counterclockwise).113 *	obj.description:114 *		rotate:-1:counterclockwise115 *		rotate:+1:+clockwise116 * 117 * @event 'swipemove'118 *		Is triggered during a swipe move gesture (finger(s) being moved around 119 *		the device, e.g. dragging)120 *	obj.description:121 *		swipemove:1:left:down122 *		swipemove:1:left:up123 *		swipemove:1:left:steady124 *		swipemove:1:right:down125 *		swipemove:1:right:up126 *		swipemove:1:right:steady127 *		swipemove:2:left:down128 *		swipemove:2:left:up129 *		swipemove:2:left:steady130 *		swipemove:2:right:down131 *		swipemove:2:right:up132 *		swipemove:2:right:steady133 *		swipemove:2:left:down134 *		swipemove:3:left:up135 *		swipemove:3:left:steady136 *		swipemove:3:right:down137 *		swipemove:3:right:up138 *		swipemove:3:right:steady139  *		swipemove:3:left:down140 *		swipemove:4:left:up141 *		swipemove:4:left:steady142 *		swipemove:4:right:down143 *		swipemove:4:right:up144 *		swipemove:4:right:steady145 *146 *  147 * Toucheend events:148 *	The jGesture-Events in this group are triggered after the touch/gesture 149 *	has completed. 150 *	In contrast to touchmove-events which are triggered during the touch/gesture 151 *	execution whenever a touchpoint changes.152 * 153 * @event 'swipeone'154 *		Is triggered after a swipe move gesture with one touchpoint (one finger155 *		was moved around the device)156 *	obj.description:157 *		swipeone:1:left:down158 *		swipeone:1:left:up159 *		swipeone:1:left:steady160 *		swipeone:1:right:down161 *		swipeone:1:right:up162 *		swipeone:1:right:steady163 * 164 * @event 'swipetwo'165 *		Is triggered after a swipe move gesture with two touchpoints (two fingers166 *		were moved around the device)167 *	obj.description:168 *		swipetwo:2:left:down169 *		swipetwo:2:left:up170 *		swipetwo:2:left:steady171 *		swipetwo:2:right:down172 *		swipetwo:2:right:up173 *		swipetwo:2:right:steady174 * 175 * @event 'swipethree'176 *		Is triggered after a swipe move gesture with three touchpoints (three 177 *		fingers were moved around the device)178 *	obj.description:179 *		swipethree:3:left:down180 *		swipethree:3:left:up181 *		swipethree:3:left:steady182 *		swipethree:3:right:down183 *		swipethree:3:right:up184 *		swipethree:3:right:steady185 * 186 * @event 'swipefour'187 *		Is triggered after a swipe move gesture with four touchpoints (four 188 *		fingers were moved around the device)189 *	obj.description:190 *		swipefour:4:left:down191 *		swipefour:4:left:up192 *		swipefour:4:left:steady193 *		swipefour:4:right:down194 *		swipefour:4:right:up195 *		swipefour:4:right:steady196 * 197  * 198 * @event 'swipeup'199 *		Is triggered after an  strict upwards swipe move gesture 200 *	obj.description:201 *		swipe:1:steady:up202 *		swipe:2:steady:up203 *		swipe:3:steady:up204 *		swipe:4:steady:up205 *206 * @event 'swiperightup'207 *		Is triggered after a rightwards and upwards swipe move gesture 208 *	obj.description:209 *		swipe:1:right:up210 *		swipe:2:right:up211 *		swipe:3:right:up212 *		swipe:4:right:up 213 * 214 * @event 'swiperight'215 *		Is triggered after a  strict rightwards swipe move gesture 216 *	obj.description:217 *		swipe:1:right:steady218 *		swipe:2:right:steady219 *		swipe:3:right:steady220 *		swipe:4:right:steady221 * 222 * @event 'swiperightdown'223 *		Is triggered after a rightwards and downwards swipe move gesture 224 *	obj.description:225 *		swipe:1:right:down226 *		swipe:2:right:down227 *		swipe:3:right:down228 *		swipe:4:right:down229 * 230 * @event 'swipedown'231 *		Is triggered after a  strict downwards swipe move gesture 232 *	obj.description:233 *		swipe:1:steady:down234 *		swipe:2:steady:down235 *		swipe:3:steady:down236 *		swipe:4:steady:down237 * 238  * @event 'swipeleftdown'239 *		Is triggered after a leftwards and downwards swipe move gesture 240 *	obj.description:241 *		swipe:1:left:down242 *		swipe:2:left:down243 *		swipe:3:left:down244 *		swipe:4:left:down245  * 246  * @event 'swipeleft'247 *		Is triggered after a strict leftwards swipe move gesture 248 *	obj.description:249 *		swipe:1:left:steady250 *		swipe:2:left:steady251 *		swipe:3:left:steady252 *		swipe:4:left:steady253   * 254  * @event 'swipeleftup'255 *		Is triggered after a leftwards and upwards swipe move gesture 256 *	obj.description:257 *		swipe:1:left:up258 *		swipe:2:left:up259 *		swipe:3:left:up260 *		swipe:4:left:up261 * 262  * @event 'tapone'263 *		Is triggered after a single (one finger) tap gesture 264 *	obj.description:265 *		tapone266* 267  * @event 'taptwo'268 *		Is triggered after a double (two finger) tap gesture 269 *	obj.description:270 *		taptwo271 * * 272  * @event 'tapthree'273 *		Is triggered after a tripple (three finger) tap gesture 274 *	obj.description:275 *		tapthree276 * 277 *  278 * Gestureend events:279 *	A gesture is an interpretation of different touchpoints. 280 *	The jGesture-Events in this group are triggered when a gesture has finished 281 *	and the touchpoints are removed from the device.282 *283 * @event 'pinchopen'284 *		Is triggered when a pinchopen gesture (two fingers moving away from each 285 *		other) occured and the touchpoints (fingers) are removed the device. 286 *	obj.description:287 *		pinch:+1:open288 * 289 * @event 'pinchclose'290 *		Is triggered when a pinchclose gesture (two fingers moving towards each 291 *		other) occured and the touchpoints (fingers) are removed the device. 292 *	obj.description:293 *		pinch:-1:close294 * 295 * @event 'rotatecw'296 *		Is triggered when a clockwise rotation gesture (two fingers rotating 297 *		clockwise) occured and the touchpoints (fingers) are removed the device.298 *	obj.description:299 *		rotate:+1:+clockwise300 * 301 * @event 'rotateccw'302 *		Is triggered when a counterclockwise rotation gesture (two fingers 303 *		rotating counterclockwise) occured and the touchpoints (fingers) are 304 *		removed the device.305 *	obj.description:306 *		rotate:-1:+counterclockwise307 * 308 * @example309 *		.bind( eventType, [ eventData ], handler(eventObject) )310 * jQuery('body').bind('tapone',function(){alert(arguments[1].description);})311  312313 */314315 (function ($) {316317     /**318     * General thresholds.319     */320     $.jGestures = {};321     $.jGestures.defaults = {};322     $.jGestures.defaults.thresholdPinchopen = 0.05;323     $.jGestures.defaults.thresholdPinchmove = 0.05;324     $.jGestures.defaults.thresholdPinch = 0.05;325     $.jGestures.defaults.thresholdPinchclose = 0.05;326     $.jGestures.defaults.thresholdRotatecw = 5; //deg327     $.jGestures.defaults.thresholdRotateccw = 5; // deg328     // a tap becomes a swipe if x/y values changes are above this threshold  329     $.jGestures.defaults.thresholdMove = 20;330     $.jGestures.defaults.thresholdSwipe = 100;331     $.jGestures.data = {};332     // get capable user agents 333     $.jGestures.data.capableDevicesInUserAgentString = ['iPad', 'iPhone', 'iPod', 'Mobile Safari']; // basic functionality such as swipe, pinch, rotate, tap should work on every mobile safari, e.g. GalaxyTab 334     $.jGestures.data.hasGestures = (function () { var _i; for (_i = 0; _i < $.jGestures.data.capableDevicesInUserAgentString.length; _i++) { if (navigator.userAgent.indexOf($.jGestures.data.capableDevicesInUserAgentString[_i]) !== -1) { return true; } } return false; })();335     $.hasGestures = $.jGestures.data.hasGestures;336     $.jGestures.events = {337         touchstart: 'jGestures.touchstart',338         touchendStart: 'jGestures.touchend;start',339         touchendProcessed: 'jGestures.touchend;processed',340         gesturestart: 'jGestures.gesturestart',341         gestureendStart: 'jGestures.gestureend;start',342         gestureendProcessed: 'jGestures.gestureend;processed'343     };344345     jQuery346		.each({347		    // "first domevent necessary"_"touch event+counter" : "exposed as"348		    // event: orientationchange349		    orientationchange_orientationchange01: "orientationchange",350		    // event: gestures351		    gestureend_pinchopen01: "pinchopen",352		    gestureend_pinchclose01: "pinchclose",353		    gestureend_rotatecw01: 'rotatecw',354		    gestureend_rotateccw01: 'rotateccw',355		    // move events356		    gesturechange_pinch01: 'pinch',357		    gesturechange_rotate01: 'rotate',358		    touchstart_swipe13: 'swipemove',359		    // event: touches360		    touchstart_swipe01: "swipeone",361		    touchstart_swipe02: "swipetwo",362		    touchstart_swipe03: "swipethree",363		    touchstart_swipe04: "swipefour",364		    touchstart_swipe05: 'swipeup',365		    touchstart_swipe06: 'swiperightup',366		    touchstart_swipe07: 'swiperight',367		    touchstart_swipe08: 'swiperightdown',368		    touchstart_swipe09: 'swipedown',369		    touchstart_swipe10: 'swipeleftdown',370		    touchstart_swipe11: 'swipeleft',371		    touchstart_swipe12: 'swipeleftup',372		    touchstart_tap01: 'tapone',373		    touchstart_tap02: 'taptwo',374		    touchstart_tap03: 'tapthree',375		    touchstart_tap04: 'tapfour'376		},377378     /**379     * Add gesture events inside the jQuery.event.special namespace 380     */381		function (sInternal_, sPublicFN_) {382383		    // add as funciton to jQuery.event.special.sPublicFN_ 384		    jQuery.event.special[sPublicFN_] = {385386		        /**387		        * When the first event handler is bound, jQuery executes the setup function.388		        * This plugin just uses one eventhandler per element, regardless of the number of bound events.389		        * All Events are stored internally as properties on the dom-element using the $.data api. 390		        * The setup-function adds the eventlistener, acting as a proxy function for the internal events.391		        * $.data.ojQueryGestures[_sDOMEvent ('tap') ] = {Boolean}392		        * @return {Void}393		        */394		        setup: function () {395396		            // split the arguments to necessary controll arguements397		            var _aSplit = sInternal_.split('_');398		            var _sDOMEvent = _aSplit[0]; // 399		            // get the associated gesture event and strip the counter: necessary for distinguisihng similliar events such as tapone-tapfour400		            var _sGestureEvent = _aSplit[1].slice(0, _aSplit[1].length - 2);401		            var _$element = jQuery(this);402		            // bind the event handler on the first $.bind() for a gestureend-event, set marker403		            if (!_$element.data('ojQueryGestures') || !_$element.data('ojQueryGestures')[_sDOMEvent]) {404		                // setup pseudo event405		                var _oDatajQueryGestures = _$element.data('ojQueryGestures') || {};406		                var oObj = {};407		                // marker for:  domEvent being set on this element 408		                // e.g.: $.data.oGestureInternals['touchstart'] = true;409		                // since they're grouped, i'm just marking the first one being added410		                oObj[_sDOMEvent] = true;411		                $.extend(true, _oDatajQueryGestures, oObj);412		                _$element.data('ojQueryGestures', _oDatajQueryGestures);413		                // add gesture events414		                if ($.hasGestures) {415		                    switch (_sGestureEvent) {416417		                        // event: orientationchange  418		                        case 'orientationchange':419		                            _$element.get(0).addEventListener('orientationchange', _onOrientationchange, false);420		                            break;421422		                        // event:   423		                        // - touchstart  424		                        // - touchmove  425		                        // - touchend  426		                        case 'tap':427		                        case 'swipe':428		                        case 'swipeup':429		                        case 'swiperightup':430		                        case 'swiperight':431		                        case 'swiperightdown':432		                        case 'swipedown':433		                        case 'swipeleftdown':434		                        case 'swipeleft':435		                            _$element.get(0).addEventListener('touchstart', _onTouchstart, false);436		                            break;437438		                        // event: gestureend  439		                        case 'pinchopen':440		                        case 'pinchclose':441		                        case 'rotatecw':442		                        case 'rotateccw':443		                            _$element.get(0).addEventListener('gesturestart', _onGesturestart, false);444		                            _$element.get(0).addEventListener('gestureend', _onGestureend, false);445		                            break;446447		                        // event: gesturechange  448		                        case 'pinch':449		                        case 'rotate':450		                            _$element.get(0).addEventListener('gesturestart', _onGesturestart, false);451		                            _$element.get(0).addEventListener('gesturechange', _onGesturechange, false);452		                            break;453		                    }454		                }455		                // create substitute for gesture events 456		                else {457		                    switch (_sGestureEvent) {458		                        // event substitutes:   459		                        // - touchstart: mousedown  460		                        // - touchmove: none  461		                        // - touchend: mouseup  462		                        case 'tap':463		                        case 'swipe':464		                            // _$element.get(0).addEventListener('mousedown', _onTouchstart, false);465		                            _$element.bind('mousedown', _onTouchstart);466		                            break;467468		                        // no substitution  469		                        case 'orientationchange':470		                        case 'pinchopen':471		                        case 'pinchclose':472		                        case 'rotatecw':473		                        case 'rotateccw':474		                        case 'pinch':475		                        case 'rotate':476477		                            break;478		                    }479		                }480481		            }482		            return false;483		        },484485		        /**486		        * For every $.bind(GESTURE) the add-function will be called.487		        * Instead of binding an actual eventlister, the event is stored as $.data on the element.488		        * The handler will be triggered using $.triggerHandler(GESTURE) if the internal 489		        * eventhandler (proxy being bound on setup()) detects a GESTURE event490		        * @param {Object} event_ jQuery-Event-Object being passed by $.bind() 491		        * @return {Void}492		        */493		        add: function (event_) {494		            // add pseudo event: properties on $.data 495		            var _$element = jQuery(this);496		            var _oDatajQueryGestures = _$element.data('ojQueryGestures');497		            //					_oDatajQueryGestures[event_.type] = { 'originalType' : event_.type , 'threshold' : event_.data.threshold, 'preventDefault' : event_.data.preventDefault } ;498		            _oDatajQueryGestures[event_.type] = { 'originalType': event_.type };499		            return false;500		        },501502		        /**503		        * For every $.unbind(GESTURE) the remove-function will be called.504		        * Instead of removing the actual eventlister, the event is removed from $.data on the element.505		        * @param {Object} event_ jQuery-Event-Object being passed by $.bind() 506		        * @return {Void}507		        */508		        remove: function (event_) {509		            // remove pseudo event: properties on $.data 510		            var _$element = jQuery(this);511		            var _oDatajQueryGestures = _$element.data('ojQueryGestures');512		            _oDatajQueryGestures[event_.type] = false;513		            _$element.data('ojQueryGestures', _oDatajQueryGestures);514		            return false;515		        },516517		        /**518		        * The last $.unbind()-call on the domElement triggers the teardown function 519		        * removing the eventlistener520		        * @return {Void}521		        */522		        // @TASK: maybe rework teardown to work with event type?!523		        teardown: function () {524		            // split the arguments to necessary controll arguements525		            var _aSplit = sInternal_.split('_');526		            var _sDOMEvent = _aSplit[0]; // 527		            // get the associated gesture event and strip the counter: necessary for distinguisihng similliar events such as tapone-tapfour528		            var _sGestureEvent = _aSplit[1].slice(0, _aSplit[1].length - 2);529		            var _$element = jQuery(this);530		            // bind the event handler on the first $.bind() for a gestureend-event, set marker531		            if (!_$element.data('ojQueryGestures') || !_$element.data('ojQueryGestures')[_sDOMEvent]) {532		                // setup pseudo event533		                var _oDatajQueryGestures = _$element.data('ojQueryGestures') || {};534		                var oObj = {};535		                // remove marker for:  domEvent being set on this element 536		                oObj[_sDOMEvent] = false;537		                $.extend(true, _oDatajQueryGestures, oObj);538		                _$element.data('ojQueryGestures', _oDatajQueryGestures);539540		                // remove gesture events541		                if ($.hasGestures) {542		                    switch (_sGestureEvent) {543544		                        // event: orientationchange  545		                        case 'orientationchange':546		                            _$element.get(0).removeEventListener('orientationchange', _onOrientationchange, false);547		                            break;548549		                        // event :   550		                        // - touchstart  551		                        // - touchmove  552		                        // - touchend  553		                        case 'tap':554		                        case 'swipe':555		                        case 'swipeup':556		                        case 'swiperightup':557		                        case 'swiperight':558		                        case 'swiperightdown':559		                        case 'swipedown':560		                        case 'swipeleftdown':561		                        case 'swipeleft':562		                        case 'swipeleftup':563		                            _$element.get(0).removeEventListener('touchstart', _onTouchstart, false);564		                            _$element.get(0).removeEventListener('touchmove', _onTouchmove, false);565		                            _$element.get(0).removeEventListener('touchend', _onTouchend, false);566		                            break;567568		                        // event: gestureend  569		                        case 'pinchopen':570		                        case 'pinchclose':571		                        case 'rotatecw':572		                        case 'rotateccw':573		                            _$element.get(0).removeEventListener('gesturestart', _onGesturestart, false);574		                            _$element.get(0).removeEventListener('gestureend', _onGestureend, false);575		                            break;576577		                        // event: gesturechange  578		                        case 'pinch':579		                        case 'rotate':580		                            _$element.get(0).removeEventListener('gesturestart', _onGesturestart, false);581		                            _$element.get(0).removeEventListener('gesturechange', _onGesturechange, false);582		                            break;583		                    }584		                }585		                // remove substitute for gesture events 586		                else {587		                    switch (_sGestureEvent) {588		                        // event substitutes:   589		                        // - touchstart: mousedown  590		                        // - touchmove: none  591		                        // - touchend: mouseup  592		                        case 'tap':593		                        case 'swipe':594		                            //									_$element.get(0).removeEventListener('mousedown', _onTouchstart, false);595		                            //									_$element.get(0).removeEventListener('mousemove', _onTouchmove, false);596		                            //									_$element.get(0).removeEventListener('mouseup', _onTouchend, false);597		                            _$element.unbind('mousedown', _onTouchstart);598		                            _$element.unbind('mousemove', _onTouchmove);599		                            _$element.unbind('mouseup', _onTouchend);600		                            break;601602		                        // no substitution  603		                        case 'orientationchange':604		                        case 'pinchopen':605		                        case 'pinchclose':606		                        case 'rotatecw':607		                        case 'rotateccw':608		                        case 'pinch':609		                        case 'rotate':610611		                            break;612		                    }613		                }614615		            }616		            return false;617		        }618619		    };620		});621622     /**623     * Creates the object that ist passed as second argument to the $element.triggerHandler function.624     * This object contains detailed informations about the gesture event.625     * @param {Object} oOptions_  {type: {String}, touches: {String}, deltaY: {String},deltaX : {String}, startMove: {Object}, event:{DOM-Event}, timestamp:{String},vector: {Number}}626     * @example _createOptions (627     *				{ 628     *					type: 'swipemove', 629     *					touches: '1', 630     *					deltaY: _iDeltaY,631     *					deltaX : _iDeltaX, 632     *					startMove: _oDatajQueryGestures.oStartTouch, 633     *					event:event_, 634     *					timestamp:_oEventData.timestamp,635     *					vector: -1636     *				}637     *			);638     * @returns {Object} 639     *			{640     *				type: eventtype e.g. "swipe","pinch",641     *				originalEvent: {DOM-Event},642     *				// default: just one entry on the delta-array - the first touchpoint643     *				// the first touchpoint is the reference point for every gesture, 644     *				// because moving touchpoints in various directions would result in 645     *				// a gesture.646     *				// delta and direction details are just provided for touch not for gesture events647     *				delta : [ 648     *					{649     *						lastX:{Number} , // x-axis: relative to the last touchevent (e.g. touchmove!)650     *						lastY:{Number}, // y-axis: relative to the last touchevent (e.g. touchmove!)651     *						moved: {Number},  // distance: relative to the original touchpoint 652     *						startX: {Number} , // relative to the original touchpoint653     *						startY: {Number} ,// relative to the original touchpoint654     *					} ],655     *				// based on the first touchpoint656     *				direction : { // relative to the last touchevent (e.g. touchmove!)657     *					vector: {Number}, // -1|+1, indicates the direction if necessary(pinch/rotate)658     *					orientation: {Number} // window.orientation: -90,0,90,180 || null (window.orienntation)659     *					lastX : {Number}, // -1,0,+1 relative to the last touchevent (e.g. touchmove!)660     *					lastY : {Number}, // -1,0,+1 relative to the last touchevent (e.g. touchmove!)661     *					startX: {Number} , //-1,0,+1 relative to the original touchpoint662     *					startY: {Number} ,// -1,0,+1 relative to the original touchpoint663     *				},664     *				rotation: {Number} || {null}, // gestureonly: amount of rotation relative to the current position NOT the original 665     *				scale: {Number} || {null}, // gestureonly: amount of scaling relative to the current position NOT the original 666     *				duration: {Number}, // ms: relative to the original touchpoint 667     *				description : {String} // details as String: {TYPE *}:{TOUCHES 1|2|3|4}:{X-AXIS 'right'|'left'|'steady'}:{Y-AXIS 'down'|'up'|'steady'} e.g. "swipe:1:left:steady" relative to the last touchpoint668     *			};669     */670     function _createOptions(oOptions_) {671         // force properties672         oOptions_.startMove = (oOptions_.startMove) ? oOptions_.startMove : { startX: null, startY: null, timestamp: null };673         var _iNow = new Date().getTime();674675         // calculate touch differences 676         if (oOptions_.touches) {677             // store delta values678             var _oDelta = [679				{680				    lastX: oOptions_.deltaX,681				    lastY: oOptions_.deltaY,682				    moved: null,683				    startX: oOptions_.screenX - oOptions_.startMove.screenX,684				    startY: oOptions_.screenY - oOptions_.startMove.screenY685				}686			];687688             var _oDirection = {689                 vector: oOptions_.vector,690                 orientation: window.orientation || null,691                 lastX: ((_oDelta[0].lastX > 0) ? +1 : ((_oDelta[0].lastX < 0) ? -1 : 0)),692                 lastY: ((_oDelta[0].lastY > 0) ? +1 : ((_oDelta[0].lastY < 0) ? -1 : 0)),693                 startX: ((_oDelta[0].startX > 0) ? +1 : ((_oDelta[0].startX < 0) ? -1 : 0)),694                 startY: ((_oDelta[0].startY > 0) ? +1 : ((_oDelta[0].startY < 0) ? -1 : 0))695             };696697             // calculate distance traveled using the pythagorean theorem		698             _oDelta[0].moved = Math.sqrt(Math.pow(Math.abs(_oDelta[0].startX), 2) + Math.pow(Math.abs(_oDelta[0].startY), 2));699700         }701         return {702             type: oOptions_.type || null,703             originalEvent: oOptions_.event || null,704             delta: _oDelta || null,705             direction: _oDirection || { orientation: window.orientation || null, vector: oOptions_.vector || null },706             duration: (oOptions_.startMove.timestamp) ? _iNow - oOptions_.timestamp : null,707             rotation: oOptions_.rotation || null,708             scale: oOptions_.scale || null,709             description: oOptions_.description || [710				oOptions_.type,711				':',712				oOptions_.touches,713				':',714				((_oDelta[0].lastX != 0) ? ((_oDelta[0].lastX > 0) ? 'right' : 'left') : 'steady'),715				':',716				((_oDelta[0].lastY != 0) ? ((_oDelta[0].lastY > 0) ? 'down' : 'up') : 'steady')717				].join('')718         };719720     }721722723724     /**725     * DOM-event handlers726     */727728     /**729     * Handler: orientationchange730     * Triggers the bound orientationchange handler on the window element731     * The "orientationchange" handler will receive an object with additional information732     * about the event.733     *  {734     * 	direction : {735     * 		orientation: {-90|0|90|180}736     * 	},737     * 	description : [738     * 		'orientationchange:{landscape:clockwise:|portrait:default|landscape:counterclockwise|portrait:upsidedown}:{-90|0|90|180}' // e.g. 'orientation:landscape:clockwise:-90739     * 	}740     * @param {DOM-Event} event_741     * @return {Void}742     */743     function _onOrientationchange(event_) {744745         // window.orientation: -90,0,90,180746         var _aDict = ['landscape:clockwise:', 'portrait:default:', 'landscape:counterclockwise:', 'portrait:upsidedown:'];747748         $(window).triggerHandler('orientationchange',749			{750			    direction: { orientation: window.orientation },751			    description: [752					'orientationchange:',753					_aDict[((window.orientation / 90) + 1)],754					window.orientation755					].join('')756			});757     }758759760     /**761     * Handler: touchstart or mousedown762     * Setup pseudo-event by storing initial values such as :763     *		screenX : {Number}764     *	screenY : {Number}765     *	timestamp: {Number}766     *  on the pseudo gesture event and 767     *  sets up additional eventlisteners for handling touchmove events.768     * @param {DOM-Event} event_769     * @return {Void}770     */771     function _onTouchstart(event_) {772773         // ignore bubbled handlers774         // if ( event_.currentTarget !== event_.target ) { return; }775776         var _$element = jQuery(event_.currentTarget);777         // var _$element = jQuery(event_.target); 778779         // trigger custom notification780         _$element.triggerHandler($.jGestures.events.touchstart, event_);781782783         // set the necessary touch events784         if ($.hasGestures) {785             event_.currentTarget.addEventListener('touchmove', _onTouchmove, false);786             event_.currentTarget.addEventListener('touchend', _onTouchend, false);787         }788         // event substitution789         else {790             //			event_.currentTarget.addEventListener('mousemove', _onTouchmove, false);791             //			event_.currentTarget.addEventListener('mouseup', _onTouchend, false);792             _$element.bind('mousemove', _onTouchmove);793             _$element.bind('mouseup', _onTouchend);794         }795796         // get stored pseudo event797         var _oDatajQueryGestures = _$element.data('ojQueryGestures');798799         // var _oEventData = _oDatajQueryGestures[_sType];800         var _eventBase = (event_.touches) ? event_.touches[0] : event_;801         // store current values for calculating relative values (changes between touchmoveevents)802         var _oObj = {};803         _oObj.oLastSwipemove = { screenX: _eventBase.screenX, screenY: _eventBase.screenY, timestamp: new Date().getTime() };804         _oObj.oStartTouch = { screenX: _eventBase.screenX, screenY: _eventBase.screenY, timestamp: new Date().getTime() };805806         _$element.data('ojQueryGestures', $.extend(true, _oDatajQueryGestures, _oObj));807     }808809810     /**811     * Handler: touchmove or mousemove812     * Calculates the x/y changes since the last event, 813     * compares it to $.jGestures.defaults.thresholdMove and triggers 814     * an swipemove event if the distance exceed the 815     * threshold.816     * Custom-event argument object: 817     * {Object} 818     *			{819     *				type: e.g. 'swipemove',820     *				â: {DOM-Event},821     *				// default: just one entry on the delta-array - the first touchpoint822     *				// the first touchpoint is the reference point for every gesture, 823     *				// because moving touchpoints in various directions would result in 824     *				// a gesture.825     *				// delta and direction details are just provided for touch not for gesture events826     *				delta : [ 827     *					{828     *						lastX:{Number} , // x-axis: relative to the last touchevent (e.g. touchmove!)829     *						lastY:{Number}, // y-axis: relative to the last touchevent (e.g. touchmove!)830     *						moved: {Number},  // distance: relative to the original touchpoint 831     *						startX: {Number} , // relative to the original touchpoint832     *						startY: {Number} ,// relative to the original touchpoint833     *					} ],834     *				// based on the first touchpoint835     *				direction : { // relative to the last touchevent (e.g. touchmove!)836     *					vector: {Number}, // -1|+1, indicates the direction if necessary(pinch/rotate)837     *					orientation: {Number} // window.orientation: -90,0,90,180 || null (window.orienntation)838     *					lastX : {Number}, // -1,0,+1 relative to the last touchevent (e.g. touchmove!)839     *					lastY : {Number}, // -1,0,+1 relative to the last touchevent (e.g. touchmove!)840     *					startX: {Number} , //-1,0,+1 relative to the original touchpoint841     *					startY: {Number} ,// -1,0,+1 relative to the original touchpoint842     *				},843     *				rotation: {null}, // gestureonly: amount of rotation relative to the current position NOT the original 844     *				scale: {null}, // gestureonly: amount of scaling relative to the current position NOT the original 845     *				duration: {Number}, // ms: relative to the original touchpoint 846     *				description : {String} // details as String: {TYPE *}:{TOUCHES 1|2|3|4}:{X-AXIS 'right'|'left'|'steady'}:{Y-AXIS 'down'|'up'|'steady'} e.g. "swipe:1:left:steady" relative to the last touchpoint847     *			};848     *		description : {String} // details as String: swipemove:1:{X-AXIS 'right'|'left'|'steady'}:{Y-AXIS 'down'|'up'|'steady'} e.g. "swipemove:1:left:steady"849     *	};850     * @param {DOM-Event} event_851     * @return {Void}852     */853     function _onTouchmove(event_) {854855         var _$element = jQuery(event_.currentTarget);856         // var _$element = jQuery(event_.target); 857858         // get stored pseudo event859         var _oDatajQueryGestures = _$element.data('ojQueryGestures');860861         var _bHasTouches = !!event_.touches;862         var _iScreenX = (_bHasTouches) ? event_.changedTouches[0].screenX : event_.screenX;863         var _iScreenY = (_bHasTouches) ? event_.changedTouches[0].screenY : event_.screenY;864865         //relative to the last event866         var _oEventData = _oDatajQueryGestures.oLastSwipemove;867         var _iDeltaX = _iScreenX - _oEventData.screenX;868         var _iDeltaY = _iScreenY - _oEventData.screenY;869870         // there's a swipemove set (not the first occurance), trigger event 871         if (!!_oDatajQueryGestures.oLastSwipemove) {872             // check 873             var _oDetails = _createOptions({ type: 'swipemove', touches: (_bHasTouches) ? event_.touches.length : '1', screenY: _iScreenY, screenX: _iScreenX, deltaY: _iDeltaY, deltaX: _iDeltaX, startMove: _oEventData, event: event_, timestamp: _oEventData.timestamp });874             _$element.triggerHandler(_oDetails.type, _oDetails);875         }876         // store the new values877         var _oObj = {};878         var _eventBase = (event_.touches) ? event_.touches[0] : event_;879         _oObj.oLastSwipemove = { screenX: _eventBase.screenX, screenY: _eventBase.screenY, timestamp: new Date().getTime() };880         _$element.data('ojQueryGestures', $.extend(true, _oDatajQueryGestures, _oObj));881     }882883884     /**885     * Handler: touchend or mouseup886     * Removes the additional handlers (move/end)887     * Calculates the x/y changes since the touchstart event888     * not in relation to the last move event.889     * Triggers the  890     *	swipeone|swipetwo|swipethree|swipefour|891     *	swipeup|swiperightup|swiperight|swiperightdown|swipedown|892     *	swipeleftdown|swipeleft|swipeleftup|893     *	tapone|taptwo|tapthree|tapfour 894     * event.895     *		{Object} 896     *			{897     *				type: eventtype e.g. "swipeone","swipeleftdown",898     *				originalEvent: {DOM-Event},899     *				// default: just one entry on the delta-array - the first touchpoint900     *				// the first touchpoint is the reference point for every gesture, 901     *				// because moving touchpoints in various directions would result in 902     *				// a gesture.903     *				// delta and direction details are just provided for touch not for gesture events904     *				delta : [ 905     *					{906     *						lastX:{Number} , // x-axis: relative to the last touchevent (e.g. touchmove!)907     *						lastY:{Number}, // y-axis: relative to the last touchevent (e.g. touchmove!)908     *						moved: {Number},  // distance: relative to the original touchpoint 909     *						startX: {Number} , // relative to the original touchpoint910     *						startY: {Number} ,// relative to the original touchpoint911     *					} ],912     *				// based on the first touchpoint913     *				direction : { // relative to the last touchevent (e.g. touchmove!)914     *					vector: {Number}, // -1|+1, indicates the direction if necessary(pinch/rotate)915     *					orientation: {Number} // window.orientation: -90,0,90,180 || null (window.orienntation)916     *					lastX : {Number}, // -1,0,+1 relative to the last touchevent (e.g. touchmove!)917     *					lastY : {Number}, // -1,0,+1 relative to the last touchevent (e.g. touchmove!)918     *					startX: {Number} , //-1,0,+1 relative to the original touchpoint919     *					startY: {Number} ,// -1,0,+1 relative to the original touchpoint920     *				},921     *				rotation: {null}, 922     *				scale: {null} , 923     *				duration: {Number}, // ms: relative to the original touchpoint 924     *				description : {String} // details as String: {TYPE *}:{TOUCHES 1|2|3|4}:{X-AXIS 'right'|'left'|'steady'}:{Y-AXIS 'down'|'up'|'steady'} e.g. "swipe:1:left:steady" relative to the last touchpoint925     *			};926     * @param {DOM-Event} event_927     * @return {Void}928     */929     function _onTouchend(event_) {930931         // ignore bubbled handlers932         // if ( event_.currentTarget !== event_.target ) { return; }933934         var _$element = jQuery(event_.currentTarget);935         var _bHasTouches = !!event_.changedTouches;936         var _iTouches = (_bHasTouches) ? event_.changedTouches.length : '1';937         var _iScreenX = (_bHasTouches) ? event_.changedTouches[0].screenX : event_.screenX;938         var _iScreenY = (_bHasTouches) ? event_.changedTouches[0].screenY : event_.screenY;939940         // trigger custom notification941         _$element.triggerHandler($.jGestures.events.touchendStart, event_);942943         // var _$element = jQuery(event_.target); 944         // remove events945         if ($.hasGestures) {946             event_.currentTarget.removeEventListener('touchmove', _onTouchmove, false);947             event_.currentTarget.removeEventListener('touchend', _onTouchend, false);948         }949         // event substitution950         else {951             //			event_.currentTarget.removeEventListener('mousemove', _onTouchmove, false);952             //			event_.currentTarget.removeEventListener('mouseup', _onTouchend, false);953             _$element.unbind('mousemove', _onTouchmove);954             _$element.unbind('mouseup', _onTouchend);955         }956         // get all bound pseudo events957         var _oDatajQueryGestures = _$element.data('ojQueryGestures');958959         // if the current change on the x/y position is above the defined threshold for moving an element set the moved flag 960         // to distinguish between a moving gesture and a shaking finger trying to tap961         var _bHasMoved = (962			Math.abs(_oDatajQueryGestures.oStartTouch.screenX - _iScreenX) > $.jGestures.defaults.thresholdMove ||963			Math.abs(_oDatajQueryGestures.oStartTouch.screenY - _iScreenY) > $.jGestures.defaults.thresholdMove964		) ? true : false;965966         // if the current change on the x/y position is above the defined threshold for swiping set the moved flag 967         // to indicate we're dealing with a swipe gesture968         var _bHasSwipeGesture = (969			Math.abs(_oDatajQueryGestures.oStartTouch.screenX - _iScreenX) > $.jGestures.defaults.thresholdSwipe ||970			Math.abs(_oDatajQueryGestures.oStartTouch.screenY - _iScreenY) > $.jGestures.defaults.thresholdSwipe971		) ? true : false;972973974         var _sType;975         // trigger events for all bound pseudo events on this element 976         for (_sType in _oDatajQueryGestures) {977978             // get current pseudo event979             var _oEventData = _oDatajQueryGestures.oStartTouch;980981             var _oDelta = {};982             var _iScreenX = (_bHasTouches) ? event_.changedTouches[0].screenX : event_.screenX;983             var _iScreenY = (_bHasTouches) ? event_.changedTouches[0].screenY : event_.screenY;984             // calculate distances in relation to the touchstart position not the last touchmove event!985             var _iDeltaX = _iScreenX - _oEventData.screenX;986             var _iDeltaY = _iScreenY - _oEventData.screenY;987             var _oDetails = _createOptions({ type: 'swipe', touches: _iTouches, screenY: _iScreenY, screenX: _iScreenX, deltaY: _iDeltaY, deltaX: _iDeltaX, startMove: _oEventData, event: event_, timestamp: _oEventData.timestamp });988989             var _aDict = ['zero', 'one', 'two', 'three', 'four'];990991             // swipe marker992             var _bIsSwipe = false;993994             // trigger bound events on this element995             switch (_sType) {996                 case 'swipeone':997998                     if (_bHasTouches === false && _iTouches == 1 && _bHasMoved === false) {999                         // trigger tapone!1000                         break;1001                     }1002                     if (_bHasTouches === false || (_iTouches == 1 && _bHasMoved === true && _bHasSwipeGesture === true)) {1003                         _bIsSwipe = true;10041005                         _oDetails.type = ['swipe', _aDict[_iTouches]].join('');1006                         _$element.triggerHandler(_oDetails.type, _oDetails);1007                     }1008                     break;10091010                 case 'swipetwo':1011                     if ((_bHasTouches && _iTouches == 2 && _bHasMoved === true && _bHasSwipeGesture === true)) {1012                         _bIsSwipe = true;1013                         _oDetails.type = ['swipe', _aDict[_iTouches]].join('');1014                         _$element.triggerHandler(_oDetails.type, _oDetails);1015                     }1016                     break;10171018                 case 'swipethree':1019                     if ((_bHasTouches && _iTouches == 3 && _bHasMoved === true && _bHasSwipeGesture === true)) {1020                         _bIsSwipe = true;1021                         _oDetails.type = ['swipe', _aDict[_iTouches]].join('');1022                         _$element.triggerHandler(_oDetails.type, _oDetails);1023                     }1024                     break;10251026                 case 'swipefour':1027                     if ((_bHasTouches && _iTouches == 4 && _bHasMoved === true && _bHasSwipeGesture === true)) {1028                         _bIsSwipe = true;1029                         _oDetails.type = ['swipe', _aDict[_iTouches]].join('');1030                         _$element.triggerHandler(_oDetails.type, _oDetails);1031                     }1032                     break;10331034                 case 'swipeup':1035                 case 'swiperightup':1036                 case 'swiperight':1037                 case 'swiperightdown':1038                 case 'swipedown':1039                 case 'swipeleftdown':1040                 case 'swipeleft':1041                 case 'swipeleftup':1042                     if (_bHasTouches && _bHasMoved === true && _bHasSwipeGesture === true) {1043                         _bIsSwipe = true;1044                         _oDetails.type = [1045									'swipe',1046								((_oDetails.delta[0].lastX != 0) ? ((_oDetails.delta[0].lastX > 0) ? 'right' : 'left') : ''),1047								((_oDetails.delta[0].lastY != 0) ? ((_oDetails.delta[0].lastY > 0) ? 'down' : 'up') : '')1048									].join('');1049                         if (_sType == _oDetails.type) {1050                             _$element.triggerHandler(_oDetails.type, _oDetails);1051                         }1052                     }1053                     break;10541055                 case 'tapone':1056                 case 'taptwo':1057                 case 'tapthree':1058                 case 'tapfour':1059                     if (( /* _bHasTouches && */_bHasMoved !== true && _bIsSwipe !== true) && (_aDict[_iTouches] == _sType.slice(3))) {1060                         _oDetails.description = ['tap', _aDict[_iTouches]].join('');1061                         _oDetails.type = ['tap', _aDict[_iTouches]].join('');1062                         _$element.triggerHandler(_oDetails.type, _oDetails);1063                     }1064                     break;10651066             }10671068             // refresh pseudo events1069             var _oObj = {};1070             //			_oObj[_sType] = false;1071             //			_oObj.hasTouchmoved = false;1072             _$element.data('ojQueryGestures', $.extend(true, _oDatajQueryGestures, _oObj));1073             _$element.data('ojQueryGestures', $.extend(true, _oDatajQueryGestures, _oObj));10741075         }1076         _$element.triggerHandler($.jGestures.events.touchendProcessed, event_);1077     }107810791080     /**1081     * Handler: gesturestart1082     * Setup pseudo-event by storing initial values such as :1083     *	timestamp: {Number}1084     *  on the pseudo gesture event1085     * Since the gesture-event doesn't supply event.touches no tuchpoints will be calculated 1086     * @param {DOM-Event} event_1087     * @return {Void}1088     */1089     function _onGesturestart(event_) {10901091         // ignore bubbled handlers1092         // if ( event_.currentTarget !== event_.target ) { return; }10931094         var _$element = jQuery(event_.currentTarget);1095         // var _$element = jQuery(event_.target); 10961097         // trigger custom notification1098         _$element.triggerHandler($.jGestures.events.gesturestart, event_);109911001101         // get stored pseudo event1102         var _oDatajQueryGestures = _$element.data('ojQueryGestures');11031104         // var _oEventData = _oDatajQueryGestures[_sType];1105         // store current values for calculating relative values (changes between touchmoveevents)1106         var _oObj = {};1107         _oObj.oStartTouch = { timestamp: new Date().getTime() };1108         _$element.data('ojQueryGestures', $.extend(true, _oDatajQueryGestures, _oObj));1109     }11101111     /**1112     * Handler: gesturechange1113     * Read the event_.scale / event_.rotate values,1114     * an triggers a pinch|rotate event if necessary.1115     * Since the gesture-event doesn't supply event.touches no tuchpoints will be calculated1116     * @returns {Object} 1117     *			{1118     *				type: eventtype e.g. "pinch","rotate",1119     *				originalEvent: {DOM-Event},1120     *				// delta and direction details are just provided for touch not for gesture events1121     *				delta : null,1122     *				direction :null,1123     *				vector: {Number}, // -1|+1, indicates the direction if necessary(pinch/rotate)1124     *				orientation: {Number} // window.orientation: -90,0,90,180 || null (window.orienntation)1125     *				rotation: {Number} , //  amount of rotation relative to the current position NOT the original 1126     *				scale: {Number} , // amount of scaling relative to the current position NOT the original 1127     *				duration: {Number}, // ms: relative to the original touchpoint 1128     *				description : {String} // details as String: pinch:{'close'|'open'} e.g. "pinch:-1:close" ||  rotate:{'counterclockwise'|'clockwise'} e.g. "rotate:-1:counterclockwise"1129     *			};1130     * @param {DOM-Event} event_1131     * @return {Void}1132     */1133     function _onGesturechange(event_) {11341135         // ignore bubbled handlers1136         // if ( event_.currentTarget !== event_.target ) { return; }11371138         var _$element = jQuery(event_.currentTarget);1139         // var _$element = jQuery(event_.target); 1140         var _iDelta, _iDirection, _sDesc, _oDetails;1141         // get all pseudo events1142         var _oDatajQueryGestures = _$element.data('ojQueryGestures');11431144         // trigger events for all bound pseudo events on this element1145         var _sType;1146         for (_sType in _oDatajQueryGestures) {11471148             // trigger a specific bound event1149             switch (_sType) {11501151                 case 'pinch':1152                     _iDelta = event_.scale;1153                     if (((_iDelta < 1) && (_iDelta % 1) < (1 - $.jGestures.defaults.thresholdPinchclose)) || ((_iDelta > 1) && (_iDelta % 1) > ($.jGestures.defaults.thresholdPinchopen))) {1154                         _iDirection = (_iDelta < 1) ? -1 : +1;1155                         _oDetails = _createOptions({ type: 'pinch', scale: _iDelta, touches: null, startMove: _oDatajQueryGestures.oStartTouch, event: event_, timestamp: _oDatajQueryGestures.oStartTouch.timestamp, vector: _iDirection, description: ['pinch:', _iDirection, ':', ((_iDelta < 1) ? 'close' : 'open')].join('') });1156                         _$element.triggerHandler(_oDetails.type, _oDetails);1157                     }1158                     break;11591160                 case 'rotate':1161                     _iDelta = event_.rotation;1162                     if (((_iDelta < 1) && (-1 * (_iDelta) > $.jGestures.defaults.thresholdRotateccw)) || ((_iDelta > 1) && (_iDelta > $.jGestures.defaults.thresholdRotatecw))) {1163                         _iDirection = (_iDelta < 1) ? -1 : +1;1164                         _oDetails = _createOptions({ type: 'rotate', rotation: _iDelta, touches: null, startMove: _oDatajQueryGestures.oStartTouch, event: event_, timestamp: _oDatajQueryGestures.oStartTouch.timestamp, vector: _iDirection, description: ['rotate:', _iDirection, ':', ((_iDelta < 1) ? 'counterclockwise' : 'clockwise')].join('') });1165                         _$element.triggerHandler(_oDetails.type, _oDetails);1166                     }1167                     break;11681169             }1170         }11711172     }117311741175     /**1176     * Handler: gestureend1177     * Read the event_.scale / event_.rotate values,1178     * compares it to $.jGestures.defaults.threshold* and triggers 1179     * a pinchclose|pinchclose|rotatecw|rotateccw event if the distance exceed the 1180     * Since the gesture-event doesn't supply event.touches no tuchpoints will be calculated1181     * * Custom-event argument object: 1182     * @returns {Object} 1183     *			{1184     *				type: eventtype e.g. "pinchclose","pinchopen", "rotatecw", "rotateccw",1185     *				originalEvent: {DOM-Event},1186     *				// delta and direction details are just provided for touch not for gesture events1187     *				delta : null,1188     *				// based on the first touchpoint1189     *				direction : null // relative to the last touchevent (e.g. touchmove!)1190     *				vector: {Number}, // -1|+1, indicates the direction if necessary(pinch/rotate)1191     *				orientation: {Number} // window.orientation: -90,0,90,180 || null (window.orienntation)1192     *				rotation: {Number} , //  amount of rotation relative to the current position NOT the original 1193     *				scale: {Number} , // amount of scaling relative to the current position NOT the original 1194     *				duration: {Number}, // ms: relative to the original touchpoint 1195     *				description : {String} // details as String: pinch:{'close'|'open'} e.g. "pinch:-1:close" ||  rotate:{'counterclockwise'|'clockwise'} e.g. "rotate:-1:counterclockwise"1196     *			};1197     * @param {DOM-Event} event_1198     * @return {Void}1199     */1200     function _onGestureend(event_) {1201         // ignore bubbled handlers1202         // if ( event_.currentTarget !== event_.target ) { return; }12031204         var _$element = jQuery(event_.currentTarget);1205         // var _$element = jQuery(event_.target);12061207         // trigger custom notification1208         _$element.triggerHandler($.jGestures.events.gestureendStart, event_);12091210         var _iDelta;1211         var _oDatajQueryGestures = _$element.data('ojQueryGestures');12121213         // trigger handler for every bound event1214         var _sType;1215         for (_sType in _oDatajQueryGestures) {12161217             switch (_sType) {12181219                 case 'pinchclose':1220                     _iDelta = event_.scale;1221                     if ((_iDelta < 1) && (_iDelta % 1) < (1 - $.jGestures.defaults.thresholdPinchclose)) {1222                         _$element.triggerHandler('pinchclose', _createOptions({ type: 'pinchclose', scale: _iDelta, vector: -1, touches: null, startMove: _oDatajQueryGestures.oStartTouch, event: event_, timestamp: _oDatajQueryGestures.oStartTouch.timestamp, description: 'pinch:-1:close' }));1223                     }1224                     break;12251226                 case 'pinchopen':1227                     _iDelta = event_.scale;1228                     if ((_iDelta > 1) && (_iDelta % 1) > ($.jGestures.defaults.thresholdPinchopen)) {1229                         _$element.triggerHandler('pinchopen', _createOptions({ type: 'pinchopen', scale: _iDelta, vector: +1, touches: null, startMove: _oDatajQueryGestures.oStartTouch, event: event_, timestamp: _oDatajQueryGestures.oStartTouch.timestamp, description: 'pinch:+1:open' }));1230                     }1231                     break;12321233                 case 'rotatecw':1234                     _iDelta = event_.rotation;1235                     if ((_iDelta > 1) && (_iDelta > $.jGestures.defaults.thresholdRotatecw)) {1236                         _$element.triggerHandler('rotatecw', _createOptions({ type: 'rotatecw', rotation: _iDelta, vector: +1, touches: null, startMove: _oDatajQueryGestures.oStartTouch, event: event_, timestamp: _oDatajQueryGestures.oStartTouch.timestamp, description: 'rotate:+1:clockwise' }));1237                     }1238                     break;12391240                 case 'rotateccw':1241                     _iDelta = event_.rotation;1242                     if ((_iDelta < 1) && (-1 * (_iDelta) > $.jGestures.defaults.thresholdRotateccw)) {1243                         _$element.triggerHandler('rotateccw', _createOptions({ type: 'rotateccw', rotation: _iDelta, vector: -1, touches: null, startMove: _oDatajQueryGestures.oStartTouch, event: event_, timestamp: _oDatajQueryGestures.oStartTouch.timestamp, description: 'rotate:-1:counterclockwise' }));1244                     }1245                     break;12461247             }1248         }1249         _$element.triggerHandler($.jGestures.events.gestureendProcessed, event_);1250     }1251 }
...jgestures.js
Source:jgestures.js  
1/**2 * jGestures: a jQuery plugin for gesture events3 * Copyright 2010-2011 Neue Digitale / Razorfish GmbH4 * Copyright 2011-2012, Razorfish GmbH5 * Licensed under the Apache License, Version 2.0 (the "License");6 * you may not use this file except in compliance with the License.7 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.08 * Unless required by applicable law or agreed to in writing, software9 * distributed under the License is distributed on an "AS IS" BASIS,10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11 * See the License for the specific language governing permissions and12 * limitations under the License.13 * @copyright Razorfish GmbH14 * @author martin.krause@razorfish.de15 * @version 0.90-shake16 * @requires jQuery JavaScript Library v1.4.2 - http://jquery.com/- Copyright 2010, John Resig- Dual licensed under the MIT or GPL Version 2 licenses. http://jquery.org/license17 */18(function(c) {19    c.jGestures = {};20    c.jGestures.defaults = {};21    c.jGestures.defaults.thresholdShake = {22        requiredShakes: 10,23        freezeShakes: 100,24        frontback: {25            sensitivity: 1026        },27        leftright: {28            sensitivity: 1029        },30        updown: {31            sensitivity: 1032        }33    };34    c.jGestures.defaults.thresholdPinchopen = 0.05;35    c.jGestures.defaults.thresholdPinchmove = 0.05;36    c.jGestures.defaults.thresholdPinch = 0.05;37    c.jGestures.defaults.thresholdPinchclose = 0.05;38    c.jGestures.defaults.thresholdRotatecw = 5;39    c.jGestures.defaults.thresholdRotateccw = 5;40    c.jGestures.defaults.thresholdMove = 20;41    c.jGestures.defaults.thresholdSwipe = 100;42    c.jGestures.data = {};43    c.jGestures.data.capableDevicesInUserAgentString = ["iPad", "iPhone", "iPod", "Mobile Safari"];44    c.jGestures.data.hasGestures = (function() {45        var k;46        for (k = 0; k < c.jGestures.data.capableDevicesInUserAgentString.length; k++) {47            if (navigator.userAgent.indexOf(c.jGestures.data.capableDevicesInUserAgentString[k]) !== -1) {48                return true49            }50        }51        return false52    })();53    c.hasGestures = c.jGestures.data.hasGestures;54    c.jGestures.events = {55        touchstart: "jGestures.touchstart",56        touchendStart: "jGestures.touchend;start",57        touchendProcessed: "jGestures.touchend;processed",58        gesturestart: "jGestures.gesturestart",59        gestureendStart: "jGestures.gestureend;start",60        gestureendProcessed: "jGestures.gestureend;processed"61    };62    jQuery.each({63        orientationchange_orientationchange01: "orientationchange",64        gestureend_pinchopen01: "pinchopen",65        gestureend_pinchclose01: "pinchclose",66        gestureend_rotatecw01: "rotatecw",67        gestureend_rotateccw01: "rotateccw",68        gesturechange_pinch01: "pinch",69        gesturechange_rotate01: "rotate",70        touchstart_swipe13: "swipemove",71        touchstart_swipe01: "swipeone",72        touchstart_swipe02: "swipetwo",73        touchstart_swipe03: "swipethree",74        touchstart_swipe04: "swipefour",75        touchstart_swipe05: "swipeup",76        touchstart_swipe06: "swiperightup",77        touchstart_swipe07: "swiperight",78        touchstart_swipe08: "swiperightdown",79        touchstart_swipe09: "swipedown",80        touchstart_swipe10: "swipeleftdown",81        touchstart_swipe11: "swipeleft",82        touchstart_swipe12: "swipeleftup",83        touchstart_tap01: "tapone",84        touchstart_tap02: "taptwo",85        touchstart_tap03: "tapthree",86        touchstart_tap04: "tapfour",87        devicemotion_shake01: "shake",88        devicemotion_shake02: "shakefrontback",89        devicemotion_shake03: "shakeleftright",90        devicemotion_shake04: "shakeupdown"91    },92    function(l, k) {93        jQuery.event.special[k] = {94            setup: function() {95                var r = l.split("_");96                var o = r[0];97                var m = r[1].slice(0, r[1].length - 2);98                var p = jQuery(this);99                var q;100                var n;101                if (!p.data("ojQueryGestures") || !p.data("ojQueryGestures")[o]) {102                    q = p.data("ojQueryGestures") || {};103                    n = {};104                    n[o] = true;105                    c.extend(true, q, n);106                    p.data("ojQueryGestures", q);107                    if (c.hasGestures) {108                        switch (m) {109                        case "orientationchange":110                            p.get(0).addEventListener("orientationchange", a, false);111                            break;112                        case "shake":113                        case "shakefrontback":114                        case "shakeleftright":115                        case "shakeupdown":116                        case "tilt":117                            p.get(0).addEventListener("devicemotion", b, false);118                            break;119                        case "tap":120                        case "swipe":121                        case "swipeup":122                        case "swiperightup":123                        case "swiperight":124                        case "swiperightdown":125                        case "swipedown":126                        case "swipeleftdown":127                        case "swipeleft":128                            p.get(0).addEventListener("touchstart", h, false);129                            break;130                        case "pinchopen":131                        case "pinchclose":132                        case "rotatecw":133                        case "rotateccw":134                            p.get(0).addEventListener("gesturestart", e, false);135                            p.get(0).addEventListener("gestureend", i, false);136                            break;137                        case "pinch":138                        case "rotate":139                            p.get(0).addEventListener("gesturestart", e, false);140                            p.get(0).addEventListener("gesturechange", f, false);141                            break142                        }143                    } else {144                        switch (m) {145                        case "tap":146                        case "swipe":147                            p.bind("mousedown", h);148                            break;149                        case "orientationchange":150                        case "pinchopen":151                        case "pinchclose":152                        case "rotatecw":153                        case "rotateccw":154                        case "pinch":155                        case "rotate":156                        case "shake":157                        case "tilt":158                            break159                        }160                    }161                }162                return false163            },164            add: function(n) {165                var m = jQuery(this);166                var o = m.data("ojQueryGestures");167                o[n.type] = {168                    originalType: n.type169                };170                return false171            },172            remove: function(n) {173                var m = jQuery(this);174                var o = m.data("ojQueryGestures");175                o[n.type] = false;176                m.data("ojQueryGestures", o);177                return false178            },179            teardown: function() {180                var r = l.split("_");181                var o = r[0];182                var m = r[1].slice(0, r[1].length - 2);183                var p = jQuery(this);184                var q;185                var n;186                if (!p.data("ojQueryGestures") || !p.data("ojQueryGestures")[o]) {187                    q = p.data("ojQueryGestures") || {};188                    n = {};189                    n[o] = false;190                    c.extend(true, q, n);191                    p.data("ojQueryGestures", q);192                    if (c.hasGestures) {193                        switch (m) {194                        case "orientationchange":195                            p.get(0).removeEventListener("orientationchange", a, false);196                            break;197                        case "shake":198                        case "shakefrontback":199                        case "shakeleftright":200                        case "shakeupdown":201                        case "tilt":202                            p.get(0).removeEventListener("devicemotion", b, false);203                            break;204                        case "tap":205                        case "swipe":206                        case "swipeup":207                        case "swiperightup":208                        case "swiperight":209                        case "swiperightdown":210                        case "swipedown":211                        case "swipeleftdown":212                        case "swipeleft":213                        case "swipeleftup":214                            p.get(0).removeEventListener("touchstart", h, false);215                            p.get(0).removeEventListener("touchmove", g, false);216                            p.get(0).removeEventListener("touchend", j, false);217                            break;218                        case "pinchopen":219                        case "pinchclose":220                        case "rotatecw":221                        case "rotateccw":222                            p.get(0).removeEventListener("gesturestart", e, false);223                            p.get(0).removeEventListener("gestureend", i, false);224                            break;225                        case "pinch":226                        case "rotate":227                            p.get(0).removeEventListener("gesturestart", e, false);228                            p.get(0).removeEventListener("gesturechange", f, false);229                            break230                        }231                    } else {232                        switch (m) {233                        case "tap":234                        case "swipe":235                            p.unbind("mousedown", h);236                            p.unbind("mousemove", g);237                            p.unbind("mouseup", j);238                            break;239                        case "orientationchange":240                        case "pinchopen":241                        case "pinchclose":242                        case "rotatecw":243                        case "rotateccw":244                        case "pinch":245                        case "rotate":246                        case "shake":247                        case "tilt":248                            break249                        }250                    }251                }252                return false253            }254        }255    });256    function d(k) {257        k.startMove = (k.startMove) ? k.startMove: {258            startX: null,259            startY: null,260            timestamp: null261        };262        var l = new Date().getTime();263        var m;264        var n;265        if (k.touches) {266            n = [{267                lastX: k.deltaX,268                lastY: k.deltaY,269                moved: null,270                startX: k.screenX - k.startMove.screenX,271                startY: k.screenY - k.startMove.screenY272            }];273            m = {274                vector: k.vector || null,275                orientation: window.orientation || null,276                lastX: ((n[0].lastX > 0) ? +1 : ((n[0].lastX < 0) ? -1 : 0)),277                lastY: ((n[0].lastY > 0) ? +1 : ((n[0].lastY < 0) ? -1 : 0)),278                startX: ((n[0].startX > 0) ? +1 : ((n[0].startX < 0) ? -1 : 0)),279                startY: ((n[0].startY > 0) ? +1 : ((n[0].startY < 0) ? -1 : 0))280            };281            n[0].moved = Math.sqrt(Math.pow(Math.abs(n[0].startX), 2) + Math.pow(Math.abs(n[0].startY), 2))282        }283        return {284            type: k.type || null,285            originalEvent: k.event || null,286            delta: n || null,287            direction: m || {288                orientation: window.orientation || null,289                vector: k.vector || null290            },291            duration: (k.duration) ? k.duration: (k.startMove.timestamp) ? l - k.timestamp: null,292            rotation: k.rotation || null,293            scale: k.scale || null,294            description: k.description || [k.type, ":", k.touches, ":", ((n[0].lastX != 0) ? ((n[0].lastX > 0) ? "right": "left") : "steady"), ":", ((n[0].lastY != 0) ? ((n[0].lastY > 0) ? "down": "up") : "steady")].join("")295        }296    }297    function a(l) {298        var k = ["landscape:clockwise:", "portrait:default:", "landscape:counterclockwise:", "portrait:upsidedown:"];299        c(window).triggerHandler("orientationchange", {300            direction: {301                orientation: window.orientation302            },303            description: ["orientationchange:", k[((window.orientation / 90) + 1)], window.orientation].join("")304        })305    }306    function b(r) {307        var k;308        var t = jQuery(window);309        var o = t.data("ojQueryGestures");310        var m = c.jGestures.defaults.thresholdShake;311        var n = o.oDeviceMotionLastDevicePosition || {312            accelerationIncludingGravity: {313                x: 0,314                y: 0,315                z: 0316            },317            shake: {318                eventCount: 0,319                intervalsPassed: 0,320                intervalsFreeze: 0321            },322            shakeleftright: {323                eventCount: 0,324                intervalsPassed: 0,325                intervalsFreeze: 0326            },327            shakefrontback: {328                eventCount: 0,329                intervalsPassed: 0,330                intervalsFreeze: 0331            },332            shakeupdown: {333                eventCount: 0,334                intervalsPassed: 0,335                intervalsFreeze: 0336            }337        };338        var q = {339            accelerationIncludingGravity: {340                x: r.accelerationIncludingGravity.x,341                y: r.accelerationIncludingGravity.y,342                z: r.accelerationIncludingGravity.z343            },344            shake: {345                eventCount: n.shake.eventCount,346                intervalsPassed: n.shake.intervalsPassed,347                intervalsFreeze: n.shake.intervalsFreeze348            },349            shakeleftright: {350                eventCount: n.shakeleftright.eventCount,351                intervalsPassed: n.shakeleftright.intervalsPassed,352                intervalsFreeze: n.shakeleftright.intervalsFreeze353            },354            shakefrontback: {355                eventCount: n.shakefrontback.eventCount,356                intervalsPassed: n.shakefrontback.intervalsPassed,357                intervalsFreeze: n.shakefrontback.intervalsFreeze358            },359            shakeupdown: {360                eventCount: n.shakeupdown.eventCount,361                intervalsPassed: n.shakeupdown.intervalsPassed,362                intervalsFreeze: n.shakeupdown.intervalsFreeze363            }364        };365        var p;366        var s;367        var l;368        for (k in o) {369            switch (k) {370            case "shake":371            case "shakeleftright":372            case "shakefrontback":373            case "shakeupdown":374                p = [];375                s = [];376                p.push(k);377                if (++q[k].intervalsFreeze > m.freezeShakes && q[k].intervalsFreeze < (2 * m.freezeShakes)) {378                    break379                }380                q[k].intervalsFreeze = 0;381                q[k].intervalsPassed++;382                if ((k === "shake" || k === "shakeleftright") && (q.accelerationIncludingGravity.x > m.leftright.sensitivity || q.accelerationIncludingGravity.x < ( - 1 * m.leftright.sensitivity))) {383                    p.push("leftright");384                    p.push("x-axis")385                }386                if ((k === "shake" || k === "shakefrontback") && (q.accelerationIncludingGravity.y > m.frontback.sensitivity || q.accelerationIncludingGravity.y < ( - 1 * m.frontback.sensitivity))) {387                    p.push("frontback");388                    p.push("y-axis")389                }390                if ((k === "shake" || k === "shakeupdown") && (q.accelerationIncludingGravity.z + 9.81 > m.updown.sensitivity || q.accelerationIncludingGravity.z + 9.81 < ( - 1 * m.updown.sensitivity))) {391                    p.push("updown");392                    p.push("z-axis")393                }394                if (p.length > 1) {395                    if (++q[k].eventCount == m.requiredShakes && (q[k].intervalsPassed) < m.freezeShakes) {396                        t.triggerHandler(k, d({397                            type: k,398                            description: p.join(":"),399                            event: r,400                            duration: q[k].intervalsPassed * 5401                        }));402                        q[k].eventCount = 0;403                        q[k].intervalsPassed = 0;404                        q[k].intervalsFreeze = m.freezeShakes + 1405                    } else {406                        if (q[k].eventCount == m.requiredShakes && (q[k].intervalsPassed) > m.freezeShakes) {407                            q[k].eventCount = 0;408                            q[k].intervalsPassed = 0409                        }410                    }411                }412                break413            }414            l = {};415            l.oDeviceMotionLastDevicePosition = q;416            t.data("ojQueryGestures", c.extend(true, o, l))417        }418    }419    function h(l) {420        var k = jQuery(l.currentTarget);421        k.triggerHandler(c.jGestures.events.touchstart, l);422        if (c.hasGestures) {423            l.currentTarget.addEventListener("touchmove", g, false);424            l.currentTarget.addEventListener("touchend", j, false)425        } else {426            k.bind("mousemove", g);427            k.bind("mouseup", j)428        }429        var n = k.data("ojQueryGestures");430        var m = (l.touches) ? l.touches[0] : l;431        var o = {};432        o.oLastSwipemove = {433            screenX: m.screenX,434            screenY: m.screenY,435            timestamp: new Date().getTime()436        };437        o.oStartTouch = {438            screenX: m.screenX,439            screenY: m.screenY,440            timestamp: new Date().getTime()441        };442        k.data("ojQueryGestures", c.extend(true, n, o))443    }444    function g(t) {445        var v = jQuery(t.currentTarget);446        var s = v.data("ojQueryGestures");447        var q = !!t.touches;448        var l = (q) ? t.changedTouches[0].screenX: t.screenX;449        var k = (q) ? t.changedTouches[0].screenY: t.screenY;450        var r = s.oLastSwipemove;451        var o = l - r.screenX;452        var n = k - r.screenY;453        var u;454        if ( !! s.oLastSwipemove) {455            u = d({456                type: "swipemove",457                touches: (q) ? t.touches.length: "1",458                screenY: k,459                screenX: l,460                deltaY: n,461                deltaX: o,462                startMove: r,463                event: t,464                timestamp: r.timestamp465            });466            v.triggerHandler(u.type, u)467        }468        var m = {};469        var p = (t.touches) ? t.touches[0] : t;470        m.oLastSwipemove = {471            screenX: p.screenX,472            screenY: p.screenY,473            timestamp: new Date().getTime()474        };475        v.data("ojQueryGestures", c.extend(true, s, m))476    }477    function j(r) {478        var v = jQuery(r.currentTarget);479        var x = !!r.changedTouches;480        var u = (x) ? r.changedTouches.length: "1";481        var p = (x) ? r.changedTouches[0].screenX: r.screenX;482        var o = (x) ? r.changedTouches[0].screenY: r.screenY;483        v.triggerHandler(c.jGestures.events.touchendStart, r);484        if (c.hasGestures) {485            r.currentTarget.removeEventListener("touchmove", g, false);486            r.currentTarget.removeEventListener("touchend", j, false)487        } else {488            v.unbind("mousemove", g);489            v.unbind("mouseup", j)490        }491        var m = v.data("ojQueryGestures");492        var y = (Math.abs(m.oStartTouch.screenX - p) > c.jGestures.defaults.thresholdMove || Math.abs(m.oStartTouch.screenY - o) > c.jGestures.defaults.thresholdMove) ? true: false;493        var B = (Math.abs(m.oStartTouch.screenX - p) > c.jGestures.defaults.thresholdSwipe || Math.abs(m.oStartTouch.screenY - o) > c.jGestures.defaults.thresholdSwipe) ? true: false;494        var A;495        var t;496        var n;497        var l;498        var k;499        var q;500        var w = ["zero", "one", "two", "three", "four"];501        var s;502        for (A in m) {503            t = m.oStartTouch;504            n = {};505            p = (x) ? r.changedTouches[0].screenX: r.screenX;506            o = (x) ? r.changedTouches[0].screenY: r.screenY;507            l = p - t.screenX;508            k = o - t.screenY;509            q = d({510                type: "swipe",511                touches: u,512                screenY: o,513                screenX: p,514                deltaY: k,515                deltaX: l,516                startMove: t,517                event: r,518                timestamp: t.timestamp519            });520            s = false;521            switch (A) {522            case "swipeone":523                if (x === false && u == 1 && y === false) {524                    break525                }526                if (x === false || (u == 1 && y === true && B === true)) {527                    s = true;528                    q.type = ["swipe", w[u]].join("");529                    v.triggerHandler(q.type, q)530                }531                break;532            case "swipetwo":533                if ((x && u == 2 && y === true && B === true)) {534                    s = true;535                    q.type = ["swipe", w[u]].join("");536                    v.triggerHandler(q.type, q)537                }538                break;539            case "swipethree":540                if ((x && u == 3 && y === true && B === true)) {541                    s = true;542                    q.type = ["swipe", w[u]].join("");543                    v.triggerHandler(q.type, q)544                }545                break;546            case "swipefour":547                if ((x && u == 4 && y === true && B === true)) {548                    s = true;549                    q.type = ["swipe", w[u]].join("");550                    v.triggerHandler(q.type, q)551                }552                break;553            case "swipeup":554            case "swiperightup":555            case "swiperight":556            case "swiperightdown":557            case "swipedown":558            case "swipeleftdown":559            case "swipeleft":560            case "swipeleftup":561                if (x && y === true && B === true) {562                    s = true;563                    q.type = ["swipe", ((q.delta[0].lastX != 0) ? ((q.delta[0].lastX > 0) ? "right": "left") : ""), ((q.delta[0].lastY != 0) ? ((q.delta[0].lastY > 0) ? "down": "up") : "")].join("");564                    v.triggerHandler(q.type, q)565                }566                break;567            case "tapone":568            case "taptwo":569            case "tapthree":570            case "tapfour":571                if ((y !== true && s !== true) && (w[u] == A.slice(3))) {572                    q.description = ["tap", w[u]].join("");573                    q.type = ["tap", w[u]].join("");574                    v.triggerHandler(q.type, q)575                }576                break577            }578            var z = {};579            v.data("ojQueryGestures", c.extend(true, m, z));580            v.data("ojQueryGestures", c.extend(true, m, z))581        }582        v.triggerHandler(c.jGestures.events.touchendProcessed, r)583    }584    function e(l) {585        var k = jQuery(l.currentTarget);586        k.triggerHandler(c.jGestures.events.gesturestart, l);587        var m = k.data("ojQueryGestures");588        var n = {};589        n.oStartTouch = {590            timestamp: new Date().getTime()591        };592        k.data("ojQueryGestures", c.extend(true, m, n))593    }594    function f(l) {595        var k = jQuery(l.currentTarget);596        var p, m, r, o;597        var q = k.data("ojQueryGestures");598        var n;599        for (n in q) {600            switch (n) {601            case "pinch":602                p = l.scale;603                if (((p < 1) && (p % 1) < (1 - c.jGestures.defaults.thresholdPinchclose)) || ((p > 1) && (p % 1) > (c.jGestures.defaults.thresholdPinchopen))) {604                    m = (p < 1) ? -1 : +1;605                    o = d({606                        type: "pinch",607                        scale: p,608                        touches: null,609                        startMove: q.oStartTouch,610                        event: l,611                        timestamp: q.oStartTouch.timestamp,612                        vector: m,613                        description: ["pinch:", m, ":", ((p < 1) ? "close": "open")].join("")614                    });615                    k.triggerHandler(o.type, o)616                }617                break;618            case "rotate":619                p = l.rotation;620                if (((p < 1) && ( - 1 * (p) > c.jGestures.defaults.thresholdRotateccw)) || ((p > 1) && (p > c.jGestures.defaults.thresholdRotatecw))) {621                    m = (p < 1) ? -1 : +1;622                    o = d({623                        type: "rotate",624                        rotation: p,625                        touches: null,626                        startMove: q.oStartTouch,627                        event: l,628                        timestamp: q.oStartTouch.timestamp,629                        vector: m,630                        description: ["rotate:", m, ":", ((p < 1) ? "counterclockwise": "clockwise")].join("")631                    });632                    k.triggerHandler(o.type, o)633                }634                break635            }636        }637    }638    function i(l) {639        var k = jQuery(l.currentTarget);640        k.triggerHandler(c.jGestures.events.gestureendStart, l);641        var n;642        var o = k.data("ojQueryGestures");643        var m;644        for (m in o) {645            switch (m) {646            case "pinchclose":647                n = l.scale;648                if ((n < 1) && (n % 1) < (1 - c.jGestures.defaults.thresholdPinchclose)) {649                    k.triggerHandler("pinchclose", d({650                        type: "pinchclose",651                        scale: n,652                        vector: -1,653                        touches: null,654                        startMove: o.oStartTouch,655                        event: l,656                        timestamp: o.oStartTouch.timestamp,657                        description: "pinch:-1:close"658                    }))659                }660                break;661            case "pinchopen":662                n = l.scale;663                if ((n > 1) && (n % 1) > (c.jGestures.defaults.thresholdPinchopen)) {664                    k.triggerHandler("pinchopen", d({665                        type: "pinchopen",666                        scale: n,667                        vector: +1,668                        touches: null,669                        startMove: o.oStartTouch,670                        event: l,671                        timestamp: o.oStartTouch.timestamp,672                        description: "pinch:+1:open"673                    }))674                }675                break;676            case "rotatecw":677                n = l.rotation;678                if ((n > 1) && (n > c.jGestures.defaults.thresholdRotatecw)) {679                    k.triggerHandler("rotatecw", d({680                        type: "rotatecw",681                        rotation: n,682                        vector: +1,683                        touches: null,684                        startMove: o.oStartTouch,685                        event: l,686                        timestamp: o.oStartTouch.timestamp,687                        description: "rotate:+1:clockwise"688                    }))689                }690                break;691            case "rotateccw":692                n = l.rotation;693                if ((n < 1) && ( - 1 * (n) > c.jGestures.defaults.thresholdRotateccw)) {694                    k.triggerHandler("rotateccw", d({695                        type: "rotateccw",696                        rotation: n,697                        vector: -1,698                        touches: null,699                        startMove: o.oStartTouch,700                        event: l,701                        timestamp: o.oStartTouch.timestamp,702                        description: "rotate:-1:counterclockwise"703                    }))704                }705                break706            }707        }708        k.triggerHandler(c.jGestures.events.gestureendProcessed, l)709    }...jgestures.min.js
Source:jgestures.min.js  
1/**2 * jGestures: a jQuery plugin for gesture events3 * Copyright 2010-2011 Neue Digitale / Razorfish GmbH4 * Copyright 2011-2012, Razorfish GmbH5 * Licensed under the Apache License, Version 2.0 (the "License");6 * you may not use this file except in compliance with the License.7 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.08 * Unless required by applicable law or agreed to in writing, software9 * distributed under the License is distributed on an "AS IS" BASIS,10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11 * See the License for the specific language governing permissions and12 * limitations under the License.13 * @copyright Razorfish GmbH14 * @author martin.krause@razorfish.de15 * @version 0.90-shake16 * @requires jQuery JavaScript Library v1.4.2 - http://jquery.com/- Copyright 2010, John Resig- Dual licensed under the MIT or GPL Version 2 licenses. http://jquery.org/license17 */18(function(c) {19    c.jGestures = {};20    c.jGestures.defaults = {};21    c.jGestures.defaults.thresholdShake = { requiredShakes: 10, freezeShakes: 100, frontback: { sensitivity: 10 }, leftright: { sensitivity: 10 }, updown: { sensitivity: 10 } };22    c.jGestures.defaults.thresholdPinchopen = 0.05;23    c.jGestures.defaults.thresholdPinchmove = 0.05;24    c.jGestures.defaults.thresholdPinch = 0.05;25    c.jGestures.defaults.thresholdPinchclose = 0.05;26    c.jGestures.defaults.thresholdRotatecw = 5;27    c.jGestures.defaults.thresholdRotateccw = 5;28    c.jGestures.defaults.thresholdMove = 20;29    c.jGestures.defaults.thresholdSwipe = 100;30    c.jGestures.data = {};31    c.jGestures.data.capableDevicesInUserAgentString = ["iPad", "iPhone", "iPod", "Mobile Safari"];32    c.jGestures.data.hasGestures = (function() { var k; for (k = 0; k < c.jGestures.data.capableDevicesInUserAgentString.length; k++) { if (navigator.userAgent.indexOf(c.jGestures.data.capableDevicesInUserAgentString[k]) !== -1) { return true } } return false })();33    c.hasGestures = c.jGestures.data.hasGestures;34    c.jGestures.events = { touchstart: "jGestures.touchstart", touchendStart: "jGestures.touchend;start", touchendProcessed: "jGestures.touchend;processed", gesturestart: "jGestures.gesturestart", gestureendStart: "jGestures.gestureend;start", gestureendProcessed: "jGestures.gestureend;processed" };35    jQuery.each({ orientationchange_orientationchange01: "orientationchange", gestureend_pinchopen01: "pinchopen", gestureend_pinchclose01: "pinchclose", gestureend_rotatecw01: "rotatecw", gestureend_rotateccw01: "rotateccw", gesturechange_pinch01: "pinch", gesturechange_rotate01: "rotate", touchstart_swipe13: "swipemove", touchstart_swipe01: "swipeone", touchstart_swipe02: "swipetwo", touchstart_swipe03: "swipethree", touchstart_swipe04: "swipefour", touchstart_swipe05: "swipeup", touchstart_swipe06: "swiperightup", touchstart_swipe07: "swiperight", touchstart_swipe08: "swiperightdown", touchstart_swipe09: "swipedown", touchstart_swipe10: "swipeleftdown", touchstart_swipe11: "swipeleft", touchstart_swipe12: "swipeleftup", touchstart_tap01: "tapone", touchstart_tap02: "taptwo", touchstart_tap03: "tapthree", touchstart_tap04: "tapfour", devicemotion_shake01: "shake", devicemotion_shake02: "shakefrontback", devicemotion_shake03: "shakeleftright", devicemotion_shake04: "shakeupdown" }, function(l, k) {36        jQuery.event.special[k] = {37            setup: function() {38                var r = l.split("_");39                var o = r[0];40                var m = r[1].slice(0, r[1].length - 2);41                var p = jQuery(this);42                var q;43                var n;44                if (!p.data("ojQueryGestures") || !p.data("ojQueryGestures")[o]) {45                    q = p.data("ojQueryGestures") || {};46                    n = {};47                    n[o] = true;48                    c.extend(true, q, n);49                    p.data("ojQueryGestures", q);50                    if (c.hasGestures) {51                        switch (m) {52                            case "orientationchange":53                                p.get(0).addEventListener("orientationchange", a, false);54                                break;55                            case "shake":56                            case "shakefrontback":57                            case "shakeleftright":58                            case "shakeupdown":59                            case "tilt":60                                p.get(0).addEventListener("devicemotion", b, false);61                                break;62                            case "tap":63                            case "swipe":64                            case "swipeup":65                            case "swiperightup":66                            case "swiperight":67                            case "swiperightdown":68                            case "swipedown":69                            case "swipeleftdown":70                            case "swipeleft":71                                p.get(0).addEventListener("touchstart", h, false);72                                break;73                            case "pinchopen":74                            case "pinchclose":75                            case "rotatecw":76                            case "rotateccw":77                                p.get(0).addEventListener("gesturestart", e, false);78                                p.get(0).addEventListener("gestureend", i, false);79                                break;80                            case "pinch":81                            case "rotate":82                                p.get(0).addEventListener("gesturestart", e, false);83                                p.get(0).addEventListener("gesturechange", f, false);84                                break85                        }86                    } else {87                        switch (m) {88                            case "tap":89                            case "swipe":90                                p.bind("mousedown", h);91                                break;92                            case "orientationchange":93                            case "pinchopen":94                            case "pinchclose":95                            case "rotatecw":96                            case "rotateccw":97                            case "pinch":98                            case "rotate":99                            case "shake":100                            case "tilt":101                                break102                        }103                    }104                }105                return false106            },107            add: function(n) {108                var m = jQuery(this);109                var o = m.data("ojQueryGestures");110                o[n.type] = { originalType: n.type };111                return false112            },113            remove: function(n) {114                var m = jQuery(this);115                var o = m.data("ojQueryGestures");116                o[n.type] = false;117                m.data("ojQueryGestures", o);118                return false119            },120            teardown: function() {121                var r = l.split("_");122                var o = r[0];123                var m = r[1].slice(0, r[1].length - 2);124                var p = jQuery(this);125                var q;126                var n;127                if (!p.data("ojQueryGestures") || !p.data("ojQueryGestures")[o]) {128                    q = p.data("ojQueryGestures") || {};129                    n = {};130                    n[o] = false;131                    c.extend(true, q, n);132                    p.data("ojQueryGestures", q);133                    if (c.hasGestures) {134                        switch (m) {135                            case "orientationchange":136                                p.get(0).removeEventListener("orientationchange", a, false);137                                break;138                            case "shake":139                            case "shakefrontback":140                            case "shakeleftright":141                            case "shakeupdown":142                            case "tilt":143                                p.get(0).removeEventListener("devicemotion", b, false);144                                break;145                            case "tap":146                            case "swipe":147                            case "swipeup":148                            case "swiperightup":149                            case "swiperight":150                            case "swiperightdown":151                            case "swipedown":152                            case "swipeleftdown":153                            case "swipeleft":154                            case "swipeleftup":155                                p.get(0).removeEventListener("touchstart", h, false);156                                p.get(0).removeEventListener("touchmove", g, false);157                                p.get(0).removeEventListener("touchend", j, false);158                                break;159                            case "pinchopen":160                            case "pinchclose":161                            case "rotatecw":162                            case "rotateccw":163                                p.get(0).removeEventListener("gesturestart", e, false);164                                p.get(0).removeEventListener("gestureend", i, false);165                                break;166                            case "pinch":167                            case "rotate":168                                p.get(0).removeEventListener("gesturestart", e, false);169                                p.get(0).removeEventListener("gesturechange", f, false);170                                break171                        }172                    } else {173                        switch (m) {174                            case "tap":175                            case "swipe":176                                p.unbind("mousedown", h);177                                p.unbind("mousemove", g);178                                p.unbind("mouseup", j);179                                break;180                            case "orientationchange":181                            case "pinchopen":182                            case "pinchclose":183                            case "rotatecw":184                            case "rotateccw":185                            case "pinch":186                            case "rotate":187                            case "shake":188                            case "tilt":189                                break190                        }191                    }192                }193                return false194            }195        }196    });197    function d(k) {198        k.startMove = (k.startMove) ? k.startMove : { startX: null, startY: null, timestamp: null };199        var l = new Date().getTime();200        var m;201        var n;202        if (k.touches) {203            n = [{ lastX: k.deltaX, lastY: k.deltaY, moved: null, startX: k.screenX - k.startMove.screenX, startY: k.screenY - k.startMove.screenY }];204            m = { vector: k.vector || null, orientation: window.orientation || null, lastX: ((n[0].lastX > 0) ? +1 : ((n[0].lastX < 0) ? -1 : 0)), lastY: ((n[0].lastY > 0) ? +1 : ((n[0].lastY < 0) ? -1 : 0)), startX: ((n[0].startX > 0) ? +1 : ((n[0].startX < 0) ? -1 : 0)), startY: ((n[0].startY > 0) ? +1 : ((n[0].startY < 0) ? -1 : 0)) };205            n[0].moved = Math.sqrt(Math.pow(Math.abs(n[0].startX), 2) + Math.pow(Math.abs(n[0].startY), 2))206        }207        return { type: k.type || null, originalEvent: k.event || null, delta: n || null, direction: m || { orientation: window.orientation || null, vector: k.vector || null }, duration: (k.duration) ? k.duration : (k.startMove.timestamp) ? l - k.timestamp : null, rotation: k.rotation || null, scale: k.scale || null, description: k.description || [k.type, ":", k.touches, ":", ((n[0].lastX != 0) ? ((n[0].lastX > 0) ? "right" : "left") : "steady"), ":", ((n[0].lastY != 0) ? ((n[0].lastY > 0) ? "down" : "up") : "steady")].join("") }208    }209    function a(l) {210        var k = ["landscape:clockwise:", "portrait:default:", "landscape:counterclockwise:", "portrait:upsidedown:"];211        c(window).triggerHandler("orientationchange", { direction: { orientation: window.orientation }, description: ["orientationchange:", k[((window.orientation / 90) + 1)], window.orientation].join("") })212    }213    function b(r) {214        var k;215        var t = jQuery(window);216        var o = t.data("ojQueryGestures");217        var m = c.jGestures.defaults.thresholdShake;218        var n = o.oDeviceMotionLastDevicePosition || { accelerationIncludingGravity: { x: 0, y: 0, z: 0 }, shake: { eventCount: 0, intervalsPassed: 0, intervalsFreeze: 0 }, shakeleftright: { eventCount: 0, intervalsPassed: 0, intervalsFreeze: 0 }, shakefrontback: { eventCount: 0, intervalsPassed: 0, intervalsFreeze: 0 }, shakeupdown: { eventCount: 0, intervalsPassed: 0, intervalsFreeze: 0 } };219        var q = { accelerationIncludingGravity: { x: r.accelerationIncludingGravity.x, y: r.accelerationIncludingGravity.y, z: r.accelerationIncludingGravity.z }, shake: { eventCount: n.shake.eventCount, intervalsPassed: n.shake.intervalsPassed, intervalsFreeze: n.shake.intervalsFreeze }, shakeleftright: { eventCount: n.shakeleftright.eventCount, intervalsPassed: n.shakeleftright.intervalsPassed, intervalsFreeze: n.shakeleftright.intervalsFreeze }, shakefrontback: { eventCount: n.shakefrontback.eventCount, intervalsPassed: n.shakefrontback.intervalsPassed, intervalsFreeze: n.shakefrontback.intervalsFreeze }, shakeupdown: { eventCount: n.shakeupdown.eventCount, intervalsPassed: n.shakeupdown.intervalsPassed, intervalsFreeze: n.shakeupdown.intervalsFreeze } };220        var p;221        var s;222        var l;223        for (k in o) {224            switch (k) {225                case "shake":226                case "shakeleftright":227                case "shakefrontback":228                case "shakeupdown":229                    p = [];230                    s = [];231                    p.push(k);232                    if (++q[k].intervalsFreeze > m.freezeShakes && q[k].intervalsFreeze < (2 * m.freezeShakes)) { break }233                    q[k].intervalsFreeze = 0;234                    q[k].intervalsPassed++;235                    if ((k === "shake" || k === "shakeleftright") && (q.accelerationIncludingGravity.x > m.leftright.sensitivity || q.accelerationIncludingGravity.x < (-1 * m.leftright.sensitivity))) {236                        p.push("leftright");237                        p.push("x-axis")238                    }239                    if ((k === "shake" || k === "shakefrontback") && (q.accelerationIncludingGravity.y > m.frontback.sensitivity || q.accelerationIncludingGravity.y < (-1 * m.frontback.sensitivity))) {240                        p.push("frontback");241                        p.push("y-axis")242                    }243                    if ((k === "shake" || k === "shakeupdown") && (q.accelerationIncludingGravity.z + 9.81 > m.updown.sensitivity || q.accelerationIncludingGravity.z + 9.81 < (-1 * m.updown.sensitivity))) {244                        p.push("updown");245                        p.push("z-axis")246                    }247                    if (p.length > 1) {248                        if (++q[k].eventCount == m.requiredShakes && (q[k].intervalsPassed) < m.freezeShakes) {249                            t.triggerHandler(k, d({ type: k, description: p.join(":"), event: r, duration: q[k].intervalsPassed * 5 }));250                            q[k].eventCount = 0;251                            q[k].intervalsPassed = 0;252                            q[k].intervalsFreeze = m.freezeShakes + 1253                        } else {254                            if (q[k].eventCount == m.requiredShakes && (q[k].intervalsPassed) > m.freezeShakes) {255                                q[k].eventCount = 0;256                                q[k].intervalsPassed = 0257                            }258                        }259                    }260                    break261            }262            l = {};263            l.oDeviceMotionLastDevicePosition = q;264            t.data("ojQueryGestures", c.extend(true, o, l))265        }266    }267    function h(l) {268        var k = jQuery(l.currentTarget);269        k.triggerHandler(c.jGestures.events.touchstart, l);270        if (c.hasGestures) {271            l.currentTarget.addEventListener("touchmove", g, false);272            l.currentTarget.addEventListener("touchend", j, false)273        } else {274            k.bind("mousemove", g);275            k.bind("mouseup", j)276        }277        var n = k.data("ojQueryGestures");278        var m = (l.touches) ? l.touches[0] : l;279        var o = {};280        o.oLastSwipemove = { screenX: m.screenX, screenY: m.screenY, timestamp: new Date().getTime() };281        o.oStartTouch = { screenX: m.screenX, screenY: m.screenY, timestamp: new Date().getTime() };282        k.data("ojQueryGestures", c.extend(true, n, o))283    }284    function g(t) {285        var v = jQuery(t.currentTarget);286        var s = v.data("ojQueryGestures");287        var q = !!t.touches;288        var l = (q) ? t.changedTouches[0].screenX : t.screenX;289        var k = (q) ? t.changedTouches[0].screenY : t.screenY;290        var r = s.oLastSwipemove;291        var o = l - r.screenX;292        var n = k - r.screenY;293        var u;294        if (!!s.oLastSwipemove) {295            u = d({ type: "swipemove", touches: (q) ? t.touches.length : "1", screenY: k, screenX: l, deltaY: n, deltaX: o, startMove: r, event: t, timestamp: r.timestamp });296            v.triggerHandler(u.type, u)297        }298        var m = {};299        var p = (t.touches) ? t.touches[0] : t;300        m.oLastSwipemove = { screenX: p.screenX, screenY: p.screenY, timestamp: new Date().getTime() };301        v.data("ojQueryGestures", c.extend(true, s, m))302    }303    function j(r) {304        var v = jQuery(r.currentTarget);305        var x = !!r.changedTouches;306        var u = (x) ? r.changedTouches.length : "1";307        var p = (x) ? r.changedTouches[0].screenX : r.screenX;308        var o = (x) ? r.changedTouches[0].screenY : r.screenY;309        v.triggerHandler(c.jGestures.events.touchendStart, r);310        if (c.hasGestures) {311            r.currentTarget.removeEventListener("touchmove", g, false);312            r.currentTarget.removeEventListener("touchend", j, false)313        } else {314            v.unbind("mousemove", g);315            v.unbind("mouseup", j)316        }317        var m = v.data("ojQueryGestures");318        var y = (Math.abs(m.oStartTouch.screenX - p) > c.jGestures.defaults.thresholdMove || Math.abs(m.oStartTouch.screenY - o) > c.jGestures.defaults.thresholdMove) ? true : false;319        var B = (Math.abs(m.oStartTouch.screenX - p) > c.jGestures.defaults.thresholdSwipe || Math.abs(m.oStartTouch.screenY - o) > c.jGestures.defaults.thresholdSwipe) ? true : false;320        var A;321        var t;322        var n;323        var l;324        var k;325        var q;326        var w = ["zero", "one", "two", "three", "four"];327        var s;328        for (A in m) {329            t = m.oStartTouch;330            n = {};331            p = (x) ? r.changedTouches[0].screenX : r.screenX;332            o = (x) ? r.changedTouches[0].screenY : r.screenY;333            l = p - t.screenX;334            k = o - t.screenY;335            q = d({ type: "swipe", touches: u, screenY: o, screenX: p, deltaY: k, deltaX: l, startMove: t, event: r, timestamp: t.timestamp });336            s = false;337            switch (A) {338                case "swipeone":339                    if (x === false && u == 1 && y === false) { break }340                    if (x === false || (u == 1 && y === true && B === true)) {341                        s = true;342                        q.type = ["swipe", w[u]].join("");343                        v.triggerHandler(q.type, q)344                    }345                    break;346                case "swipetwo":347                    if ((x && u == 2 && y === true && B === true)) {348                        s = true;349                        q.type = ["swipe", w[u]].join("");350                        v.triggerHandler(q.type, q)351                    }352                    break;353                case "swipethree":354                    if ((x && u == 3 && y === true && B === true)) {355                        s = true;356                        q.type = ["swipe", w[u]].join("");357                        v.triggerHandler(q.type, q)358                    }359                    break;360                case "swipefour":361                    if ((x && u == 4 && y === true && B === true)) {362                        s = true;363                        q.type = ["swipe", w[u]].join("");364                        v.triggerHandler(q.type, q)365                    }366                    break;367                case "swipeup":368                case "swiperightup":369                case "swiperight":370                case "swiperightdown":371                case "swipedown":372                case "swipeleftdown":373                case "swipeleft":374                case "swipeleftup":375                    if (x && y === true && B === true) {376                        s = true;377                        q.type = ["swipe", ((q.delta[0].lastX != 0) ? ((q.delta[0].lastX > 0) ? "right" : "left") : ""), ((q.delta[0].lastY != 0) ? ((q.delta[0].lastY > 0) ? "down" : "up") : "")].join("");378                        v.triggerHandler(q.type, q)379                    }380                    break;381                case "tapone":382                case "taptwo":383                case "tapthree":384                case "tapfour":385                    if ((y !== true && s !== true) && (w[u] == A.slice(3))) {386                        q.description = ["tap", w[u]].join("");387                        q.type = ["tap", w[u]].join("");388                        v.triggerHandler(q.type, q)389                    }390                    break391            }392            var z = {};393            v.data("ojQueryGestures", c.extend(true, m, z));394            v.data("ojQueryGestures", c.extend(true, m, z))395        }396        v.triggerHandler(c.jGestures.events.touchendProcessed, r)397    }398    function e(l) {399        var k = jQuery(l.currentTarget);400        k.triggerHandler(c.jGestures.events.gesturestart, l);401        var m = k.data("ojQueryGestures");402        var n = {};403        n.oStartTouch = { timestamp: new Date().getTime() };404        k.data("ojQueryGestures", c.extend(true, m, n))405    }406    function f(l) {407        var k = jQuery(l.currentTarget);408        var p, m, r, o;409        var q = k.data("ojQueryGestures");410        var n;411        for (n in q) {412            switch (n) {413                case "pinch":414                    p = l.scale;415                    if (((p < 1) && (p % 1) < (1 - c.jGestures.defaults.thresholdPinchclose)) || ((p > 1) && (p % 1) > (c.jGestures.defaults.thresholdPinchopen))) {416                        m = (p < 1) ? -1 : +1;417                        o = d({ type: "pinch", scale: p, touches: null, startMove: q.oStartTouch, event: l, timestamp: q.oStartTouch.timestamp, vector: m, description: ["pinch:", m, ":", ((p < 1) ? "close" : "open")].join("") });418                        k.triggerHandler(o.type, o)419                    }420                    break;421                case "rotate":422                    p = l.rotation;423                    if (((p < 1) && (-1 * (p) > c.jGestures.defaults.thresholdRotateccw)) || ((p > 1) && (p > c.jGestures.defaults.thresholdRotatecw))) {424                        m = (p < 1) ? -1 : +1;425                        o = d({ type: "rotate", rotation: p, touches: null, startMove: q.oStartTouch, event: l, timestamp: q.oStartTouch.timestamp, vector: m, description: ["rotate:", m, ":", ((p < 1) ? "counterclockwise" : "clockwise")].join("") });426                        k.triggerHandler(o.type, o)427                    }428                    break429            }430        }431    }432    function i(l) {433        var k = jQuery(l.currentTarget);434        k.triggerHandler(c.jGestures.events.gestureendStart, l);435        var n;436        var o = k.data("ojQueryGestures");437        var m;438        for (m in o) {439            switch (m) {440                case "pinchclose":441                    n = l.scale;442                    if ((n < 1) && (n % 1) < (1 - c.jGestures.defaults.thresholdPinchclose)) { k.triggerHandler("pinchclose", d({ type: "pinchclose", scale: n, vector: -1, touches: null, startMove: o.oStartTouch, event: l, timestamp: o.oStartTouch.timestamp, description: "pinch:-1:close" })) }443                    break;444                case "pinchopen":445                    n = l.scale;446                    if ((n > 1) && (n % 1) > (c.jGestures.defaults.thresholdPinchopen)) { k.triggerHandler("pinchopen", d({ type: "pinchopen", scale: n, vector: +1, touches: null, startMove: o.oStartTouch, event: l, timestamp: o.oStartTouch.timestamp, description: "pinch:+1:open" })) }447                    break;448                case "rotatecw":449                    n = l.rotation;450                    if ((n > 1) && (n > c.jGestures.defaults.thresholdRotatecw)) { k.triggerHandler("rotatecw", d({ type: "rotatecw", rotation: n, vector: +1, touches: null, startMove: o.oStartTouch, event: l, timestamp: o.oStartTouch.timestamp, description: "rotate:+1:clockwise" })) }451                    break;452                case "rotateccw":453                    n = l.rotation;454                    if ((n < 1) && (-1 * (n) > c.jGestures.defaults.thresholdRotateccw)) { k.triggerHandler("rotateccw", d({ type: "rotateccw", rotation: n, vector: -1, touches: null, startMove: o.oStartTouch, event: l, timestamp: o.oStartTouch.timestamp, description: "rotate:-1:counterclockwise" })) }455                    break456            }457        }458        k.triggerHandler(c.jGestures.events.gestureendProcessed, l)459    }...scripts-alt.js
Source:scripts-alt.js  
1$(function() {2	mouseWheelIn();3	mouseWheelOut();4	pinchOpen();5	pinchClose();6	$(document).on("pagechange", function () {7		pinchOpen();8	});9	//$("a").unbind("mousewheel");10});11function mouseWheelIn () {12	var timeStamp = new Date().getTime();13	14	$(document).on("mousewheel", "[data-link='true']", function (event, delta, deltaX, deltaY) {15		event.preventDefault();16		17		var timeNow = new Date().getTime(),18			target = $(this).attr("data-target");19		if(timeNow - timeStamp < 100) {20			//console.log(timeNow - timeStamp + " = Too soon.");21			timeStamp = timeNow;...scripts.js
Source:scripts.js  
1$(function() {2	mouseWheelIn();3	mouseWheelOut();4	pinchOpen();5	pinchClose();6	$(document).on("pagechange", function () {7		pinchOpen();8	});9	//$("a").unbind("mousewheel");10});11function mouseWheelIn () {12	var timeStamp = new Date().getTime();13	14	$(document).on("mousewheel", "a", function (event, delta, deltaX, deltaY) {15		event.preventDefault();16		17		var timeNow = new Date().getTime(),18			target = $(this).attr("href");19		if(timeNow - timeStamp < 100) {20			//console.log(timeNow - timeStamp + " = Too soon.");21			timeStamp = timeNow;...scripts3.js
Source:scripts3.js  
1$(function() {2	mouseWheel();3	mouseWheelLink();4	pinchOpen();5	pinchClose();6	$(document).live("pagechange", function () {7		pinchOpen();8	});9});10function mouseWheel () {11	var timeStamp = new Date().getTime();12	$(document).on("mousewheel", function (event, delta) {13		event.preventDefault();14		var timeNow = new Date().getTime();15		16		if(timeNow - timeStamp < 100) {17			timeStamp = timeNow;18			return;19		} else {20			timeStamp = timeNow;21			if (delta < 0) {...pinch-open-close-specs.js
Source:pinch-open-close-specs.js  
1"use strict";2var okIfAlert = require('../../../helpers/alert').okIfAlert,3    setup = require("../../common/setup-base"),4    desired = require('./desired');5describe('testapp - pinchOpen/pinchClose', function () {6  var driver;7  setup(this, desired).then(function (d) { driver = d; });8  it('should pinchOpen and pinchClose map after tapping Test Gesture', function (done) {9    driver10      .elementsByClassName('UIAButton').at(5).click()11      .sleep(1000).then(function () { okIfAlert(driver); })12      .elementByXPath('//UIAMapView')13      .execute("mobile: pinchOpen", [{startX: 114.0, startY: 198.0, endX: 257.0,14        endY: 256.0, duration: 5.0}])15      .elementByXPath('//UIAMapView')16      .execute("mobile: pinchClose", [{startX: 114.0, startY: 198.0, endX: 257.0,17        endY: 256.0, duration: 5.0}])18      .nodeify(done);19  });...Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3  const browser = await chromium.launch();4  const context = await browser.newContext();5  const page = await context.newPage();6  await page.pinchOpen();7  await browser.close();8})();Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3  const browser = await chromium.launch();4  const context = await browser.newContext();5  const page = await context.newPage();6  await page.pinchOpen({ x: 100, y: 100 });7  await browser.close();8})();9const { chromium } = require('playwright');10(async () => {11  const browser = await chromium.launch();12  const context = await browser.newContext();13  const page = await context.newPage();14  await page.pinchClose({ x: 100, y: 100 });15  await browser.close();16})();17const { chromium } = require('playwright');18(async () => {19  const browser = await chromium.launch();20  const context = await browser.newContext();21  const page = await context.newPage();22  await page.pinchTo({ x: 100, y: 100 }, { x: 300, y: 300 });23  await browser.close();24})();25const { chromium } = require('playwright');26(async () => {27  const browser = await chromium.launch();28  const context = await browser.newContext();29  const page = await context.newPage();30  await page.type('input[name="q"]', 'Playwright');31  await browser.close();32})();33const { chromium } = require('playwright');34(async () => {35  const browser = await chromium.launch();36  const context = await browser.newContext();37  const page = await context.newPage();38  await page.press('input[name="q"]', 'Enter');39  await browser.close();40})();41const { chromium } = require('playwright');42(async () => {43  const browser = await chromium.launch();Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3  const browser = await chromium.launch();4  const context = await browser.newContext();5  const page = await context.newPage();6  await page.pinchOpen();7  await browser.close();8})();9const { chromium } = require('playwright');10(async () => {11  const browser = await chromium.launch();12  const context = await browser.newContext();13  const page = await context.newPage();14  await page.pinchClose();15  await browser.close();16})();17const { chromium } = require('playwright');18(async () => {19  const browser = await chromium.launch();20  const context = await browser.newContext();21  const page = await context.newPage();22  await page.pinchTo({ x: 100, y: 100 }, { scale: 1.5 });23  await browser.close();24})();25const { chromium } = require('playwright');26(async () => {27  const browser = await chromium.launch();28  const context = await browser.newContext();29  const page = await context.newPage();30  await page.screenshot();31  await browser.close();32})();33const { chromium } = require('playwright');34(async () => {35  const browser = await chromium.launch();36  const context = await browser.newContext();37  const page = await context.newPage();38  await page.tap('input');39  await browser.close();40})();41const { chromium } = require('playwright');42(async () => {43  const browser = await chromium.launch();44  const context = await browser.newContext();45  const page = await context.newPage();46  await page.type('input', 'Playwright');47  await browser.close();48})();49const { chromium } = require('playwright');50(async () => {Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3  const browser = await chromium.launch({ headless: false });4  const context = await browser.newContext();5  const page = await context.newPage();6  await page.pinchOpen();7  await browser.close();8})();9const { chromium } = require('playwright');10(async () => {11  const browser = await chromium.launch({ headless: false });12  const context = await browser.newContext();13  const page = await context.newPage();14  await page.pinchClose();15  await browser.close();16})();17const { chromium } = require('playwright');18(async () => {19  const browser = await chromium.launch({ headless: false });20  const context = await browser.newContext();21  const page = await context.newPage();22  await page.pinchTo({ x: 100, y: 100 }, { scale: 2 });23  await browser.close();24})();25const { chromium } = require('playwright');26(async () => {27  const browser = await chromium.launch({ headless: false });28  const context = await browser.newContext();29  const page = await context.newPage();30  await page.touchscreen.tap(100, 100);31  await browser.close();32})();33const { chromium } = require('playwright');34(async () => {35  const browser = await chromium.launch({ headless: false });36  const context = await browser.newContext();37  const page = await context.newPage();38  await page.type('input[name="q"]', 'Hello World');39  await browser.close();40})();41const { chromium } = require('playwright');42(async () => {43  const browser = await chromium.launch({ headless: false });Using AI Code Generation
1const { chromium, devices } = require('playwright');2(async () => {3  const browser = await chromium.launch();4  const context = await browser.newContext();5  const page = await context.newPage();6  await page.pinchOpen({ x: 100, y: 100 });7  await page.screenshot({ path: 'pinchOpen.png' });8  await browser.close();9})();10Recommended Posts: Playwright | pinchClose() method11Playwright | pinchToZoom() method12Playwright | tap() method13Playwright | click() method14Playwright | type() method15Playwright | waitForSelector() method16Playwright | waitForFunction() method17Playwright | waitForRequest() method18Playwright | waitForResponse() method19Playwright | waitForNavigation() method20Playwright | waitForLoadState() method21Playwright | waitForFileChooser() method22Playwright | waitForEvent() method23Playwright | waitForTimeout() method24Playwright | waitForRequest() method25Playwright | waitForResponse() method26Playwright | waitForNavigation() method27Playwright | waitForLoadState() method28Playwright | waitForFileChooser() method29Playwright | waitForEvent() method30Playwright | waitForTimeout() method31Playwright | waitForRequest() method32Playwright | waitForResponse() method33Playwright | waitForNavigation() method34Playwright | waitForLoadState() method35Playwright | waitForFileChooser() method36Playwright | waitForEvent() method37Playwright | waitForTimeout() method38Playwright | waitForRequest() method39Playwright | waitForResponse() method40Playwright | waitForNavigation() method41Playwright | waitForLoadState() method42Playwright | waitForFileChooser() method43Playwright | waitForEvent() method44Playwright | waitForTimeout() method45Playwright | waitForRequest() method46Playwright | waitForResponse() method47Playwright | waitForNavigation() method48Playwright | waitForLoadState() method49Playwright | waitForFileChooser() method50Playwright | waitForEvent() method51Playwright | waitForTimeout() method52Playwright | waitForRequest() method53Playwright | waitForResponse() method54Playwright | waitForNavigation() methodUsing AI Code Generation
1const { chromium } = require('playwright');2(async () => {3  const browser = await chromium.launch();4  const page = await browser.newPage();5  await page.pinchOpen();6  await browser.close();7})();8const { chromium } = require('playwright');9(async () => {10  const browser = await chromium.launch();11  const page = await browser.newPage();12  await page.pinchClose();13  await browser.close();14})();15const { chromium } = require('playwright');16(async () => {17  const browser = await chromium.launch();18  const page = await browser.newPage();19  await page.pinchTo({ x: 10, y: 10 }, { scale: 2 });20  await browser.close();21})();22const { chromium } = require('playwright');23(async () => {24  const browser = await chromium.launch();25  const page = await browser.newPage();26  await page.tap('input');27  await browser.close();28})();29const { chromium } = require('playwright');30(async () => {31  const browser = await chromium.launch();32  const page = await browser.newPage();33  await page.doubleTap('input');34  await browser.close();35})();36const { chromium } = require('playwright');37(async () => {38  const browser = await chromium.launch();39  const page = await browser.newPage();40  await page.tripleTap('input');41  await browser.close();42})();43const { chromium } = require('playwright');44(async () => {45  const browser = await chromium.launch();46  const page = await browser.newPage();Using AI Code Generation
1const { devices } = require('playwright');2const iPhone = devices['iPhone 6'];3(async () => {4  const browser = await chromium.launch({ headless: false });5  const context = await browser.newContext({6    geolocation: { longitude: 12.492507, latitude: 41.889938 },7  });8  const page = await context.newPage();9  await page.click('text="Your location"');10  await page.waitForTimeout(3000);Using AI Code Generation
1const { devices } = require('playwright');2const iPhone11 = devices['iPhone 11 Pro'];3const {chromium} = require('playwright');4(async () => {5  const browser = await chromium.launch();6  const context = await browser.newContext({7    geolocation: { longitude: 12.492507, latitude: 41.889938 },8  });9  const page = await context.newPage();10  await page.click('text="Your location"');11  await page.click('#searchboxinput');12  await page.fill('#searchboxinput', 'Rome');13  await page.click('text="Rome, Italy"');14  await page.click('text="Rome, Italy"');15  await page.click('#searchboxinput');16  await page.fill('#searchboxinput', 'Milan');17  await page.click('text="Milan, Italy"');18  await page.click('text="Milan, Italy"');19  await page.click('#searchboxinput');20  await page.fill('#searchboxinput', 'Venice');21  await page.click('text="Venice, Italy"');22  await page.click('text="Venice, Italy"');23  await page.click('#searchboxinput');24  await page.fill('#searchboxinput', 'Florence');25  await page.click('text="Florence, Italy"');26  await page.click('text="Florence, Italy"');27  await page.click('#searchboxinput');28  await page.fill('#searchboxinput', 'Naples');29  await page.click('text="Naples, Italy"');30  await page.click('text="Naples, Italy"');31  await page.click('#searchboxinput');32  await page.fill('#searchboxinput', 'Bologna');33  await page.click('text="Bologna, Italy"');34  await page.click('text="Bologna, Italy"');35  await page.click('#searchboxinput');36  await page.fill('#searchboxinput', 'Turin');37  await page.click('text="Turin, Italy"');38  await page.click('text="Turin, Italy"');39  await page.click('#searchboxinput');40  await page.fill('#searchboxinput', 'Genoa');41  await page.click('text="GenoaUsing AI Code Generation
1const { pinchOpen } = require('playwright/lib/internal/remote');2const { chromium } = require('playwright');3(async () => {4  const browser = await chromium.launch();5  const context = await browser.newContext();6  const page = await context.newPage();7  await pinchOpen(page, { x: 100, y: 100 });8  await browser.close();9})();LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!
