PageSourceSearch

http://baotangchienthangb52.com.vn/3rdparty/mobility/vendor/jquery.mobile-events.js

js baotangchienthangb52.com.vn collected 2026-10-02 12:30:42 UTC 40,203 bytes, 873 lines download raw bytes

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