vendor: 24,124 bytes, lines 1-493
1/* 2TouchSwipe - jQuery Plugin, version 1.6.18 3 4Matt Bryson http://www.github.com/mattbryson 5https://github.com/mattbryson/TouchSwipe-Jquery-Plugin 6http://labs.rampinteractive.co.uk/touchSwipe/ 7http://plugins.jquery.com/project/touchSwipe 8 9Copyright (c) 2010-2015 Matt Bryson 10Dual licensed under the MIT or GPL Version 2 licenses. 11*/ 12 13! function(factory) { 14 "function" == typeof define && define.amd && define.amd.jQuery ? define(["jquery"], factory) : factory("undefined" != typeof module && module.exports ? require("jquery") : jQuery) 15}(function(jQuery) { 16 "use strict"; 17 18 function init(options) { 19 return !options || void 0 !== options.allowPageScroll || void 0 === options.swipe && void 0 === options.swipeStatus || (options.allowPageScroll = NONE), void 0 !== options.click && void 0 === options.tap && (options.tap = options.click), options || (options = {}), options = jQuery.extend({}, jQuery.fn.swipe.defaults, options), this.each(function() { 20 var that = jQuery(this), 21 plugin = that.data(PLUGIN_NS); 22 plugin || (plugin = new TouchSwipe(this, options), that.data(PLUGIN_NS, plugin)) 23 }) 24 } 25 26 function TouchSwipe(element, options) { 27 function touchStart(jqEvent) { 28 if (!(getTouchInProgress() || jQuery(jqEvent.target).closest(options.excludedElements, el).length > 0)) { 29 var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent; 30 if (!event.pointerType || "mouse" != event.pointerType || 0 != options.fallbackToMouseEvents) { 31 var ret, touches = event.touches, 32 evt = touches ? touches[0] : event; 33 return phase = PHASE_START, touches ? fingerCount = touches.length : options.preventDefaultEvents !== !1 && jqEvent.preventDefault(), distance = 0, direction = null, currentDirection = null, pinchDirection = null, duration = 0, startTouchesDistance = 0, endTouchesDistance = 0, pinchZoom = 1, pinchDistance = 0, maximumsMap = createMaximumsData(), cancelMultiFingerRelease(), createFingerData(0, evt), !touches || fingerCount === options.fingers || options.fingers === ALL_FINGERS || hasPinches() ? (startTime = getTimeStamp(), 2 == fingerCount && (createFingerData(1, touches[1]), startTouchesDistance = endTouchesDistance = calculateTouchesDistance(fingerData[0].start, fingerData[1].start)), (options.swipeStatus || options.pinchStatus) && (ret = triggerHandler(event, phase))) : ret = !1, ret === !1 ? (phase = PHASE_CANCEL, triggerHandler(event, phase), ret) : (options.hold && (holdTimeout = setTimeout(jQuery.proxy(function() { 34 el.trigger("hold", [event.target]), options.hold && (ret = options.hold.call(el, event, event.target)) 35 }, this), options.longTapThreshold)), setTouchInProgress(!0), null) 36 } 37 } 38 } 39 40 function touchMove(jqEvent) { 41 var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent; 42 if (phase !== PHASE_END && phase !== PHASE_CANCEL && !inMultiFingerRelease()) { 43 var ret, touches = event.touches, 44 evt = touches ? touches[0] : event, 45 currentFinger = updateFingerData(evt); 46 if (endTime = getTimeStamp(), touches && (fingerCount = touches.length), options.hold && clearTimeout(holdTimeout), phase = PHASE_MOVE, 2 == fingerCount && (0 == startTouchesDistance ? (createFingerData(1, touches[1]), startTouchesDistance = endTouchesDistance = calculateTouchesDistance(fingerData[0].start, fingerData[1].start)) : (updateFingerData(touches[1]), endTouchesDistance = calculateTouchesDistance(fingerData[0].end, fingerData[1].end), pinchDirection = calculatePinchDirection(fingerData[0].end, fingerData[1].end)), pinchZoom = calculatePinchZoom(startTouchesDistance, endTouchesDistance), pinchDistance = Math.abs(startTouchesDistance - endTouchesDistance)), fingerCount === options.fingers || options.fingers === ALL_FINGERS || !touches || hasPinches()) { 47 if (direction = calculateDirection(currentFinger.start, currentFinger.end), currentDirection = calculateDirection(currentFinger.last, currentFinger.end), validateDefaultEvent(jqEvent, currentDirection), distance = calculateDistance(currentFinger.start, currentFinger.end), duration = calculateDuration(), setMaxDistance(direction, distance), ret = triggerHandler(event, phase), !options.triggerOnTouchEnd || options.triggerOnTouchLeave) { 48 var inBounds = !0; 49 if (options.triggerOnTouchLeave) { 50 var bounds = getbounds(this); 51 inBounds = isInBounds(currentFinger.end, bounds) 52 }!options.triggerOnTouchEnd && inBounds ? phase = getNextPhase(PHASE_MOVE) : options.triggerOnTouchLeave && !inBounds && (phase = getNextPhase(PHASE_END)), phase != PHASE_CANCEL && phase != PHASE_END || triggerHandler(event, phase) 53 } 54 } else phase = PHASE_CANCEL, triggerHandler(event, phase); 55 ret === !1 && (phase = PHASE_CANCEL, triggerHandler(event, phase)) 56 } 57 } 58 59 function touchEnd(jqEvent) { 60 var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent, 61 touches = event.touches; 62 if (touches) { 63 if (touches.length && !inMultiFingerRelease()) return startMultiFingerRelease(event), !0; 64 if (touches.length && inMultiFingerRelease()) return !0 65 } 66 return inMultiFingerRelease() && (fingerCount = fingerCountAtRelease), endTime = getTimeStamp(), duration = calculateDuration(), didSwipeBackToCancel() || !validateSwipeDistance() ? (phase = PHASE_CANCEL, triggerHandler(event, phase)) : options.triggerOnTouchEnd || options.triggerOnTouchEnd === !1 && phase === PHASE_MOVE ? (options.preventDefaultEvents !== !1 && jqEvent.preventDefault(), phase = PHASE_END, triggerHandler(event, phase)) : !options.triggerOnTouchEnd && hasTap() ? (phase = PHASE_END, triggerHandlerForGesture(event, phase, TAP)) : phase === PHASE_MOVE && (phase = PHASE_CANCEL, triggerHandler(event, phase)), setTouchInProgress(!1), null 67 } 68 69 function touchCancel() { 70 fingerCount = 0, endTime = 0, startTime = 0, startTouchesDistance = 0, endTouchesDistance = 0, pinchZoom = 1, cancelMultiFingerRelease(), setTouchInProgress(!1) 71 } 72 73 function touchLeave(jqEvent) { 74 var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent; 75 options.triggerOnTouchLeave && (phase = getNextPhase(PHASE_END), triggerHandler(event, phase)) 76 } 77 78 function removeListeners() { 79 el.unbind(START_EV, touchStart), el.unbind(CANCEL_EV, touchCancel), el.unbind(MOVE_EV, touchMove), el.unbind(END_EV, touchEnd), LEAVE_EV && el.unbind(LEAVE_EV, touchLeave), setTouchInProgress(!1) 80 } 81 82 function getNextPhase(currentPhase) { 83 var nextPhase = currentPhase, 84 validTime = validateSwipeTime(), 85 validDistance = validateSwipeDistance(), 86 didCancel = didSwipeBackToCancel(); 87 return !validTime || didCancel ? nextPhase = PHASE_CANCEL : !validDistance || currentPhase != PHASE_MOVE || options.triggerOnTouchEnd && !options.triggerOnTouchLeave ? !validDistance && currentPhase == PHASE_END && options.triggerOnTouchLeave && (nextPhase = PHASE_CANCEL) : nextPhase = PHASE_END, nextPhase 88 } 89 90 function triggerHandler(event, phase) { 91 var ret, touches = event.touches; 92 return (didSwipe() || hasSwipes()) && (ret = triggerHandlerForGesture(event, phase, SWIPE)), (didPinch() || hasPinches()) && ret !== !1 && (ret = triggerHandlerForGesture(event, phase, PINCH)), didDoubleTap() && ret !== !1 ? ret = triggerHandlerForGesture(event, phase, DOUBLE_TAP) : didLongTap() && ret !== !1 ? ret = triggerHandlerForGesture(event, phase, LONG_TAP) : didTap() && ret !== !1 && (ret = triggerHandlerForGesture(event, phase, TAP)), phase === PHASE_CANCEL && touchCancel(event), phase === PHASE_END && (touches ? touches.length || touchCancel(event) : touchCancel(event)), ret 93 } 94 95 function triggerHandlerForGesture(event, phase, gesture) { 96 var ret; 97 if (gesture == SWIPE) { 98 if (el.trigger("swipeStatus", [phase, direction || null, distance || 0, duration || 0, fingerCount, fingerData, currentDirection]), options.swipeStatus && (ret = options.swipeStatus.call(el, event, phase, direction || null, distance || 0, duration || 0, fingerCount, fingerData, currentDirection), ret === !1)) return !1; 99 if (phase == PHASE_END && validateSwipe()) { 100 if (clearTimeout(singleTapTimeout), clearTimeout(holdTimeout), el.trigger("swipe", [direction, distance, duration, fingerCount, fingerData, currentDirection]), options.swipe && (ret = options.swipe.call(el, event, direction, distance, duration, fingerCount, fingerData, currentDirection), ret === !1)) return !1; 101 switch (direction) { 102 case LEFT: 103 el.trigger("swipeLeft", [direction, distance, duration, fingerCount, fingerData, currentDirection]), options.swipeLeft && (ret = options.swipeLeft.call(el, event, direction, distance, duration, fingerCount, fingerData, currentDirection)); 104 break; 105 case RIGHT: 106 el.trigger("swipeRight", [direction, distance, duration, fingerCount, fingerData, currentDirection]), options.swipeRight && (ret = options.swipeRight.call(el, event, direction, distance, duration, fingerCount, fingerData, currentDirection)); 107 break; 108 case UP: 109 el.trigger("swipeUp", [direction, distance, duration, fingerCount, fingerData, currentDirection]), options.swipeUp && (ret = options.swipeUp.call(el, event, direction, distance, duration, fingerCount, fingerData, currentDirection)); 110 break; 111 case DOWN: 112 el.trigger("swipeDown", [direction, distance, duration, fingerCount, fingerData, currentDirection]), options.swipeDown && (ret = options.swipeDown.call(el, event, direction, distance, duration, fingerCount, fingerData, currentDirection)) 113 } 114 } 115 } 116 if (gesture == PINCH) { 117 if (el.trigger("pinchStatus", [phase, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]), options.pinchStatus && (ret = options.pinchStatus.call(el, event, phase, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData), ret === !1)) return !1; 118 if (phase == PHASE_END && validatePinch()) switch (pinchDirection) { 119 case IN: 120 el.trigger("pinchIn", [pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]), options.pinchIn && (ret = options.pinchIn.call(el, event, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData)); 121 break; 122 case OUT: 123 el.trigger("pinchOut", [pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]), options.pinchOut && (ret = options.pinchOut.call(el, event, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData)) 124 } 125 } 126 return gesture == TAP ? phase !== PHASE_CANCEL && phase !== PHASE_END || (clearTimeout(singleTapTimeout), clearTimeout(holdTimeout), hasDoubleTap() && !inDoubleTap() ? (doubleTapStartTime = getTimeStamp(), singleTapTimeout = setTimeout(jQuery.proxy(function() { 127 doubleTapStartTime = null, el.trigger("tap", [event.target]), options.tap && (ret = options.tap.call(el, event, event.target)) 128 }, this), options.doubleTapThreshold)) : (doubleTapStartTime = null, el.trigger("tap", [event.target]), options.tap && (ret = options.tap.call(el, event, event.target)))) : gesture == DOUBLE_TAP ? phase !== PHASE_CANCEL && phase !== PHASE_END || (clearTimeout(singleTapTimeout), clearTimeout(holdTimeout), doubleTapStartTime = null, el.trigger("doubletap", [event.target]), options.doubleTap && (ret = options.doubleTap.call(el, event, event.target))) : gesture == LONG_TAP && (phase !== PHASE_CANCEL && phase !== PHASE_END || (clearTimeout(singleTapTimeout), doubleTapStartTime = null, el.trigger("longtap", [event.target]), options.longTap && (ret = options.longTap.call(el, event, event.target)))), ret 129 } 130 131 function validateSwipeDistance() { 132 var valid = !0; 133 return null !== options.threshold && (valid = distance >= options.threshold), valid 134 } 135 136 function didSwipeBackToCancel() { 137 var cancelled = !1; 138 return null !== options.cancelThreshold && null !== direction && (cancelled = getMaxDistance(direction) - distance >= options.cancelThreshold), cancelled 139 } 140 141 function validatePinchDistance() { 142 return null === options.pinchThreshold || pinchDistance >= options.pinchThreshold 143 } 144 145 function validateSwipeTime() { 146 var result; 147 return result = !options.maxTimeThreshold || !(duration >= options.maxTimeThreshold) 148 } 149 150 function validateDefaultEvent(jqEvent, direction) { 151 if (options.preventDefaultEvents !== !1) 152 if (options.allowPageScroll === NONE) jqEvent.preventDefault(); 153 else { 154 var auto = options.allowPageScroll === AUTO; 155 switch (direction) { 156 case LEFT: 157 (options.swipeLeft && auto || !auto && options.allowPageScroll != HORIZONTAL) && jqEvent.preventDefault(); 158 break; 159 case RIGHT: 160 (options.swipeRight && auto || !auto && options.allowPageScroll != HORIZONTAL) && jqEvent.preventDefault(); 161 break; 162 case UP: 163 (options.swipeUp && auto || !auto && options.allowPageScroll != VERTICAL) && jqEvent.preventDefault(); 164 break; 165 case DOWN: 166 (options.swipeDown && auto || !auto && options.allowPageScroll != VERTICAL) && jqEvent.preventDefault(); 167 break; 168 case NONE: 169 } 170 } 171 } 172 173 function validatePinch() { 174 var hasCorrectFingerCount = validateFingers(), 175 hasEndPoint = validateEndPoint(), 176 hasCorrectDistance = validatePinchDistance(); 177 return hasCorrectFingerCount && hasEndPoint && hasCorrectDistance 178 } 179 180 function hasPinches() { 181 return !!(options.pinchStatus || options.pinchIn || options.pinchOut) 182 } 183 184 function didPinch() { 185 return !(!validatePinch() || !hasPinches()) 186 } 187 188 function validateSwipe() { 189 var hasValidTime = validateSwipeTime(), 190 hasValidDistance = validateSwipeDistance(), 191 hasCorrectFingerCount = validateFingers(), 192 hasEndPoint = validateEndPoint(), 193 didCancel = didSwipeBackToCancel(), 194 valid = !didCancel && hasEndPoint && hasCorrectFingerCount && hasValidDistance && hasValidTime; 195 return valid 196 } 197 198 function hasSwipes() { 199 return !!(options.swipe || options.swipeStatus || options.swipeLeft || options.swipeRight || options.swipeUp || options.swipeDown) 200 } 201 202 function didSwipe() { 203 return !(!validateSwipe() || !hasSwipes()) 204 } 205 206 function validateFingers() { 207 return fingerCount === options.fingers || options.fingers === ALL_FINGERS || !SUPPORTS_TOUCH 208 } 209 210 function validateEndPoint() { 211 return 0 !== fingerData[0].end.x 212 } 213 214 function hasTap() { 215 return !!options.tap 216 } 217 218 function hasDoubleTap() { 219 return !!options.doubleTap 220 } 221 222 function hasLongTap() { 223 return !!options.longTap 224 } 225 226 function validateDoubleTap() { 227 if (null == doubleTapStartTime) return !1; 228 var now = getTimeStamp(); 229 return hasDoubleTap() && now - doubleTapStartTime <= options.doubleTapThreshold 230 } 231 232 function inDoubleTap() { 233 return validateDoubleTap() 234 } 235 236 function validateTap() { 237 return (1 === fingerCount || !SUPPORTS_TOUCH) && (isNaN(distance) || distance < options.threshold) 238 } 239 240 function validateLongTap() { 241 return duration > options.longTapThreshold && distance < DOUBLE_TAP_THRESHOLD 242 } 243 244 function didTap() { 245 return !(!validateTap() || !hasTap()) 246 } 247 248 function didDoubleTap() { 249 return !(!validateDoubleTap() || !hasDoubleTap()) 250 } 251 252 function didLongTap() { 253 return !(!validateLongTap() || !hasLongTap()) 254 } 255 256 function startMultiFingerRelease(event) { 257 previousTouchEndTime = getTimeStamp(), fingerCountAtRelease = event.touches.length + 1 258 } 259 260 function cancelMultiFingerRelease() { 261 previousTouchEndTime = 0, fingerCountAtRelease = 0 262 } 263 264 function inMultiFingerRelease() { 265 var withinThreshold = !1; 266 if (previousTouchEndTime) { 267 var diff = getTimeStamp() - previousTouchEndTime; 268 diff <= options.fingerReleaseThreshold && (withinThreshold = !0) 269 } 270 return withinThreshold 271 } 272 273 function getTouchInProgress() { 274 return !(el.data(PLUGIN_NS + "_intouch") !== !0) 275 } 276 277 function setTouchInProgress(val) { 278 el && (val === !0 ? (el.bind(MOVE_EV, touchMove), el.bind(END_EV, touchEnd), LEAVE_EV && el.bind(LEAVE_EV, touchLeave)) : (el.unbind(MOVE_EV, touchMove, !1), el.unbind(END_EV, touchEnd, !1), LEAVE_EV && el.unbind(LEAVE_EV, touchLeave, !1)), el.data(PLUGIN_NS + "_intouch", val === !0)) 279 } 280 281 function createFingerData(id, evt) { 282 var f = { 283 start: { 284 x: 0, 285 y: 0 286 }, 287 last: { 288 x: 0, 289 y: 0 290 }, 291 end: { 292 x: 0, 293 y: 0 294 } 295 }; 296 return f.start.x = f.last.x = f.end.x = evt.pageX || evt.clientX, f.start.y = f.last.y = f.end.y = evt.pageY || evt.clientY, fingerData[id] = f, f 297 } 298 299 function updateFingerData(evt) { 300 var id = void 0 !== evt.identifier ? evt.identifier : 0, 301 f = getFingerData(id); 302 return null === f && (f = createFingerData(id, evt)), f.last.x = f.end.x, f.last.y = f.end.y, f.end.x = evt.pageX || evt.clientX, f.end.y = evt.pageY || evt.clientY, f 303 } 304 305 function getFingerData(id) { 306 return fingerData[id] || null 307 } 308 309 function setMaxDistance(direction, distance) { 310 direction != NONE && (distance = Math.max(distance, getMaxDistance(direction)), maximumsMap[direction].distance = distance) 311 } 312 313 function getMaxDistance(direction) { 314 if (maximumsMap[direction]) return maximumsMap[direction].distance 315 } 316 317 function createMaximumsData() { 318 var maxData = {}; 319 return maxData[LEFT] = createMaximumVO(LEFT), maxData[RIGHT] = createMaximumVO(RIGHT), maxData[UP] = createMaximumVO(UP), maxData[DOWN] = createMaximumVO(DOWN), maxData 320 } 321 322 function createMaximumVO(dir) { 323 return { 324 direction: dir, 325 distance: 0 326 } 327 } 328 329 function calculateDuration() { 330 return endTime - startTime 331 } 332 333 function calculateTouchesDistance(startPoint, endPoint) { 334 var diffX = Math.abs(startPoint.x - endPoint.x), 335 diffY = Math.abs(startPoint.y - endPoint.y); 336 return Math.round(Math.sqrt(diffX * diffX + diffY * diffY)) 337 } 338 339 function calculatePinchZoom(startDistance, endDistance) { 340 var percent = endDistance / startDistance * 1; 341 return percent.toFixed(2) 342 } 343 344 function calculatePinchDirection() { 345 return pinchZoom < 1 ? OUT : IN 346 } 347 348 function calculateDistance(startPoint, endPoint) { 349 return Math.round(Math.sqrt(Math.pow(endPoint.x - startPoint.x, 2) + Math.pow(endPoint.y - startPoint.y, 2))) 350 } 351 352 function calculateAngle(startPoint, endPoint) { 353 var x = startPoint.x - endPoint.x, 354 y = endPoint.y - startPoint.y, 355 r = Math.atan2(y, x), 356 angle = Math.round(180 * r / Math.PI); 357 return angle < 0 && (angle = 360 - Math.abs(angle)), angle 358 } 359 360 function calculateDirection(startPoint, endPoint) { 361 if (comparePoints(startPoint, endPoint)) return NONE; 362 var angle = calculateAngle(startPoint, endPoint); 363 return angle <= 45 && angle >= 0 ? LEFT : angle <= 360 && angle >= 315 ? LEFT : angle >= 135 && angle <= 225 ? RIGHT : angle > 45 && angle < 135 ? DOWN : UP 364 } 365 366 function getTimeStamp() { 367 var now = new Date; 368 return now.getTime() 369 } 370 371 function getbounds(el) { 372 el = jQuery(el); 373 var offset = el.offset(), 374 bounds = { 375 left: offset.left, 376 right: offset.left + el.outerWidth(), 377 top: offset.top, 378 bottom: offset.top + el.outerHeight() 379 }; 380 return bounds 381 } 382 383 function isInBounds(point, bounds) { 384 return point.x > bounds.left && point.x < bounds.right && point.y > bounds.top && point.y < bounds.bottom 385 } 386 387 function comparePoints(pointA, pointB) { 388 return pointA.x == pointB.x && pointA.y == pointB.y 389 } 390 var options = jQuery.extend({}, options), 391 useTouchEvents = SUPPORTS_TOUCH || SUPPORTS_POINTER || !options.fallbackToMouseEvents, 392 START_EV = useTouchEvents ? SUPPORTS_POINTER ? SUPPORTS_POINTER_IE10 ? "MSPointerDown" : "pointerdown" : "touchstart" : "mousedown", 393 MOVE_EV = useTouchEvents ? SUPPORTS_POINTER ? SUPPORTS_POINTER_IE10 ? "MSPointerMove" : "pointermove" : "touchmove" : "mousemove", 394 END_EV = useTouchEvents ? SUPPORTS_POINTER ? SUPPORTS_POINTER_IE10 ? "MSPointerUp" : "pointerup" : "touchend" : "mouseup", 395 LEAVE_EV = useTouchEvents ? SUPPORTS_POINTER ? "mouseleave" : null : "mouseleave", 396 CANCEL_EV = SUPPORTS_POINTER ? SUPPORTS_POINTER_IE10 ? "MSPointerCancel" : "pointercancel" : "touchcancel", 397 distance = 0, 398 direction = null, 399 currentDirection = null, 400 duration = 0, 401 startTouchesDistance = 0, 402 endTouchesDistance = 0, 403 pinchZoom = 1, 404 pinchDistance = 0, 405 pinchDirection = 0, 406 maximumsMap = null, 407 el = jQuery(element), 408 phase = "start", 409 fingerCount = 0, 410 fingerData = {}, 411 startTime = 0, 412 endTime = 0, 413 previousTouchEndTime = 0, 414 fingerCountAtRelease = 0, 415 doubleTapStartTime = 0, 416 singleTapTimeout = null, 417 holdTimeout = null; 418 try { 419 el.bind(START_EV, touchStart), el.bind(CANCEL_EV, touchCancel) 420 } catch (e) { 421 jQuery.error("events not supported " + START_EV + "," + CANCEL_EV + " on jQuery.swipe") 422 } 423 this.enable = function() { 424 return this.disable(), el.bind(START_EV, touchStart), el.bind(CANCEL_EV, touchCancel), el 425 }, this.disable = function() { 426 return removeListeners(), el 427 }, this.destroy = function() { 428 removeListeners(), el.data(PLUGIN_NS, null), el = null 429 }, this.option = function(property, value) { 430 if ("object" == typeof property) options = jQuery.extend(options, property); 431 else if (void 0 !== options[property]) { 432 if (void 0 === value) return options[property]; 433 options[property] = value 434 } else { 435 if (!property) return options; 436 jQuery.error("Option " + property + " does not exist on jQuery.swipe.options") 437 } 438 return null 439 } 440 } 441 var VERSION = "1.6.18", 442 LEFT = "left", 443 RIGHT = "right", 444 UP = "up", 445 DOWN = "down", 446 IN = "in", 447 OUT = "out", 448 NONE = "none", 449 AUTO = "auto", 450 SWIPE = "swipe", 451 PINCH = "pinch", 452 TAP = "tap", 453 DOUBLE_TAP = "doubletap", 454 LONG_TAP = "longtap", 455 HORIZONTAL = "horizontal", 456 VERTICAL = "vertical", 457 ALL_FINGERS = "all", 458 DOUBLE_TAP_THRESHOLD = 10, 459 PHASE_START = "start", 460 PHASE_MOVE = "move", 461 PHASE_END = "end", 462 PHASE_CANCEL = "cancel", 463 SUPPORTS_TOUCH = "ontouchstart" in window, 464 SUPPORTS_POINTER_IE10 = window.navigator.msPointerEnabled && !window.PointerEvent && !SUPPORTS_TOUCH, 465 SUPPORTS_POINTER = (window.PointerEvent || window.navigator.msPointerEnabled) && !SUPPORTS_TOUCH, 466 PLUGIN_NS = "TouchSwipe", 467 defaults = { 468 fingers: 1, 469 threshold: 75, 470 cancelThreshold: null, 471 pinchThreshold: 20, 472 maxTimeThreshold: null, 473 fingerReleaseThreshold: 250, 474 longTapThreshold: 500, 475 doubleTapThreshold: 200, 476 swipe: null, 477 swipeLeft: null, 478 swipeRight: null, 479 swipeUp: null, 480 swipeDown: null, 481 swipeStatus: null, 482 pinchIn: null, 483 pinchOut: null, 484 pinchStatus: null, 485 click: null, 486 tap: null, 487 doubleTap: null, 488 longTap: null, 489 hold: null, 490 triggerOnTouchEnd: !0, 491 triggerOnTouchLeave: !1, 492 allowPageScroll: "auto", 493 fallbackToMouseEvents: !0,
494 excludedElements: ".noSwipe", 495 preventDefaultEvents: !0 496 }; 497 jQuery.fn.swipe = function(method) { 498 var that = jQuery(this), 499 plugin = that.data(PLUGIN_NS); 500 if (plugin && "string" == typeof method) { 501 if (plugin[method]) return plugin[method].apply(plugin, Array.prototype.slice.call(arguments, 1)); 502 jQuery.error("Method " + method + " does not exist on jQuery.swipe") 503 } else if (plugin && "object" == typeof method) plugin.option.apply(plugin, arguments); 504 else if (!(plugin || "object" != typeof method && method)) return init.apply(this, arguments); 505 return that 506 }, jQuery.fn.swipe.version = VERSION, jQuery.fn.swipe.defaults = defaults, jQuery.fn.swipe.phases = { 507 PHASE_START: PHASE_START, 508 PHASE_MOVE: PHASE_MOVE, 509 PHASE_END: PHASE_END, 510 PHASE_CANCEL: PHASE_CANCEL 511 }, jQuery.fn.swipe.directions = { 512 LEFT: LEFT, 513 RIGHT: RIGHT, 514 UP: UP, 515 DOWN: DOWN, 516 IN: IN, 517 OUT: OUT 518 }, jQuery.fn.swipe.pageScroll = { 519 NONE: NONE, 520 HORIZONTAL: HORIZONTAL, 521 VERTICAL: VERTICAL, 522 AUTO: AUTO 523 }, jQuery.fn.swipe.fingers = { 524 ONE: 1, 525 TWO: 2, 526 THREE: 3, 527 FOUR: 4, 528 FIVE: 5, 529 ALL: ALL_FINGERS 530 } 531}); 532 533 534/* 535TopBox is derived from Nivo Lightbox v1.3.1, created by Dev7studios: 536http://dev7studios.com/nivo-lightbox 537 538TopBox is updated for jQuery 3 and has additional features / content support. 539Maintained by William Woodgate 540 541TopBox homepage: 542https://willwoodgate.com/projects/topbox/ 543 544Free to use and abuse under the MIT license. 545http://www.opensource.org/licenses/mit-license.php 546*/ 547 548jQuery(document).ready(function() { 549 550 var pluginName = 'topbox', 551 defaults = { 552 effect: 'fade', 553 backgroundBlur: false, 554 skin: 'darkroom', 555 keyboardNav: true, 556 clickImgToClose: false, 557 clickOverlayToClose: true, 558 closeToolTip: 'Close', 559 previousToolTip: 'Previous', 560 nextToolTip: 'Next', 561 titleSource: 'title', 562 onInit: function() {}, 563 beforeShowLightbox: function() {}, 564 afterShowLightbox: function(lightbox) {}, 565 beforeHideLightbox: function() {}, 566 afterHideLightbox: function() {}, 567 beforePrev: function(element) {}, 568 onPrev: function(element) {}, 569 beforeNext: function(element) {}, 570 onNext: function(element) {}, 571 pdfMessage: 'View the PDF in a new window:', 572 pdfButton: 'Tap Here', 573 errorMessage: 'The requested content cannot be loaded. Please try again later.' 574 }; 575 576 function TopBox(element, options) { 577 this.el = element; 578 this.ele = jQuery(this.el); 579 this.options = jQuery.extend({}, defaults, options); 580 this._defaults = defaults; 581 this._name = pluginName; 582 this.init(); 583 } 584 585 TopBox.prototype = { 586 587 init: function() { 588 var that = this; 589 590 // If web browser is NOT a touch device (need this so we don't use CSS transitions in mobile) 591 if (!(/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent))) { 592 jQuery('body').addClass('topbox_notouch'); 593 } 594 595 // Background blur 596 if (this.options.backgroundBlur) { 597 jQuery('body').wrapInner('<div class="topbox_blur_wrapper" />'); 598 } 599 600 // Setup the click 601 this.ele.on('click', function(e) { 602 that.showLightbox(e); 603 }); 604 605 // keyboard navigation 606 if (this.options.keyboardNav) { 607 jQuery('body').off('keyup').on('keyup', function(e) { 608 var code = (e.keyCode ? e.keyCode : e.which); 609 // Escape 610 if (code == 27) that.destructLightbox(); 611 // Left 612 if (code == 37) jQuery('.topbox_prev').trigger('click'); 613 // Right 614 if (code == 39) jQuery('.topbox_next').trigger('click'); 615 }); 616 } 617 618 this.options.onInit.call(this); 619 620 }, 621 622 showLightbox: function(e) { 623 var that = this, 624 currentLink = this.ele; 625 626 // Check content 627 var check = this.checkContent(currentLink); 628 if (!check) return; 629 630 e.preventDefault(); 631 this.options.beforeShowLightbox.call(this); 632 var lightbox = this.constructLightbox(); 633 if (!lightbox) return; 634 var content = lightbox.find('.topbox_content'); 635 if (!content) return; 636 637 jQuery('body').addClass('topbox_open topbox_body_effect_' + this.options.effect); 638 639 this.processContent(content, currentLink); 640 641 // Nav 642 if (this.ele.attr('data-lightbox-gallery')) { 643 var galleryItems = jQuery('[data-lightbox-gallery="' + this.ele.attr('data-lightbox-gallery') + '"]'); 644 645 jQuery('.topbox_nav').show(); 646 647 // Prev 648 jQuery('.topbox_prev').off('click').on('click', function(e) { 649 e.preventDefault(); 650 // Empty content 651 jQuery('.topbox_content').empty(); 652 var index = galleryItems.index(currentLink); 653 currentLink = galleryItems.eq(index - 1); 654 if (!jQuery(currentLink).length) currentLink = galleryItems.last(
654); 655 jQuery.when(that.options.beforePrev.call(this, [currentLink])).done(function() { 656 that.processContent(content, currentLink); 657 that.options.onPrev.call(this, [currentLink]); 658 }); 659 }); 660 661 // Next 662 jQuery('.topbox_next').off('click').on('click', function(e) { 663 e.preventDefault(); 664 // Empty content 665 jQuery('.topbox_content').empty(); 666 var index = galleryItems.index(currentLink); 667 currentLink = galleryItems.eq(index + 1); 668 if (!jQuery(currentLink).length) currentLink = galleryItems.first(); 669 jQuery.when(that.options.beforeNext.call(this, [currentLink])).done(function() { 670 that.processContent(content, currentLink); 671 that.options.onNext.call(this, [currentLink]); 672 }); 673 }); 674 } 675 676 setTimeout(function() { 677 lightbox.addClass('topbox_open'); 678 that.options.afterShowLightbox.call(this, [lightbox]); 679 }, 1); // For CSS transitions 680 }, 681 682 checkContent: function(link) { 683 var that = this, 684 href = link.attr('href'), 685 video = href.match(/(youtube|youtube-nocookie|youtu|vimeo)\.(com|be|ly|tv)\/((watch\?v=([\w-]+))|(embed\/([\w-]+))|([\w-]+))/); 686 videoOther = href.match(/(dai|brighteon|ted)\.(com|be|ly|tv|net)\/((talks\/([\w-]+))|([\w-]+))/); 687 688 if (href.match(/\.(jpeg|jpg|gif|png|tiff|svg|webp)$/i) !== null) { 689 return true; 690 } 691 692 // HTML5 Audio 693 else if (href.match(/\.(ogg|mp3)$/i) !== null) { 694 return true; 695 } 696 697 // HTML5 Video 698 else if (href.match(/\.(ogv|mov|webm|mp4)$/i) !== null) { 699 return true; 700 } 701 702 // PDF 703 else if (href.match(/\.(pdf)$/i) !== null) { 704 return true; 705 } 706 707 // Video (Youtube/Vimeo) 708 else if (video) { 709 return true; 710 } 711 712 // Video (Dailymotion, Brighteon, TED) 713 else if (videoOther) { 714 return true; 715 } 716 717 // AJAX 718 else if (link.attr('data-lightbox-type') == 'ajax') { 719 return true; 720 } 721 722 // Inline HTML 723 else if (href.substring(0, 1) == '#' && link.attr('data-lightbox-type') == 'inline') { 724 return true; 725 } 726 727 // Video iFrame 728 else if (link.attr('data-lightbox-type') == 'video-iframe') { 729 return true; 730 } 731 732 // iFrame (default) 733 else if (link.attr('data-lightbox-type') == 'iframe') { 734 return true; 735 } 736 737 return false; 738 }, 739 740 processContent: function(content, link) { 741 var that = this, 742 href = link.attr('href'), 743 video = href.match(/(youtube|youtube-nocookie|youtu|vimeo)\.(com|be|ly|tv)\/((watch\?v=([\w-]+))|(embed\/([\w-]+))|([\w-]+))/); 744 videoOther = href.match(/(dai|brighteon|ted)\.(com|be|net|ly|tv)\/((talks\/([\w-]+))|([\w-]+))/); 745 746 // Image 747 if (href.match(/\.(jpeg|jpg|gif|png|tiff|svg|webp)$/i) !== null) { 748 var imgtag = jQuery('<img>', { 749 src: href, 750 'class': 'topbox_image' 751 }); 752 imgtag.one('load', function() { 753 content.prepend(imgtag); 754 }).each(function() { 755 if (this.complete) jQuery(this).on("load"); 756 }); 757 758 imgtag.on("error", function() { 759 var wrap = jQuery('<div class="topbox_error"><p>' + that.options.errorMessage + '</p></div>'); 760 content.html(wrap); 761 }); 762 } 763 764 // Embedded video (e.g. Youtube, Vimeo) 765 else if (video) { 766 var src = '', 767 classTerm = 'topbox_embedded_web_video'; 768 769 if (video[1] == 'youtube') { 770 src = 'https://www.youtube.com/embed/' + video[3] + '?autoplay=1&rel=0&playsinline=1'; 771 classTerm = 'topbox_youtube'; 772 } 773 774 if (video[1] == 'youtu') { 775 src = 'https://www.youtube.com/embed/' + video[3] + '?autoplay=1&rel=0&playsinline=1'; 776 classTerm = 'topbox_youtube'; 777 } 778 779 if (video[1] == 'vimeo') { 780 src = 'https://player.vimeo.com/video/' + video[3] + '?autoplay=1&rel=0&playsinline=1'; 781 classTerm = 'topbox_vimeo'; 782 } 783 784 if (src) { 785 var iframeVideo = jQuery('<iframe>', { 786 src: src, 787 'class': classTerm, 788 frameborder: 0, 789 vspace: 0, 790 hspace: 0, 791 playsinline: true, 792 scrolling: 'auto', 793 allowfullscreen: 'true', 794 allow: 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture' 795 });
796 content.prepend(iframeVideo); 797 jQuery('iframe').wrap('<div class="topbox_embedded_web_video" id="player" />'); 798 } 799 } 800 801 // Embedded video (e.g. Brighteon, TED, DailyMotion) 802 else if (videoOther) { 803 var src = '', 804 classTerm = 'topbox_embedded_web_video'; 805 806 if (videoOther[1] == 'dai') { 807 src = 'https://www.dailymotion.com/embed/video/' + videoOther[3] + '?autoPlay=1'; 808 classTerm = 'topbox_dailymotion'; 809 } 810 811 if (videoOther[1] == 'ted') { 812 src = 'https://embed.ted.com/' + videoOther[3] + '?autoplay=1';; 813 classTerm = 'topbox_ted'; 814 } 815 816 if (videoOther[1] == 'brighteon') { 817 src = 'https://www.brighteon.com/embed/' + videoOther[3] + '?autoplay=1'; 818 classTerm = 'topbox_brighteon'; 819 } 820 821 if (src) { 822 var iframeVideo = jQuery('<iframe>', { 823 src: src, 824 'class': classTerm, 825 frameborder: 0, 826 vspace: 0, 827 hspace: 0, 828 scrolling: 'auto', 829 allowfullscreen: 'true', 830 allowtransparency: 'true', 831 allow: 'autoplay; encrypted-media' 832 }); 833 content.prepend(iframeVideo); 834 jQuery('iframe').wrap('<div class="topbox_embedded_web_video" />'); 835 836 } 837 } 838 839 // AJAX 840 else if (link.attr('data-lightbox-type') == 'ajax') { 841 jQuery.ajax({ 842 url: href, 843 cache: false, 844 success: function(data) { 845 var wrap = jQuery('<div class="topbox_ajax" />'); 846 wrap.append(data); 847 }, 848 error: function() { 849 var wrap = jQuery('<div class="topbox_error"><p>' + that.options.errorMessage + '</p></div>'); 850 content.html(wrap); 851 } 852 }); 853 } 854 855 // Inline HTML 856 else if (href.substring(0, 1) == '#' && link.attr('data-lightbox-type') == 'inline') { 857 if (jQuery(href).length) { 858 var wrap = jQuery('<div class="topbox_inline" />'); 859 wrap.append(jQuery(href).clone().show()); 860 content.html(wrap); 861 } else { 862 var wrapError = jQuery('<div class="topbox_error"><p>' + that.options.errorMessage + '</p></div>'); 863 content.html(wrapError); 864 } 865 } 866 867 // PDF 868 else if (href.match(/\.(pdf)$/i) !== null) { 869 if (/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent)) { 870 var pdfLink = href 871 var pdfMobileMessage = jQuery('<div class="topbox_pdf_mobile_message"><p>' + that.options.pdfMessage + '<br><a href="' + pdfLink + '" target="_blank" class="topbox_pdf_mobile_button">' + that.options.pdfButton + '</a></p></div>'); 872 content.html(pdfMobileMessage); 873 } else { 874 var iframe = jQuery('<iframe>', { 875 src: href, 876 'class': 'topbox_pdf', 877 frameborder: 0, 878 vspace: 0, 879 hspace: 0, 880 scrolling: 'auto' 881 }); 882 content.html(iframe); 883 jQuery('iframe.topbox_pdf').wrap('<div class="topbox_pdf_wrap" />'); 884 } 885 } 886 887 // HTML5 audio 888 else if (href.match(/\.(ogg|mp3)$/i) !== null) { 889 var audioframe = jQuery('<audio>', { 890 src: href, 891 'id': 'player', 892 'class': 'topbox_html5audio', 893 'controls': 'true', 894 'playsinline': 'true', 895 'preload': 'auto', 896 'autoplay': 'true' 897 }); 898 content.html(audioframe); 899 jQuery('audio.topbox_html5audio').wrap('<div class="topbox_html5_audio_wrap" />'); 900 } 901 902 // HTML5 video 903 else if (href.match(/\.(ogv|mov|webm|mp4)$/i) !== null) { 904 var vidframe = jQuery('<video>', { 905 src: href, 906 'id': 'player', 907 'class': 'topbox_html5video', 908 'controls': 'true', 909 'playsinline': 'true', 910 'preload': 'auto', 911 'autoplay': 'true' 912 }); 913 content.html(vidframe); 914 jQuery('video.topbox_html5video').wrap('<div class="topbox_html5_video_wrap" />'); 915 } 916 917 // iFrame (default) 918 else if (link.attr('data-lightbox-type') == 'iframe') { 919 var iframe = jQuery('<iframe>', { 920 src: href, 921 'class': 'topbox_iframe', 922 frameborder: 0, 923 vspace: 0, 924 hspace: 0, 925 scrolling: 'auto' 926 }); 927 content.html(iframe); 928 jQuery('iframe.topbox_iframe').wrap('<div class="topbox_iframe_wrap" />'); 929 } 930 931 // Video iFrame 932 else if (link.attr('data-lightbox-type') == 'video-iframe') { 933 var iframe = jQuery('<iframe>', { 934 src: href, 935 'class': 'topbox_video_iframe', 936 frameborder: 0, 937 vspace: 0, 938 hspace: 0, 939 scrolling: 'auto' 940 }); 941 content.html(iframe); 942 jQuery('iframe.topbox_video_iframe').wrap('<div class="topbox_video_iframe_wrap" />'); 943 944 } else { 945 return false;
946 } 947 948 // Set the title 949 if (link.attr(this.options.titleSource)) { 950 var titleWrap = jQuery('<span>', { 951 'id': 'topbox_title', 952 'class': 'topbox_title' 953 }); 954 titleWrap.text(link.attr(this.options.titleSource)); 955 jQuery('.topbox_title_wrap').html(titleWrap); 956 } else { 957 jQuery('.topbox_title_wrap').html(''); 958 } 959 }, 960 961 constructLightbox: function() { 962 if (jQuery('.topbox_overlay').length) return jQuery('.topbox_overlay'); 963 964 var overlay = jQuery('<div>', { 965 'aria-labelledby': 'topbox_title', 966 'role': 'dialog', 967 'class': 'topbox_overlay topbox_skin_' + this.options.skin + ' topbox_effect_' + this.options.effect 968 }); 969 var fill = jQuery('<div class="topbox_fill"></div>'); 970 var wrap = jQuery('<div>', { 971 'class': 'topbox_wrapper' 972 }); 973 var content = jQuery('<div>', { 974 'class': 'topbox_content' 975 }); 976 var title = jQuery('<div>', { 977 'class': 'topbox_title_wrap' 978 }); 979 // Why are we using links here and not buttons? Links permit tab / keybaord focus better 980 var nav = jQuery('<a href="#" class="topbox_nav topbox_prev" tabindex="2" title="' + this.options.previousToolTip + '"></a><a href="#" class="topbox_nav topbox_next" tabindex="3" title="' + this.options.nextToolTip + '"></a>'); 981 var close = jQuery('<a href="#" class="topbox_close" tabindex="1" title="' + this.options.closeToolTip + '"></a>'); 982 983 overlay.append(fill); 984 wrap.append(content); 985 wrap.append(title); 986 overlay.append(wrap); 987 overlay.append(nav); 988 overlay.append(close); 989 jQuery('body').append(overlay); 990 991 var that = this; 992 if (that.options.clickOverlayToClose) { 993 overlay.on('click', function(e) { 994 if (e.target === this || jQuery(e.target).hasClass('topbox_wrapper') || jQuery(e.target).hasClass('topbox_content')) { 995 that.destructLightbox(); 996 } 997 }); 998 } 999 if (that.options.clickImgToClose) { 1000 overlay.on('click', function(e) { 1001 if (e.target === this || jQuery(e.target).hasClass('topbox_image')) { 1002 that.destructLightbox(); 1003 } 1004 }); 1005 } 1006 1007 close.on('click', function(e) { 1008 e.preventDefault(); 1009 that.destructLightbox(); 1010 }); 1011 1012 // Custom close buttons 1013 jQuery('.topbox_closer').on('click', function(e) { 1014 e.preventDefault(); 1015 that.destructLightbox(); 1016 }); 1017 1018 // Lock keyboard / tab focus to TopBox (prevents a user being able to tab behind the open lightbox) 1019 jQuery("*[tabindex]").each(function(i) { 1020 // Store tabindex as data and change all instances to -1 1021 jQuery(this).data('tabindex', jQuery(this).attr('tabindex')).attr('tabindex', '-1'); 1022 }); 1023 jQuery(".topbox_overlay *[tabindex]").each(function(index) { 1024 // Restore any tabindex in TopBox back to their defaults, e.g. close button 1, prev 2, next 3 1025 jQuery(this).attr('tabindex', jQuery(this).data('tabindex')); 1026 }); 1027 1028 return overlay; 1029 }, 1030 1031 destructLightbox: function() { 1032 var that = this; 1033 this.options.beforeHideLightbox.call(this); 1034 1035 jQuery('.topbox_overlay').removeClass('topbox_open'); 1036 jQuery('.topbox_nav').hide(); 1037 jQuery('body').removeClass('topbox_open topbox_body_effect_' + that.options.effect); 1038 1039 // Remove click handlers 1040 jQuery('.topbox_prev').off('click'); 1041 jQuery('.topbox_next').off('click'); 1042 1043 // Empty content 1044 jQuery('.topbox_content').empty(); 1045 1046 // Restore tabindex values 1047 jQuery("*[tabindex]").each(function(i) { 1048 jQuery(this).attr('tabindex', jQuery(this).data('tabindex')); 1049 }); 1050 1051 this.options.afterHideLightbox.call(this); 1052 }, 1053 1054 }; 1055 1056 jQuery.fn[pluginName] = function(options) { 1057 return this.each(function() { 1058 if (!jQuery.data(this, pluginName)) { 1059 jQuery.data(this, pluginName, new TopBox(this, options)); 1060 } 1061 }); 1062 }; 1063 1064 // Start Swipe support 1065 var addSwipeTo = function(selector) { 1066 jQuery(selector).swipe("destroy"); 1067 jQuery(selector).swipe({ 1068 swipe: function(event, direction, distance, duration, fingerCount, fingerData) { 1069 if (direction == "left") { 1070 jQuery(".topbox_next").trigger("click"); 1071 } 1072 if (direction == "right") { 1073 jQuery(".topbox_prev").trigger("click"); 1074 } 1075 } 1076 }); 1077 }; 1078 1079 jQuery(document).on('click', ".lightbox", function() { 1080 addSwipeTo(".topbox_overlay"); 1081 }); 1082 // End Swipe support 1083 1084});
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.