vendor: 25,833 bytes, lines 1-877
1/* 2 * @fileOverview TouchSwipe - jQuery Plugin 3 * @version 1.6.9 4 * 5 * @author Matt Bryson http://www.github.com/mattbryson 6 * @see https://github.com/mattbryson/TouchSwipe-Jquery-Plugin 7 * @see http://labs.rampinteractive.co.uk/touchSwipe/ 8 * @see http://plugins.jquery.com/project/touchSwipe 9 * 10 * Copyright (c) 2010-2015 Matt Bryson 11 * Dual licensed under the MIT or GPL Version 2 licenses. 12 * 13 */ 14 15(function(factory) { 16 if (typeof define === 'function' && define.amd && define.amd.jQuery) { 17 define(['jquery'], factory); 18 } else { 19 factory(jQuery); 20 } 21}(function($) { 22 "use strict"; 23 var VERSION = "1.6.9", 24 LEFT = "left", 25 RIGHT = "right", 26 UP = "up", 27 DOWN = "down", 28 IN = "in", 29 OUT = "out", 30 NONE = "none", 31 AUTO = "auto", 32 SWIPE = "swipe", 33 PINCH = "pinch", 34 TAP = "tap", 35 DOUBLE_TAP = "doubletap", 36 LONG_TAP = "longtap", 37 HOLD = "hold", 38 HORIZONTAL = "horizontal", 39 VERTICAL = "vertical", 40 ALL_FINGERS = "all", 41 DOUBLE_TAP_THRESHOLD = 10, 42 PHASE_START = "start", 43 PHASE_MOVE = "move", 44 PHASE_END = "end", 45 PHASE_CANCEL = "cancel", 46 SUPPORTS_TOUCH = 'ontouchstart' in window, 47 SUPPORTS_POINTER_IE10 = window.navigator.msPointerEnabled && !window.navigator.pointerEnabled, 48 SUPPORTS_POINTER = window.navigator.pointerEnabled || window.navigator.msPointerEnabled, 49 PLUGIN_NS = 'TouchSwipe'; 50 var defaults = { 51 fingers: 1, 52 threshold: 75, 53 cancelThreshold: null, 54 pinchThreshold: 20, 55 maxTimeThreshold: null, 56 fingerReleaseThreshold: 250, 57 longTapThreshold: 500, 58 doubleTapThreshold: 200, 59 swipe: null, 60 swipeLeft: null, 61 swipeRight: null, 62 swipeUp: null, 63 swipeDown: null, 64 swipeStatus: null, 65 pinchIn: null, 66 pinchOut: null, 67 pinchStatus: null, 68 click: null, 69 tap: null, 70 doubleTap: null, 71 longTap: null, 72 hold: null, 73 triggerOnTouchEnd: true, 74 triggerOnTouchLeave: false, 75 allowPageScroll: "auto", 76 fallbackToMouseEvents: true, 77 excludedElements: "label, button, input, select, textarea, a, .noSwipe", 78 preventDefaultEvents: true 79 }; 80 $.fn.swipe = function(method) { 81 var $this = $(this), 82 plugin = $this.data(PLUGIN_NS); 83 if (plugin && typeof method === 'string') { 84 if (plugin[method]) { 85 return plugin[method].apply(this, Array.prototype.slice.call(arguments, 1)); 86 } else { 87 $.error('Method ' + method + ' does not exist on jQuery.swipe'); 88 } 89 } else if (!plugin && (typeof method === 'object' || !method)) { 90 return init.apply(this, arguments); 91 } 92 return $this; 93 }; 94 $.fn.swipe.version = VERSION; 95 $.fn.swipe.defaults = defaults; 96 $.fn.swipe.phases = { 97 PHASE_START: PHASE_START, 98 PHASE_MOVE: PHASE_MOVE, 99 PHASE_END: PHASE_END, 100 PHASE_CANCEL: PHASE_CANCEL 101 }; 102 $.fn.swipe.directions = { 103 LEFT: LEFT, 104 RIGHT: RIGHT, 105 UP: UP, 106 DOWN: DOWN, 107 IN: IN, 108 OUT: OUT 109 }; 110 $.fn.swipe.pageScroll = { 111 NONE: NONE, 112 HORIZONTAL: HORIZONTAL, 113 VERTICAL: VERTICAL, 114 AUTO: AUTO 115 }; 116 $.fn.swipe.fingers = { 117 ONE: 1, 118 TWO: 2, 119 THREE: 3, 120 ALL: ALL_FINGERS 121 }; 122 123 function init(options) { 124 if (options && (options.allowPageScroll === undefined && (options.swipe !== undefined || options.swipeStatus !== undefined))) { 125 options.allowPageScroll = NONE; 126 } 127 if (options.click !== undefined && options.tap === undefined) { 128 options.tap = options.click; 129 } 130 if (!options) { 131 options = {}; 132 } 133 options = $.extend({}, $.fn.swipe.defaults, options); 134 return this.each(function() { 135 var $this = $(this); 136 var plugin = $this.data(PLUGIN_NS); 137 if (!plugin) { 138 plugin = new TouchSwipe(this, options); 139 $this.data(PLUGIN_NS, plugin); 140 } 141 }); 142 } 143 144 function TouchSwipe(element, options) { 145 var useTouchEvents = (SUPPORTS_TOUCH || SUPPORTS_POINTER || !options.fallbackToMouseEvents), 146 START_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerDown' : 'pointerdown') : 'touchstart') : 'mousedown', 147 MOVE_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerMove' : 'pointermove') : 'touchmove') : 'mousemove', 148 END_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerUp' : 'pointerup') : 'touchend') : 'mouseup', 149 LEAVE_EV = useTouchEvents ? null : 'mouseleave', 150 CANCEL_EV = (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerCancel' : 'pointercancel') : 'touchcancel'); 151 var distance = 0, 152 direction = null, 153 duration = 0, 154 startTouchesDistance = 0, 155 endTouchesDistance = 0, 156 pinchZoom = 1, 157 pinchDistance = 0, 158 pinchDirection = 0, 159 maximumsMap = null; 160 var $element = $(element); 161 var phase = "start"; 162 var fingerCount = 0; 163 var fingerData = null; 164 var startTime = 0, 165 endTime = 0, 166 previousTouchEndTime = 0, 167 previousTouchFingerCount = 0, 168 doubleTapStartTime = 0; 169 var singleTapTimeout = null, 170 holdTimeout = null; 171 try { 172 $element.bind(START_EV, touchStart); 173 $element.bind(CANCEL_EV, touchCancel); 174 } catch (e) { 175 $.error('events not supported ' + START_EV + ',' + CANCEL_EV + ' on jQuery.swipe'); 176 } 177 this.enable = function() { 178 $element.bind(START_EV, touchStart); 179 $element.bind(CANCEL_EV, touchCancel); 180 return $element; 181 }; 182 this.disable = function() { 183 removeListeners(); 184 return $element; 185 }; 186 this.destroy = function() { 187 removeListeners(); 188 $element.data(PLUGIN_NS, null); 189 $element = null; 190 }; 191 this.option = function(property, value) { 192 if (options[property] !== undefined) { 193 if (value === undefined) { 194 return options[property]; 195 } else { 196 options[property] = value; 197 } 198 } else { 199 $.error('Option ' + property + ' does not exist on jQuery.swipe.options'); 200 } 201 return null; 202 } 203 204 function touchStart(jqEvent) { 205 if (getTouchInProgress()) 206 return; 207 if ($(jqEvent.target).closest(options.excludedElements, $element).length > 0) 208 return; 209 var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent; 210 var ret, touches = event.touches, 211 evt = touches ? touches[0] : event; 212 phase = PHASE_START; 213 if (touches) { 214 fingerCount = touches.length; 215 } else { 216 jqEvent.preventDefault(); 217 } 218 distance = 0; 219 direction = null; 220 pinchDirection = null; 221 duration = 0; 222 startTouchesDistance = 0; 223 endTouchesDistance = 0; 224 pinchZoom = 1; 225 pinchDistance = 0; 226 fingerData = createAllFingerData(); 227 maximumsMap = createMaximumsData(); 228 cancelMultiFingerRelease(); 229 if (!touches || (fingerCount === options.fingers || options.fingers === ALL_FINGERS) || hasPinches()) { 230 createFingerData(0, evt); 231 startTime = getTimeStamp(); 232 if (fingerCount == 2) { 233 createFingerData(1, touches[1]); 234 startTouchesDistance = endTouchesDistance = calculateTouchesDistance(fingerData[0].start, fingerData[1].start); 235 } 236 if (options.swipeStatus || options.pinchStatus) { 237 ret = triggerHandler(event, phase); 238 } 239 } else { 240 ret = false; 241 } 242 if (ret === false) { 243 phase = PHASE_CANCEL; 244 triggerHandler(event, phase); 245 return ret; 246 } else { 247 if (options.hold) { 248 holdTimeout = setTimeout($.proxy(function() { 249 $element.trigger('hold', [event.target]); 250 if (options.hold) { 251 ret = options.hold.call($element, event, event.target); 252 } 253 }, this), options.longTapThreshold); 254 } 255 setTouchInProgress(true); 256 } 257 return null; 258 }; 259 260 function touchMove(jqEvent) { 261 var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent; 262 if (phase === PHASE_END || phase === PHASE_CANCEL || inMultiFingerRelease()) 263 return; 264 var ret, touches = event.touches, 265 evt = touches ? touches[0] : event; 266 var currentFinger = updateFingerData(evt); 267 endTime = getTimeStamp(); 268 if (touches) { 269 fingerCount = touches.length; 270 } 271 if (options.hold) 272 clearTimeout(holdTimeout); 273 phase = PHASE_MOVE; 274 if (fingerCount == 2) { 275 if (startTouchesDistance == 0) { 276 createFingerData(1, touches[1]); 277 startTouchesDistance = endTouchesDistance = calculateTouchesDistance(fingerData[0].start, fingerData[1].start); 278 } else { 279 updateFingerData(touches[1]); 280 endTouchesDistance = calculateTouchesDistance(fingerData[0].end, fingerData[1].end); 281 pinchDirection = calculatePinchDirection(fingerData[0].end, fingerData[1].end); 282 } 283 pinchZoom = calculatePinchZoom(startTouchesDistance, endTouchesDistance); 284 pinchDistance = Math.abs(startTouchesDistance - endTouchesDistance); 285 } 286 if ((fingerCount === options.fingers || options.fingers === ALL_FINGERS) || !touches || hasPinches()) { 287 direction = calculateDirection(currentFinger.start, currentFinger.end); 288 validateDefaultEvent(jqEvent, direction); 289 distance = calculateDistance(currentFinger.start, currentFinger.end); 290 duration = calculateDuration(); 291 setMaxDistance(direction, distance); 292 if (options.swipeStatus || options.pinchStatus) { 293 ret = triggerHandler(event, phase); 294 } 295 if (!options.triggerOnTouchEnd || options.triggerOnTouchLeave) { 296 var inBounds = true; 297 if (options.triggerOnTouchLeave) { 298 var bounds = getbounds(this); 299 inBounds = isInBounds(currentFinger.end, bounds); 300 } 301 if (!options.triggerOnTouchEnd && inBounds) { 302 phase = getNextPhase(PHASE_MOVE); 303 } else if (options.triggerOnTouchLeave && !inBounds) { 304 phase = getNextPhase(PHASE_END); 305 } 306 if (phase == PHASE_CANCEL || phase == PHASE_END) { 307 triggerHandler(event, phase); 308 } 309 } 310 } else { 311 phase = PHASE_CANCEL; 312 triggerHandler(event, phase); 313 } 314 if (ret === false) { 315 phase = PHASE_CANCEL; 316 triggerHandler(event, phase); 317 } 318 } 319 320 function touchEnd(jqEvent) { 321 var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent, 322 touches = event.touches; 323 if (touches) { 324 if (touches.length) { 325 startMultiFingerRelease(); 326 return true; 327 } 328 } 329 if (inMultiFingerRelease()) { 330 fingerCount = previousTouchFingerCount; 331 } 332 endTime = getTimeStamp(); 333 duration = calculateDuration(); 334 if (didSwipeBackToCancel() || !validateSwipeDistance()) { 335 phase = PHASE_CANCEL; 336 triggerHandler(event, phase); 337 } else if (options.triggerOnTouchEnd || (options.triggerOnTouchEnd == false && phase === PHASE_MOVE)) { 338 jqEvent.preventDefault(); 339 phase = PHASE_END; 340 triggerHandler(event, phase); 341 } else if (!options.triggerOnTouchEnd && hasTap()) { 342 phase = PHASE_END; 343 triggerHandlerForGesture(event, phase, TAP); 344 } else if (phase === PHASE_MOVE) { 345 phase = PHASE_CANCEL; 346 triggerHandler(event, phase); 347 } 348 setTouchInProgress(false); 349 return null; 350 } 351 352 function touchCancel() { 353 fingerCount = 0; 354 endTime = 0; 355 startTime = 0; 356 startTouchesDistance = 0; 357 endTouchesDistance = 0; 358 pinchZoom = 1; 359 cancelMultiFingerRelease(); 360 setTouchInProgress(false); 361 } 362 363 function touchLeave(jqEvent) { 364 var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent; 365 if (options.triggerOnTouchLeave) { 366 phase = getNextPhase(PHASE_END); 367 triggerHandler(event, phase); 368 } 369 } 370 371 function removeListeners() { 372 $element.unbind(START_EV, touchStart); 373 $element.unbind(CANCEL_EV, touchCancel); 374 $element.unbind(MOVE_EV, touchMove); 375 $element.unbind(END_EV, touchEnd); 376 if (LEAVE_EV) { 377 $element.unbind(LEAVE_EV, touchLeave); 378 } 379 setTouchInProgress(false); 380 } 381 382 function getNextPhase(currentPhase) { 383 var nextPhase = currentPhase; 384 var validTime = validateSwipeTime(); 385 var validDistance = validateSwipeDistance(); 386 var didCancel = didSwipeBackToCancel(); 387 if (!validTime || didCancel) { 388 nextPhase = PHASE_CANCEL; 389 } else if (validDistance && currentPhase == PHASE_MOVE && (!options.triggerOnTouchEnd || options.triggerOnTouchLeave)) { 390 nextPhase = PHASE_END; 391 } else if (!validDistance && currentPhase == PHASE_END && options.triggerOnTouchLeave) { 392 nextPhase = PHASE_CANCEL; 393 } 394 return nextPhase; 395 } 396 397 function triggerHandler(event, phase) { 398 var ret, touches = event.touches; 399 if ((didSwipe() || hasSwipes()) || (didPinch() || hasPinches())) { 400 if (didSwipe() || hasSwipes()) { 401 ret = triggerHandlerForGesture(event, phase, SWIPE); 402 } 403 if ((didPinch() || hasPinches()) && ret !== false) { 404 ret = triggerHandlerForGesture(event, phase, PINCH); 405 } 406 } else { 407 if (didDoubleTap() && ret !== false) { 408 ret = triggerHandlerForGesture(event, phase, DOUBLE_TAP); 409 } else if (didLongTap() && ret !== false) { 410 ret = triggerHandlerForGesture(event, phase, LONG_TAP); 411 } else if (didTap() && ret !== false) { 412 ret = triggerHandlerForGesture(event, phase, TAP); 413 } 414 } 415 if (phase === PHASE_CANCEL) { 416 touchCancel(event); 417 } 418 if (phase === PHASE_END) { 419 if (touches) { 420 if (!touches.length) { 421 touchCancel(event); 422 } 423 } else { 424 touchCancel(event); 425 } 426 } 427 return ret; 428 } 429 430 function triggerHandlerForGesture(event, phase, gesture) { 431 var ret; 432 if (gesture == SWIPE) { 433 $element.trigger('swipeStatus', [phase, direction || null, distance || 0, duration || 0, fingerCount, fingerData]); 434 if (options.swipeStatus) { 435 ret = options.swipeStatus.call($element, event, phase, direction || null, distance || 0, duration || 0, fingerCount, fingerData); 436 if (ret === false) return false; 437 } 438 if (phase == PHASE_END && validateSwipe()) { 439 $element.trigger('swipe', [direction, distance, duration, fingerCount, fingerData]); 440 if (options.swipe) { 441 ret = options.swipe.call($element, event, direction, distance, duration, fingerCount, fingerData); 442 if (ret === false) return false; 443 } 444 switch (direction) { 445 case LEFT: 446 $element.trigger('swipeLeft', [direction, distance, duration, fingerCount, fingerData]); 447 if (options.swipeLeft) { 448 ret = options.swipeLeft.call($element, event, direction, distance, duration, fingerCount, fingerData); 449 } 450 break; 451 case RIGHT: 452 $element.trigger('swipeRight', [direction, distance, duration, fingerCount, fingerData]); 453 if (options.swipeRight) { 454 ret = options.swipeRight.call($element, event, direction, distance, duration, fingerCount, fingerData); 455 } 456 break; 457 case UP: 458 $element.trigger('swipeUp', [direction, distance, duration, fingerCount, fingerData]); 459 if (options.swipeUp) { 460 ret = options.swipeUp.call($element, event, direction, distance, duration, fingerCount, fingerData); 461 } 462 break; 463 case DOWN: 464 $element.trigger('swipeDown', [direction, distance, duration, fingerCount, fingerData]); 465 if (options.swipeDown) { 466 ret = options.swipeDown.call($element, event, direction, distance, duration, fingerCount, fingerData); 467 } 468 break; 469 } 470 } 471 } 472 if (gesture == PINCH) { 473 $element.trigger('pinchStatus', [phase, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]); 474 if (options.pinchStatus) { 475 ret = options.pinchStatus.call($element, event, phase, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData); 476 if (ret === false) return false; 477 } 478 if (phase == PHASE_END && validatePinch()) { 479 switch (pinchDirection) { 480 case IN: 481 $element.trigger('pinchIn', [pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]); 482 if (options.pinchIn) { 483 ret = options.pinchIn.call($element, event, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData); 484 } 485 break; 486 case OUT: 487 $element.trigger('pinchOut', [pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]); 488 if (options.pinchOut) { 489 ret = options.pinchOut.call($element, event, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData); 490 } 491 break; 492 } 493 } 494 } 495 if (gesture == TAP) { 496 if (phase === PHASE_CANCEL || phase === PHASE_END) { 497 clearTimeout(singleTapTimeout); 498 clearTimeout(holdTimeout); 499 if (hasDoubleTap() && !inDoubleTap()) { 500 doubleTapStartTime = getTimeStamp(); 501 singleTapTimeout = setTimeout($.proxy(function() { 502 doubleTapStartTime = null; 503 $element.trigger('tap', [event.target]); 504 if (options.tap) { 505 ret = options.tap.call($element, event, event.target); 506 } 507 }, this), options.doubleTapThreshold); 508 } else { 509 doubleTapStartTime = null; 510 $element.trigger('tap', [event.target]); 511 if (options.tap) { 512 ret = options.tap.call($element, event, event.target); 513 } 514 } 515 } 516 } else if (gesture == DOUBLE_TAP) { 517 if (phase === PHASE_CANCEL || phase === PHASE_END) { 518 clearTimeout(singleTapTimeout); 519 doubleTapStartTime = null; 520 $element.trigger('doubletap', [event.target]); 521 if (options.doubleTap) { 522 ret = options.doubleTap.call($element, event, event.target); 523 } 524 } 525 } else if (gesture == LONG_TAP) { 526 if (phase === PHASE_CANCEL || phase === PHASE_END) { 527 clearTimeout(singleTapTimeout); 528 doubleTapStartTime = null; 529 $element.trigger('longtap', [event.target]); 530 if (options.longTap) { 531 ret = options.longTap.call($element, event, event.target); 532 } 533 } 534 } 535 return ret; 536 } 537 538 function validateSwipeDistance() { 539 var valid = true; 540 if (options.threshold !== null) { 541 valid = distance >= options.threshold; 542 } 543 return valid; 544 } 545 546 function didSwipeBackToCancel() { 547 var cancelled = false; 548 if (options.cancelThreshold !== null && direction !== null) { 549 cancelled = (getMaxDistance(direction) - distance) >= options.cancelThreshold; 550 } 551 return cancelled; 552 } 553 554 function validatePinchDistance() { 555 if (options.pinchThreshold !== null) { 556 return pinchDistance >= options.pinchThreshold; 557 } 558 return true; 559 } 560 561 function validateSwipeTime() { 562 var result; 563 if (options.maxTimeThreshold) { 564 if (duration >= options.maxTimeThreshold) { 565 result = false; 566 } else { 567 result = true; 568 } 569 } else { 570 result = true; 571 } 572 return result; 573 } 574 575 function validateDefaultEvent(jqEvent, direction) { 576 if (options.preventDefaultEvents === false) { 577 return; 578 } 579 if (options.allowPageScroll === NONE) { 580 jqEvent.preventDefault(); 581 } else { 582 var auto = options.allowPageScroll === AUTO; 583 switch (direction) { 584 case LEFT: 585 if ((options.swipeLeft && auto) || (!auto && options.allowPageScroll != HORIZONTAL)) { 586 jqEvent.preventDefault(); 587 } 588 break; 589 case RIGHT: 590 if ((options.swipeRight && auto) || (!auto && options.allowPageScroll != HORIZONTAL)) { 591 jqEvent.preventDefault(); 592 } 593 break; 594 case UP: 595 if ((options.swipeUp && auto) || (!auto && options.allowPageScroll != VERTICAL)) { 596 jqEvent.preventDefault(); 597 } 598 break; 599 case DOWN: 600 if ((options.swipeDown && auto) || (!auto && options.allowPageScroll != VERTICAL)) { 601 jqEvent.preventDefault(); 602 } 603 break; 604 } 605 } 606 } 607 608 function validatePinch() { 609 var hasCorrectFingerCount = validateFingers(); 610 var hasEndPoint = validateEndPoint(); 611 var hasCorrectDistance = validatePinchDistance(); 612 return hasCorrectFingerCount && hasEndPoint && hasCorrectDistance; 613 } 614 615 function hasPinches() { 616 return !!(options.pinchStatus || options.pinchIn || options.pinchOut); 617 } 618 619 function didPinch() { 620 return !!(validatePinch() && hasPinches()); 621 } 622 623 function validateSwipe() { 624 var hasValidTime = validateSwipeTime(); 625 var hasValidDistance = validateSwipeDistance(); 626 var hasCorrectFingerCount = validateFingers(); 627 var hasEndPoint = validateEndPoint(); 628 var didCancel = didSwipeBackToCancel(); 629 var valid = !didCancel && hasEndPoint && hasCorrectFingerCount && hasValidDistance && hasValidTime; 630 return valid; 631 } 632 633 function hasSwipes() { 634 return !!(options.swipe || options.swipeStatus || options.swipeLeft || options.swipeRight || options.swipeUp || options.swipeDown); 635 } 636 637 function didSwipe() { 638 return !!(validateSwipe() && hasSwipes()); 639 } 640 641 function validateFingers() { 642 return ((fingerCount === options.fingers || options.fingers === ALL_FINGERS) || !SUPPORTS_TOUCH); 643 } 644 645 function validateEndPoint() { 646 return fingerData[0].end.x !== 0; 647 } 648 649 function hasTap() { 650 return !!(options.tap); 651 } 652 653 function hasDoubleTap() { 654 return !!(options.doubleTap); 655 } 656 657 function hasLongTap() { 658 return !!(options.longTap); 659 } 660 661 function validateDoubleTap() { 662 if (doubleTapStartTime == null) { 663 return false; 664 } 665 var now = getTimeStamp(); 666 return (hasDoubleTap() && ((now - doubleTapStartTime) <= options.doubleTapThreshold)); 667 } 668 669 function inDoubleTap() { 670 return validateDoubleTap(); 671 } 672 673 function validateTap() { 674 return ((fingerCount === 1 || !SUPPORTS_TOUCH) && (isNaN(distance) || distance < options.threshold)); 675 } 676 677 function validateLongTap() { 678 return ((duration > options.longTapThreshold) && (distance < DOUBLE_TAP_THRESHOLD)); 679 } 680 681 function didTap() { 682 return !!(validateTap() && hasTap()); 683 } 684 685 function didDoubleTap() { 686 return !!(validateDoubleTap() && hasDoubleTap()); 687 } 688 689 function didLongTap() { 690 return !!(validateLongTap() && hasLongTap()); 691 } 692 693 function startMultiFingerRelease() { 694 previousTouchEndTime = getTimeStamp(); 695 previousTouchFingerCount = event.touches.length + 1; 696 } 697 698 function cancelMultiFingerRelease() { 699 previousTouchEndTime = 0; 700 previousTouchFingerCount = 0; 701 } 702 703 function inMultiFingerRelease() { 704 var withinThreshold = false; 705 if (previousTouchEndTime) { 706 var diff = getTimeStamp() - previousTouchEndTime 707 if (diff <= options.fingerReleaseThreshold) { 708 withinThreshold = true; 709 } 710 } 711 return withinThreshold; 712 } 713 714 function getTouchInProgress() { 715 return !!($element.data(PLUGIN_NS + '_intouch') === true); 716 } 717 718 function setTouchInProgress(val) { 719 if (val === true) { 720 $element.bind(MOVE_EV, touchMove); 721 $element.bind(END_EV, touchEnd); 722 if (LEAVE_EV) { 723 $element.bind(LEAVE_EV, touchLeave); 724 } 725 } else { 726 $element.unbind(MOVE_EV, touchMove, false); 727 $element.unbind(END_EV, touchEnd, false); 728 if (LEAVE_EV) { 729 $element.unbind(LEAVE_EV, touchLeave, false); 730 } 731 } 732 $element.data(PLUGIN_NS + '_intouch', val === true); 733 } 734 735 function createFingerData(index, evt) { 736 var id = evt.identifier !== undefined ? evt.identifier : 0; 737 fingerData[index].identifier = id; 738 fingerData[index].start.x = fingerData[index].end.x = evt.pageX || evt.clientX; 739 fingerData[index].start.y = fingerData[index].end.y = evt.pageY || evt.clientY; 740 return fingerData[index]; 741 } 742 743 function updateFingerData(evt) { 744 var id = evt.identifier !== undefined ? evt.identifier : 0; 745 var f = getFingerData(id); 746 f.end.x = evt.pageX || evt.clientX; 747 f.end.y = evt.pageY || evt.clientY; 748 return f; 749 } 750 751 function getFingerData(id) { 752 for (var i = 0; i < fingerData.length; i++) { 753 if (fingerData[i].identifier == id) { 754 return fingerData[i]; 755 } 756 } 757 } 758 759 function createAllFingerData() { 760 var fingerData = []; 761 for (var i = 0; i <= 5; i++) { 762 fingerData.push({ 763 start: { 764 x: 0, 765 y: 0 766 }, 767 end: { 768 x: 0, 769 y: 0 770 }, 771 identifier: 0 772 }); 773 } 774 return fingerData; 775 } 776 777 function setMaxDistance(direction, distance) { 778 distance = Math.max(distance, getMaxDistance(direction)); 779 maximumsMap[direction].distance = distance; 780 } 781 782 function getMaxDistance(direction) { 783 if (maximumsMap[direction]) return maximumsMap[direction].distance; 784 return undefined; 785 } 786 787 function createMaximumsData() { 788 var maxData = {}; 789 maxData[LEFT] = createMaximumVO(LEFT); 790 maxData[RIGHT] = createMaximumVO(RIGHT); 791 maxData[UP] = createMaximumVO(UP); 792 maxData[DOWN] = createMaximumVO(DOWN); 793 return maxData; 794 } 795 796 function createMaximumVO(dir) { 797 return { 798 direction: dir, 799 distance: 0 800 } 801 } 802 803 function calculateDuration() { 804 return endTime - startTime; 805 } 806 807 function calculateTouchesDistance(startPoint, endPoint) { 808 var diffX = Math.abs(startPoint.x - endPoint.x); 809 var diffY = Math.abs(startPoint.y - endPoint.y); 810 return Math.round(Math.sqrt(diffX * diffX + diffY * diffY)); 811 } 812 813 function calculatePinchZoom(startDistance, endDistance) { 814 var percent = (endDistance / startDistance) * 1; 815 return percent.toFixed(2); 816 } 817 818 function calculatePinchDirection() { 819 if (pinchZoom < 1) { 820 return OUT; 821 } else { 822 return IN; 823 } 824 } 825 826 function calculateDistance(startPoint, endPoint) { 827 return Math.round(Math.sqrt(Math.pow(endPoint.x - startPoint.x, 2) + Math.pow(endPoint.y - startPoint.y, 2))); 828 } 829 830 function calculateAngle(startPoint, endPoint) { 831 var x = startPoint.x - endPoint.x; 832 var y = endPoint.y - startPoint.y; 833 var r = Math.atan2(y, x); 834 var angle = Math.round(r * 180 / Math.PI); 835 if (angle < 0) { 836 angle = 360 - Math.abs(angle); 837 } 838 return angle; 839 } 840 841 function calculateDirection(startPoint, endPoint) { 842 var angle = calculateAngle(startPoint, endPoint); 843 if ((angle <= 45) && (angle >= 0)) { 844 return LEFT; 845 } else if ((angle <= 360) && (angle >= 315)) { 846 return LEFT; 847 } else if ((angle >= 135) && (angle <= 225)) { 848 return RIGHT; 849 } else if ((angle > 45) && (angle < 135)) { 850 return DOWN; 851 } else { 852 return UP; 853 } 854 } 855 856 function getTimeStamp() { 857 var now = new Date(); 858 return now.getTime(); 859 } 860 861 function getbounds(el) { 862 el = $(el); 863 var offset = el.offset(); 864 var bounds = { 865 left: offset.left, 866 right: offset.left + el.outerWidth(), 867 top: offset.top, 868 bottom: offset.top + el.outerHeight() 869 } 870 return bounds; 871 } 872 873 function isInBounds(point, bounds) { 874 return (point.x > bounds.left && point.x < bounds.right && point.y > bounds.top && point.y < bounds.bottom); 875 }; 876 } 877}));
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.