PageSourceSearch

https://www.extron.com.au/Content/vendor/jquery-mobile-events/jquery.mobile-events.js

js extron.com.au collected 2026-10-01 23:50:49 UTC 41,325 bytes, 882 lines download raw bytes

1/*!
2 * jQuery Mobile Events
3 * by Ben Major
4 *
5 * Copyright 2011-2017, Ben Major
6 * Licensed under the MIT License:
7 * 
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 * 
26 */
27
28"use strict";
29
30(function ($) {
31    $.attrFn = $.attrFn || {};
32
33    // navigator.userAgent.toLowerCase() isn't reliable for Chrome installs
34    // on mobile devices. As such, we will create a boolean isChromeDesktop
35    // The reason that we need to do this is because Chrome annoyingly
36    // purports support for touch events even if the underlying hardware
37    // does not!
38    var touchCapable = ('ontouchstart' in window),
39	
40        settings = {
41            tap_pixel_range: 5,
42            swipe_h_threshold: 50,
43            swipe_v_threshold: 50,
44            taphold_threshold: 750,
45            doubletap_int: 500,
46
47            touch_capable: touchCapable,
48            orientation_support: ('orientation' in window && 'onorientationchange' in window),
49
50            startevent:  (touchCapable) ? 'touchstart' : 'mousedown',
51            endevent:    (touchCapable) ? 'touchend' : 'mouseup',
52            moveevent:   (touchCapable) ? 'touchmove' : 'mousemove',
53            tapevent:    (touchCapable) ? 'tap' : 'click',
54            scrollevent: (touchCapable) ? 'touchmove' : 'scroll',
55
56            hold_timer: null,
57            tap_timer: null
58        };
59    
60    // Convenience functions:
61    $.isTouchCapable = function() { return settings.touch_capable; };
62    $.getStartEvent  = function() { return settings.startevent;    };
63    $.getEndEvent    = function() { return settings.endevent;      };
64    $.getMoveEvent   = function() { return settings.moveevent;     };
65    $.getTapEvent    = function() { return settings.tapevent;      };
66    $.getScrollEvent = function() { return settings.scrollevent;   };
67    
68    // Add Event shortcuts:
69    $.each(['tapstart', 'tapend', 'tapmove', 'tap', 'tap2', 'tap3', 'tap4', 'singletap', 'doubletap', 'taphold', 'swipe', 'swipeup', 'swiperight', 'swipedown', 'swipeleft', 'swipeend', 'scrollstart', 'scrollend', 'orientationchange'], function (i, name) {
70        $.fn[name] = function (fn) {
71            return fn ? this.on(name, fn) : this.trigger(name);
72        };
73
74        $.attrFn[name] = true;
75    });
76
77    // tapstart Event:
78    $.event.special.tapstart = {
79        setup: function () {
80			
81            var thisObject = this,
82                $this = $(thisObject);
83			
84            $this.on(settings.startevent, function tapStartFunc(e) {
85				
86                $this.data('callee', tapStartFunc);
87                if (e.which && e.which !== 1) {
88                    return false;
89                }
90
91                var origEvent = e.originalEvent,
92                    touchData = {
93                        'position': {
94                            'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX),
95                            'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY
96                        },
97                        'offset': {
98                            'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)),
99                            'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0))
100                        },
101                        'time': Date.now(),
102                        'target': e.target
103                    };
104				
105                triggerCustomEvent(thisObject, 'tapstart', e, touchData);
106                return true;
107            });
108        },
109
110        remove: function () {
111            $(this).off(settings.startevent, $(this).data.callee);
112        }
113    };
114	
115    // tapmove Event:
116    $.event.special.tapmove = {
117    	setup: function() {
118            var thisObject = this,
119            $this = $(thisObject);
120    			
121            $this.on(settings.moveevent, function tapMoveFunc(e) {
122                $this.data('callee', tapMoveFunc);
123    			
124                var origEvent = e.originalEvent,
125                    touchData = {
126                        'position': {
127                            'x': ((settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX),
128                            'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY
129                        },
130                        'offset': {
131                            'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)),
132							'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0))
133                        },
134                        'time': Date.now(),
135                        'target': e.target
136                    };
137    				
138                triggerCustomEvent(thisObject, 'tapmove', e, touchData);
139                return true;
140            });
141        },
142        remove: function() {
143            $(this).off(settings.moveevent, $(this).data.callee);
144        }
145    };
146
147    // tapend Event:
148    $.event.special.tapend = {
149        setup: function () {
150            var thisObject = this,
151                $this = $(thisObject);
152
153            $this.on(settings.endevent, function tapEndFunc(e) {
154                // Touch event data:
155                $this.data('callee', tapEndFunc);
156
157                var origEvent = e.originalEvent;
158                var touchData = {
159                    'position': {
160                        'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX,
161                        'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY
162                    },
163                    'offset': {
164                        'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)),
165                        'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0))
166                    },
167                    'time': Date.now(),
168                    'target': e.target
169                };
170                triggerCustomEvent(thisObject, 'tapend', e, touchData);
171                return true;
172            });
173        },
174        remove: function () {
175            $(this).off(settings.endevent, $(this).data.callee);
176        }
177    };
178
179    // taphold Event:
180    $.event.special.taphold = {
181        setup: function () {
182            var thisObject = this,
183                $this = $(thisObject),
184                origTarget,
185                start_pos = {
186                    x: 0,
187                    y: 0
188                },
189                end_x = 0,
190                end_y = 0;
191
192            $this.on(settings.startevent, function tapHoldFunc1(e) {
193                if (e.which && e.which !== 1) {
194                    return false;
195                } else {
196                    $this.data('tapheld', false);
197                    origTarget = e.target;
198
199                    var origEvent = e.originalEvent;
200                    var start_time = Date.now(),
201                        startPosition = {
202                            'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX,
203                            'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY
204                        },
205                        startOffset = {
206                            'x': (settings.touch_capable) ? origEvent.touches[0].pageX - origEvent.touches[0].target.offsetLeft : e.offsetX,
207                            'y': (settings.touch_capable) ? origEvent.touches[0].pageY - origEvent.touches[0].target.offsetTop : e.offsetY
208                        };
209
210                    start_pos.x = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageX : e.pageX;
211                    start_pos.y = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageY : e.pageY;
212
213                    end_x = start_pos.x;
214                    end_y = start_pos.y;
215                    
216                    // Get the element's threshold:
217                    
218                    var ele_threshold = ($this.parent().data('threshold')) ? $this.parent().data('threshold') : $this.data('threshold'),
219                        threshold = (typeof ele_threshold !== 'undefined' && ele_threshold !== false && parseInt(ele_threshold)) ? parseInt(ele_threshold) : settings.taphold_threshold; 
220
221                    settings.hold_timer = window.setTimeout(function () {
222
223                        var diff_x = (start_pos.x - end_x),
224                            diff_y = (start_pos.y - end_y);
225
226                        if (e.target == origTarget && ((start_pos.x == end_x && start_pos.y == end_y) || (diff_x >= -(settings.tap_pixel_range) && diff_x <= settings.tap_pixel_range && diff_y >= -(settings.tap_pixel_range) && diff_y <= settings.tap_pixel_range))) {
227                            $this.data('tapheld', true);
228
229                            var end_time = Date.now(),
230                                endPosition = {
231                                    'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX,
232                                    'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY
233                                },
234                                endOffset = {
235                                    'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)),
236									'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0))
237                                };
238                            var duration = end_time - start_time;
239
240                            // Build the touch data:
241                            var touchData = {
242                                'startTime': start_time,
243                                'endTime': end_time,
244                                'startPosition': startPosition,
245                                'startOffset': startOffset,
246                                'endPosition': endPosition,
247                                'endOffset': endOffset,
248                                'duration': duration,
249                                'target': e.target
250                            };
251                            $this.data('callee1', tapHoldFunc1);
252                            triggerCustomEvent(thisObject, 'taphold', e, touchData);
253                        }
254                    }, threshold);
255
256                    return true;
257                }
258            }).on(settings.endevent, function tapHoldFunc2() {
259                $this.data('callee2', tapHoldFunc2);
260                $this.data('tapheld', false);
261                window.clearTimeout(settings.hold_timer);
262            })
263            .on(settings.moveevent, function tapHoldFunc3(e) {
264                $this.data('callee3', tapHoldFunc3);
265				
266                end_x = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageX : e.pageX;
267                end_y = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageY : e.pageY;
268            });
269        },
270
271        remove: function () {
272            $(this).off(settings.startevent, $(this).data.callee1).off(settings.endevent, $(this).data.callee2).off(settings.moveevent, $(this).data.callee3);
273        }
274    };
275
276    // doubletap Event:
277    $.event.special.doubletap = {
278        setup: function () {
279            var thisObject = this,
280                $this = $(thisObject),
281                origTarget,
282                action,
283                firstTap = null,
284                origEvent,
285				cooloff,
286				cooling = false;
287
288            $this.on(settings.startevent, function doubleTapFunc1(e) {
289                if (e.which && e.which !== 1) {
290                    return false;
291                }
292                
293                $this.data('doubletapped', false);
294                origTarget = e.target;
295                $this.data('callee1', doubleTapFunc1);
296
297                origEvent = e.originalEvent;
298                if (!firstTap) {
299                    firstTap = {
300                        'position': {
301                            'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX,
302                            'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY
303                        },
304                        'offset': {
305                            'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)),
306                            'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0))
307                        },
308                        'time': Date.now(),
309                        'target': e.target,
310                        'element': e.originalEvent.srcElement,
311                        'index':   $(e.target).index()
312                    };
313                }
314
315                return true;
316            }).on(settings.endevent, function doubleTapFunc2(e) {
317				
318                var now = Date.now();
319                var lastTouch = $this.data('lastTouch') || now + 1;
320                var delta = now - lastTouch;
321                window.clearTimeout(action);
322                $this.data('callee2', doubleTapFunc2);
323
324                if (delta < settings.doubletap_int && ($(e.target).index() == firstTap.index) && delta > 100) {
325                    $this.data('doubletapped', true);
326                    window.clearTimeout(settings.tap_timer);
327
328                    // Now get the current event:
329                    var lastTap = {
330                        'position': {
331                            'x': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenX : e.screenX,
332                            'y': (settings.touch_capable) ? e.originalEvent.changedTouches[0].screenY : e.screenY
333                        },
334                        'offset': {
335                            'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)),
336                            'y': (settings.touch_capable) ? Math.round(origEve
336nt.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0))
337                        },
338                        'time': Date.now(),
339                        'target': e.target,
340                        'element': e.originalEvent.srcElement,
341                        'index': $(e.target).index()
342                    };
343
344                    var touchData = {
345                        'firstTap': firstTap,
346                        'secondTap': lastTap,
347                        'interval': lastTap.time - firstTap.time
348                    };
349
350                    if (!cooling) {
351                    	triggerCustomEvent(thisObject, 'doubletap', e, touchData);
352                        firstTap = null;
353                    }
354                    
355                    cooling = true;
356                    
357                    cooloff = window.setTimeout(function () {
358                    	cooling = false;
359                    }, settings.doubletap_int);
360					
361                } else {
362                    $this.data('lastTouch', now);
363                    action = window.setTimeout(function () {
364                        firstTap = null;
365                        window.clearTimeout(action);
366                    }, settings.doubletap_int, [e]);
367                }
368                $this.data('lastTouch', now);
369            });
370        },
371        remove: function () {
372            $(this).off(settings.startevent, $(this).data.callee1).off(settings.endevent, $(this).data.callee2);
373        }
374    };
375
376    // singletap Event:
377    // This is used in conjuction with doubletap when both events are needed on the same element
378    $.event.special.singletap = {
379        setup: function () {
380            var thisObject = this,
381                $this = $(thisObject),
382                origTarget = null,
383                startTime = null,
384                start_pos = {
385                    x: 0,
386                    y: 0
387                };
388
389            $this.on(settings.startevent, function singleTapFunc1(e) {
390                if (e.which && e.which !== 1) {
391                    return false;
392                } else {
393                    startTime = Date.now();
394                    origTarget = e.target;
395                    $this.data('callee1', singleTapFunc1);
396
397                    // Get the start x and y position:
398                    start_pos.x = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageX : e.pageX;
399                    start_pos.y = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageY : e.pageY;
400                    
401                    return true;
402                }
403            }).on(settings.endevent, function singleTapFunc2(e) {
404                $this.data('callee2', singleTapFunc2);
405                if (e.target == origTarget) {
406                    
407                    // Get the end point:
408                    var end_pos_x = (e.originalEvent.changedTouches) ? e.originalEvent.changedTouches[0].pageX : e.pageX,
409                        end_pos_y = (e.originalEvent.changedTouches) ? e.originalEvent.changedTouches[0].pageY : e.pageY;
410                    
411                    // We need to check if it was a taphold:
412
413                    settings.tap_timer = window.setTimeout(function () {
414                        
415                        var diff_x = (start_pos.x - end_pos_x), diff_y = (start_pos.y - end_pos_y);
416                        
417                        if(!$this.data('doubletapped') && !$this.data('tapheld') && (((start_pos.x == end_pos_x) && (start_pos.y == end_pos_y)) || (diff_x >= -(settings.tap_pixel_range) && diff_x <= settings.tap_pixel_range && diff_y >= -(settings.tap_pixel_range) && diff_y <= settings.tap_pixel_range))) {
418
419                            var origEvent = e.originalEvent;
420                            var touchData = {
421                                'position': {
422                                    'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX,
423                                    'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY
424                                },
425                                'offset': {
426                                    'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)),
427									'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0))
428                                },
429                                'time': Date.now(),
430                                'target': e.target
431                            };
432                            
433                            // Was it a taphold?
434                            if((touchData.time - startTime) < settings.taphold_threshold)
435                            {
436                                triggerCustomEvent(thisObject, 'singletap', e, touchData);
437                            }
438                        }
439                    }, settings.doubletap_int);
440                }
441            });
442        },
443
444        remove: function () {
445            $(this).off(settings.startevent, $(this).data.callee1).off(settings.endevent, $(this).data.callee2);
446        }
447    };
448
449    // tap Event:
450    $.event.special.tap = {
451        setup: function () {
452            var thisObject = this,
453                $this = $(thisObject),
454                started = false,
455                origTarget = null,
456                start_time,
457                start_pos = {
458                    x: 0,
459                    y: 0
460                },
461                touches;
462
463            $this.on(settings.startevent, function tapFunc1(e) {
464                $this.data('callee1', tapFunc1);
465
466                if( e.which && e.which !== 1 )
467				{
468                    return false;
469                }
470				else
471				{
472                    started = true;
473                    start_pos.x = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageX : e.pageX;
474                    start_pos.y = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageY : e.pageY;
475                    start_time = Date.now();
476                    origTarget = e.target;
477					
478                    touches = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches : [ e ];
479                    return true;
480                }
481            }).on(settings.endevent, function tapFunc2(e) {
482                $this.data('callee2', tapFunc2);
483
484                // Only trigger if they've started, and the target matches:
485                var end_x = (e.originalEvent.targetTouches) ? e.originalEvent.changedTouches[0].pageX : e.pageX,
486                    end_y = (e.originalEvent.targetTouches) ? e.originalEvent.changedTouches[0].pageY : e.pageY,
487                    diff_x = (start_pos.x - end_x),
488                    diff_y = (start_pos.y - end_y),
489                    eventName;
490					
491                if (origTarget == e.target && started && ((Date.now() - start_time) < settings.taphold_threshold) && ((start_pos.x == end_x && start_pos.y == end_y) || (diff_x >= -(settings.tap_pixel_range) && diff_x <= settings.tap_pixel_range && diff_y >= -(settings.tap_pixel_range) && diff_y <= settings.tap_pixel_range))) {
492                    var origEvent = e.originalEvent;
493                    var touchData = [ ];
494					
495                    for( var i = 0; i < touches.length; i++)
496                    {
497                        var touch = {
498                            'position': {
499                                'x': (settings.touch_capable) ? origEvent.changedTouches[i].screenX : e.screenX,
500                                'y': (settings.touch_capable) ? origEvent.changedTouches[i].screenY : e.screenY
501                            },
502                            'offset': {
503                                'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)),
504                                'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[i].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0))
505                            },
506                            'time': Date.now(),
507                            'target': e.target
508                        };
509                    	
510                        touchData.push( touch );
511                    }
512                    
513                    triggerCustomEvent(thisObject, 'tap', e, touchData);
514                }
515            });
516        },
517
518        remove: function () {
519            $(this).off(settings.startevent, $(this).data.callee1).off(settings.endevent, $(this).data.callee2);
520        }
521    };
522
523    // swipe Event (also handles swipeup, swiperight, swipedown and swipeleft):
524    $.event.special.swipe = {
525        setup: function () {
526            var thisObject = this,
527                $this = $(thisObject),
528                started = false,
529                hasSwiped = false,
530                originalCoord = {
531                    x: 0,
532                    y: 0
533                },
534                finalCoord = {
535                    x: 0,
536                    y: 0
537                },
538                startEvnt;
539
540            // Screen touched, store the original coordinate
541
542            function touchStart(e) {
543                $this = $(e.currentTarget);
544                $this.data('callee1', touchStart);
545                originalCoord.x = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageX : e.pageX;
546                originalCoord.y = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageY : e.pageY;
547                finalCoord.x = originalCoord.x;
548                finalCoord.y = originalCoord.y;
549                started = true;
550                var origEvent = e.originalEvent;
551                // Read event data into our startEvt:
552                startEvnt = {
553                    'position': {
554                        'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX,
555                        'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY
556                    },
557                    'offset': {
558                        'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)),
559                        'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0))
560                    },
561                    'time': Date.now(),
562                    'target': e.target
563                };
564            }
565
566            // Store coordinates as finger is swiping
567
568            function touchMove(e) {
569                $this = $(e.currentTarget);
570                $this.data('callee2', touchMove);
571                finalCoord.x = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageX : e.pageX;
572                finalCoord.y = (e.originalEvent.targetTouches) ? e.originalEvent.targetTouches[0].pageY : e.pageY;
573
574                var swipedir;
575
576                // We need to check if the element to which the event was bound contains a data-xthreshold | data-vthreshold:
577                var ele_x_threshold = ($this.parent().data('xthreshold')) ? $this.parent().data('xthreshold') : $this.data('xthreshold'),
578                    ele_y_threshold = ($this.parent().data('ythreshold')) ? $this.parent().data('ythreshold') : $this.data('ythreshold'),
579                    h_threshold = (typeof ele_x_threshold !== 'undefined' && ele_x_threshold !== false && parseInt(ele_x_threshold)) ? parseInt(ele_x_threshold) : settings.swipe_h_threshold,
580                    v_threshold = (typeof ele_y_threshold !== 'undefined' && ele_y_threshold !== false && parseInt(ele_y_threshold)) ? parseInt(ele_y_threshold) : settings.swipe_v_threshold; 
581                
582                if (originalCoord.y > finalCoord.y && (originalCoord.y - finalCoord.y > v_threshold)) {
583                    swipedir = 'swipeup';
584                }
585                if (originalCoord.x < finalCoord.x && (finalCoord.x - originalCoord.x > h_threshold)) {
586                    swipedir = 'swiperight';
587                }
588                if (originalCoord.y < finalCoord.y && (finalCoord.y - originalCoord.y > v_threshold)) {
589                    swipedir = 'swipedown';
590                }
591                if (originalCoord.x > finalCoord.x && (originalCoord.x - finalCoord.x > h_threshold)) {
592                    swipedir = 'swipeleft';
593                }
594                if (swipedir != undefined && started) {
595                    originalCoord.x = 0;
596                    originalCoord.y = 0;
597                    finalCoord.x = 0;
598                    finalCoord.y = 0;
599                    started = false;
600
601                    // Read event data into our endEvnt:
602                    var origEvent = e.originalEvent;
603                    var endEvnt = {
604                        'position': {
605                            'x': (settings.touch_capable) ? origEvent.touches[0].screenX : e.screenX,
606                            'y': (settings.touch_capable) ? origEvent.touches[0].screenY : e.screenY
607                        },
608                        'offset': {
609                            'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)),
610                            'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0))
611                        },
612                        'time': Date.now(),
613                        'target': e.target
614                    };
615
616                    // Calculate the swipe amount (normalized):
617                    var xAmount = Math.abs(startEvnt.position.x - endEvnt.position.x),
618                        yAmount = Math.abs(startEvnt.position.y - endEvnt.position.y);
619
620                    var touchData = {
621                        'startEvnt': startEvnt,
622                        'endEvnt': endEvnt,
623                        'direction': swipedir.replace('swipe', ''),
624                        'xAmount': xAmount,
625                        'yAmount': yAmount,
626                        'duration': endEvnt.time - startEvnt.time
627                    };
628                    hasSwiped = true;
629                    $this.trigger('swipe', touchData).trigger(swipedir, touchData);
630                }
631            }
632
633            function touchEnd(e) {
634                $this = $(e.currentTarget);
635                var swipedir = "";
636                $this.data('callee3', touchEnd);
637                if (hasSwiped) {
638                    // We need to check if the element to which the event was bound contains a data-xthreshold | data-vthreshold:
639                    var ele_x_threshold = $this.data('xthreshold'),
640                        ele_y_threshold = $this.data('ythreshold'),
641                        h_threshold = (typeof ele_x_threshold !== 'undefined' && ele_x_threshold !== false && parseInt(ele_x_threshold)) ? parseInt(ele_x_threshold) : settings.swipe_h_threshold,
642                        v_threshold = (typeof ele_y_threshold !== 'undefined' && ele_y_threshold !== false && parseInt(ele_y_threshold)) ? parseInt(ele_y_threshold) : settings.swipe_v_threshold;
643
644                    var origEvent = e.originalEvent;
645                    var endEvnt = {
646                        'position': {
647                            'x': (settings.touch_capable) ? origEvent.changedTouches[0].screenX : e.screenX,
648                            'y': (settings.touch_capable) ? origEvent.changedTouches[0].screenY : e.screenY
649                        },
650                        'offset': {
651                            'x': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageX - ($this.offset() ? $this.offset().left : 0)) : Math.round(e.pageX - ($this.offset() ? $this.offset().left : 0)),
652                            'y': (settings.touch_capable) ? Math.round(origEvent.changedTouches[0].pageY - ($this.offset() ? $this.offset().top : 0)) : Math.round(e.pageY - ($this.offset() ? $this.offset().top : 0))
653                        },
654                        'time': Date.now(),
655                        'target': e.target
656                    };
657
658                    // Read event data into our endEvnt:
659                    if (startEvnt.position.y > endEvnt.position.y && (startEvnt.position.y - endEvnt.position.y > v_threshold)) {
660                        swipedir = 'swipeup';
661                    }
662                    if (startEvnt.position.x < endEvnt.position.x && (endEvnt.position.x - startEvnt.position.x > h_threshold)) {
663                        swipedir = 'swiperight';
664                    }
665                    if (startEvnt.position.y < endEvnt.position.y && (endEvnt.position.y - startEvnt.position.y > v_threshold)) {
666                        swipedir = 'swipedown';
667                    }
668                    if (startEvnt.position.x > endEvnt.position.x && (startEvnt.position.x - endEvnt.position.x > h_threshold)) {
669                        swipedir = 'swipeleft';
670                    }
671
672                    // Calculate the swipe amount (normalized):
673                    var xAmount = Math.abs(startEvnt.position.x - endEvnt.position.x),
674                        yAmount = Math.abs(startEvnt.position.y - endEvnt.position.y);
675
676                    var touchData = {
677                        'startEvnt': startEvnt,
678                        'endEvnt': endEvnt,
679                        'direction': swipedir.replace('swipe', ''),
680                        'xAmount': xAmount,
681                        'yAmount': yAmount,
682                        'duration': endEvnt.time - startEvnt.time
683                    };
684                    $this.trigger('swipeend', touchData);
685                }
686
687                started = false;
688                hasSwiped = false;
689            }
690
691            $this.on(settings.startevent, touchStart);
692            $this.on(settings.moveevent, touchMove);
693            $this.on(settings.endevent, touchEnd);
694        },
695
696        remove: function () {
697            $(this).off(settings.startevent, $(this).data.callee1).off(settings.moveevent, $(this).data.callee2).off(settings.endevent, $(this).data.callee3);
698        }
699    };
700
701    // scrollstart Event (also handles scrollend):
702    $.event.special.scrollstart = {
703        setup: function () {
704            var thisObject = this,
705                $this = $(thisObject),
706                scrolling,
707                timer;
708
709            function trigger(event, state) {
710                scrolling = state;
711                triggerCustomEvent(thisObject, scrolling ? 'scrollstart' : 'scrollend', event);
712            }
713
714            // iPhone triggers scroll after a small delay; use touchmove instead
715            $this.on(settings.scrollevent, function scrollFunc(event) {
716                $this.data('callee', scrollFunc);
717
718                if (!scrolling) {
719                    trigger(event, true);
720                }
721
722                clearTimeout(timer);
723                timer = setTimeout(function () {
724                    trigger(event, false);
725                }, 50);
726            });
727        },
728
729        remove: function () {
730            $(this).off(settings.scrollevent, $(this).data.callee);
731        }
732    };
733
734    // This is the orientation change (largely borrowed from jQuery Mobile):
735    var win = $(window),
736        special_event,
737        get_orientation,
738        last_orientation,
739        initial_orientation_is_landscape,
740        initial_orientation_is_default,
741        portrait_map = {
742            '0': true,
743            '180': true
744        };
745
746    if (settings.orientation_support) {
747        var ww = window.innerWidth || win.width(),
748            wh = window.innerHeight || win.height(),
749            landscape_threshold = 50;
750
751        initial_orientation_is_landscape = ww > wh && (ww - wh) > landscape_threshold;
752        initial_orientation_is_default = portrait_map[window.orientation];
753
754        if ((initial_orientation_is_landscape && initial_orientation_is_default) || (!initial_orientation_is_landscape && !initial_orientation_is_default)) {
755            portrait_map = {
756                '-90': true,
757                '90': true
758            };
759        }
760    }
761
762    $.event.special.orientationchange = special_event = {
763        setup: function () {
764            // If the event is supported natively, return false so that jQuery
765            // will on to the event using DOM methods.
766            if (settings.orientation_support) {
767                return false;
768            }
769
770            // Get the current orientation to avoid initial double-triggering.
771            last_orientation = get_orientation();
772
773            win.on('throttledresize', handler);
774            return true;
775        },
776        teardown: function () {
777            if (settings.orientation_support) {
778                return false;
779            }
780
781            win.off('throttledresize', handler);
782            return true;
783        },
784        add: function (handleObj) {
785            // Save a reference to the bound event handler.
786            var old_handler = handleObj.handler;
787
788            handleObj.handler = function (event) {
789                event.orientation = get_orientation();
790                return old_handler.apply(this, arguments);
791            };
792        }
793    };
794
795    // If the event is not supported natively, this handler will be bound to
796    // the window resize event to simulate the orientationchange event.
797
798    function handler() {
799        // Get the current orientation.
800        var orientation = get_orientation();
801
802        if (orientation !== last_orientation) {
803            // The orientation has changed, so trigger the orientationchange event.
804            last_orientation = orientation;
805            win.trigger("orientationchange");
806        }
807    }
808
809    $.event.special.orientationchange.orientation = get_orientation = function () {
810        var isPortrait = true,
811            elem = document.documentElement;
812
813        if (settings.orientation_support) {
814            isPortrait = portrait_map[window.orientation];
815        } else {
816            isPortrait = elem && elem.clientWidth / elem.clientHeight < 1.1;
817        }
818
819        return isPortrait ? 'portrait' : 'landscape';
820    };
821
822    // throttle Handler:
823    $.event.special.throttledresize = {
824        setup: function () {
825            $(this).on('resize', throttle_handler);
826        },
827        teardown: function () {
828            $(this).off('resize', throttle_handler);
829        }
830    };
831
832    var throttle = 250,
833        throttle_handler = function () {
834            curr = Date.now();
835            diff = curr - lastCall;
836
837            if (diff >= throttle) {
838                lastCall = curr;
839                $(this).trigger('throttledresize');
840
841            } else {
842                if (heldCall) {
843                    window.clearTimeout(heldCall);
844                }
845
846                // Promise a held call will still execute
847                heldCall = window.setTimeout(handler, throttle - diff);
848            }
849        },
850        lastCall = 0,
851        heldCall,
852        curr,
853        diff;
854
855    // Trigger a custom event:
856
857    function triggerCustomEvent(obj, eventType, event, touchData) {
858        var originalType = event.type;
859        event.type = eventType;
860
861        $.event.dispatch.call(obj, event, touchData);
862        event.type = originalType;
863    }
864
865    // Correctly on anything we've overloaded:
866    $.each({
867        scrollend: 'scrollstart',
868        swipeup: 'swipe',
869        swiperight: 'swipe',
870        swipedown: 'swipe',
871        swipeleft: 'swipe',
872        swipeend: 'swipe',
873        tap2: 'tap'
874    }, function (e, srcE) {
875        $.event.special[e] = {
876            setup: function () {
877                $(this).on(srcE, $.noop);
878            }
879        };
880    });
881
882}(jQuery));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.