vendor: 2,956 bytes, lines 1-105
1/* Source and licensing information for the line(s) below can be found at https://www.justformen.com/sites/g/files/sgirzt191/files/cohesion/scripts/drupal-menu/pep.js. */ 2/*! 3 * @sitestudioexcludesonar 4 * PEP v0.4.3 | https://github.com/jquery/PEP 5 * Copyright jQuery Foundation and other contributors | http://jquery.org/license 6 */ 7 8(function (global, factory) { 9 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 10 typeof define === 'function' && define.amd ? define(factory) : 11 (global.PointerEventsPolyfill = factory()); 12}(this, function () { 'use strict'; 13 14 /** 15 * This is the constructor for new PointerEvents. 16 * 17 * New Pointer Events must be given a type, and an optional dictionary of 18 * initialization properties. 19 * 20 * Due to certain platform requirements, events returned from the constructor 21 * identify as MouseEvents. 22 * 23 * @constructor 24 * @param {String} inType The type of the event to create. 25 * @param {Object} [inDict] An optional dictionary of initial event properties. 26 * @return {Event} A new PointerEvent of type `inType`, initialized with properties from `inDict`. 27 */ 28 var MOUSE_PROPS = [ 29 'bubbles', 30 'cancelable', 31 'view', 32 'detail', 33 'screenX', 34 'screenY', 35 'clientX', 36 'clientY', 37 'ctrlKey', 38 'altKey', 39 'shiftKey', 40 'metaKey', 41 'button', 42 'relatedTarget', 43 'pageX', 44 'pageY' 45 ]; 46 47 var MOUSE_DEFAULTS = [ 48 false, 49 false, 50 null, 51 null, 52 0, 53 0, 54 0, 55 0, 56 false, 57 false, 58 false, 59 false, 60 0, 61 null, 62 0, 63 0 64 ]; 65 66 function PointerEvent(inType, inDict) { 67 inDict = inDict || Object.create(null); 68 69 var e = document.createEvent('Event'); 70 e.initEvent(inType, inDict.bubbles || false, inDict.cancelable || false); 71 72 // define inherited MouseEvent properties 73 // skip bubbles and cancelable since they're set above in initEvent() 74 for (var i = 2, p; i < MOUSE_PROPS.length; i++) { 75 p = MOUSE_PROPS[i]; 76 e[p] = inDict[p] || MOUSE_DEFAULTS[i]; 77 } 78 e.buttons = inDict.buttons || 0; 79 80 // Spec requires that pointers without pressure specified use 0.5 for down 81 // state and 0 for up state. 82 var pressure = 0; 83 84 if (inDict.pressure && e.buttons) { 85 pressure = inDict.pressure; 86 } else { 87 pressure = e.buttons ? 0.5 : 0; 88 } 89 90 // add x/y properties aliased to clientX/Y 91 e.x = e.clientX; 92 e.y = e.clientY; 93 94 // define the properties of the PointerEvent interface 95 e.pointerId = inDict.pointerId || 0; 96 e.width = inDict.width || 0; 97 e.height = inDict.height || 0; 98 e.pressure = pressure; 99 e.tiltX = inDict.tiltX || 0; 100 e.tiltY = inDict.tiltY || 0; 101 e.twist = inDict.twist || 0; 102 e.tangentialPressure = inDict.tangentialPressure || 0; 103 e.pointerType = inDict.pointerType || ''; 104 e.hwTimestamp = inDict.hwTimestamp || 0; 105 e.isPrimary = inDict.isPrimary || false
vendor: 9,237 bytes, lines 105-469
105; 106 return e; 107 } 108 109 /** 110 * This module implements a map of pointer states 111 */ 112 var USE_MAP = window.Map && window.Map.prototype.forEach; 113 var PointerMap = USE_MAP ? Map : SparseArrayMap; 114 115 function SparseArrayMap() { 116 this.array = []; 117 this.size = 0; 118 } 119 120 SparseArrayMap.prototype = { 121 set: function(k, v) { 122 if (v === undefined) { 123 return this.delete(k); 124 } 125 if (!this.has(k)) { 126 this.size++; 127 } 128 this.array[k] = v; 129 }, 130 has: function(k) { 131 return this.array[k] !== undefined; 132 }, 133 delete: function(k) { 134 if (this.has(k)) { 135 delete this.array[k]; 136 this.size--; 137 } 138 }, 139 get: function(k) { 140 return this.array[k]; 141 }, 142 clear: function() { 143 this.array.length = 0; 144 this.size = 0; 145 }, 146 147 // return value, key, map 148 forEach: function(callback, thisArg) { 149 return this.array.forEach(function(v, k) { 150 callback.call(thisArg, v, k, this); 151 }, this); 152 } 153 }; 154 155 var CLONE_PROPS = [ 156 157 // MouseEvent 158 'bubbles', 159 'cancelable', 160 'view', 161 'detail', 162 'screenX', 163 'screenY', 164 'clientX', 165 'clientY', 166 'ctrlKey', 167 'altKey', 168 'shiftKey', 169 'metaKey', 170 'button', 171 'relatedTarget', 172 173 // DOM Level 3 174 'buttons', 175 176 // PointerEvent 177 'pointerId', 178 'width', 179 'height', 180 'pressure', 181 'tiltX', 182 'tiltY', 183 'pointerType', 184 'hwTimestamp', 185 'isPrimary', 186 187 // event instance 188 'type', 189 'target', 190 'currentTarget', 191 'which', 192 'pageX', 193 'pageY', 194 'timeStamp' 195 ]; 196 197 var CLONE_DEFAULTS = [ 198 199 // MouseEvent 200 false, 201 false, 202 null, 203 null, 204 0, 205 0, 206 0, 207 0, 208 false, 209 false, 210 false, 211 false, 212 0, 213 null, 214 215 // DOM Level 3 216 0, 217 218 // PointerEvent 219 0, 220 0, 221 0, 222 0, 223 0, 224 0, 225 '', 226 0, 227 false, 228 229 // event instance 230 '', 231 null, 232 null, 233 0, 234 0, 235 0, 236 0 237 ]; 238 239 var BOUNDARY_EVENTS = { 240 'pointerover': 1, 241 'pointerout': 1, 242 'pointerenter': 1, 243 'pointerleave': 1 244 }; 245 246 var HAS_SVG_INSTANCE = (typeof SVGElementInstance !== 'undefined'); 247 248 /** 249 * This module is for normalizing events. Mouse and Touch events will be 250 * collected here, and fire PointerEvents that have the same semantics, no 251 * matter the source. 252 * Events fired: 253 * - pointerdown: a pointing is added 254 * - pointerup: a pointer is removed 255 * - pointermove: a pointer is moved 256 * - pointerover: a pointer crosses into an element 257 * - pointerout: a pointer leaves an element 258 * - pointercancel: a pointer will no longer generate events 259 */ 260 var dispatcher = { 261 pointermap: new PointerMap(), 262 eventMap: Object.create(null), 263 captureInfo: Object.create(null), 264 265 // Scope objects for native events. 266 // This exists for ease of testing. 267 eventSources: Object.create(null), 268 eventSourceList: [], 269 /** 270 * Add a new event source that will generate pointer events. 271 * 272 * `inSource` must contain an array of event names named `events`, and 273 * functions with the names specified in the `events` array. 274 * @param {string} name A name for the event source 275 * @param {Object} source A new source of platform events. 276 */ 277 registerSource: function(name, source) { 278 var s = source; 279 var newEvents = s.events; 280 if (newEvents) { 281 newEvents.forEach(function(e) { 282 if (s[e]) { 283 this.eventMap[e] = s[e].bind(s); 284 } 285 }, this); 286 this.eventSources[name] = s; 287 this.eventSourceList.push(s); 288 } 289 }, 290 register: function(element) { 291 var l = this.eventSourceList.length; 292 for (var i = 0, es; (i < l) && (es = this.eventSourceList[i]); i++) { 293 294 // call eventsource register 295 es.register.call(es, element); 296 } 297 }, 298 unregister: function(element) { 299 var l = this.eventSourceList.length; 300 for (var i = 0, es; (i < l) && (es = this.eventSourceList[i]); i++) { 301 302 // call eventsource register 303 es.unregister.call(es, element); 304 } 305 }, 306 contains: /*scope.external.contains || */function(container, contained) { 307 try { 308 return container.contains(contained); 309 } catch (ex) { 310 311 // most likely: https://bugzilla.mozilla.org/show_bug.cgi?id=208427 312 return false; 313 } 314 }, 315 316 // EVENTS 317 down: function(inEvent) { 318 inEvent.bubbles = true; 319 this.fireEvent('pointerdown', inEvent); 320 }, 321 move: function(inEvent) { 322 inEvent.bubbles = true; 323 this.fireEvent('pointermove', inEvent); 324 }, 325 up: function(inEvent) { 326 inEvent.bubbles = true; 327 this.fireEvent('pointerup', inEvent); 328 }, 329 enter: function(inEvent) { 330 inEvent.bubbles = false; 331 this.fireEvent('pointerenter', inEvent); 332 }, 333 leave: function(inEvent) { 334 inEvent.bubbles = false; 335 this.fireEvent('pointerleave', inEvent); 336 }, 337 over: function(inEvent) { 338 inEvent.bubbles = true; 339 this.fireEvent('pointerover', inEvent); 340 }, 341 out: function(inEvent) { 342 inEvent.bubbles = true; 343 this.fireEvent('pointerout', inEvent); 344 }, 345 cancel: function(inEvent) { 346 inEvent.bubbles = true; 347 this.fireEvent('pointercancel', inEvent); 348 }, 349 leaveOut: function(event) { 350 this.out(event); 351 this.propagate(event, this.leave, false); 352 }, 353 enterOver: function(event) { 354 this.over(event); 355 this.propagate(event, this.enter, true); 356 }, 357 358 // LISTENER LOGIC 359 eventHandler: function(inEvent) { 360 361 // This is used to prevent multiple dispatch of pointerevents from 362 // platform events. This can happen when two elements in different scopes 363 // are set up to create pointer events, which is relevant to Shadow DOM. 364 if (inEvent._handledByPE) { 365 return; 366 } 367 var type = inEvent.type; 368 var fn = this.eventMap && this.eventMap[type]; 369 if (fn) { 370 fn(inEvent); 371 } 372 inEvent._handledByPE = true; 373 }, 374 375 // set up event listeners 376 listen: function(target, events) { 377 events.forEach(function(e) { 378 this.addEvent(target, e); 379 }, this); 380 }, 381 382 // remove event listeners 383 unlisten: function(target, events) { 384 events.forEach(function(e) { 385 this.removeEvent(target, e); 386 }, this); 387 }, 388 addEvent: /*scope.external.addEvent || */function(target, eventName) { 389 target.addEventListener(eventName, this.boundHandler); 390 }, 391 removeEvent: /*scope.external.removeEvent || */function(target, eventName) { 392 target.removeEventListener(eventName, this.boundHandler); 393 }, 394 395 // EVENT CREATION AND TRACKING 396 /** 397 * Creates a new Event of type `inType`, based on the information in 398 * `inEvent`. 399 * 400 * @param {string} inType A string representing the type of event to create 401 * @param {Event} inEvent A platform event with a target 402 * @return {Event} A PointerEvent of type `inType` 403 */ 404 makeEvent: function(inType, inEvent) { 405 406 // relatedTarget must be null if pointer is captured 407 if (this.captureInfo[inEvent.pointerId]) { 408 inEvent.relatedTarget = null; 409 } 410 var e = new PointerEvent(inType, inEvent); 411 if (inEvent.preventDefault) { 412 e.preventDefault = inEvent.preventDefault; 413 } 414 e._target = e._target || inEvent.target; 415 return e; 416 }, 417 418 // make and dispatch an event in one call 419 fireEvent: function(inType, inEvent) { 420 var e = this.makeEvent(inType, inEvent); 421 return this.dispatchEvent(e); 422 }, 423 /** 424 * Returns a snapshot of inEvent, with writable properties. 425 * 426 * @param {Event} inEvent An event that contains properties to copy. 427 * @return {Object} An object containing shallow copies of `inEvent`'s 428 * properties. 429 */ 430 cloneEvent: function(inEvent) { 431 var eventCopy = Object.create(null); 432 var p; 433 for (var i = 0; i < CLONE_PROPS.length; i++) { 434 p = CLONE_PROPS[i]; 435 eventCopy[p] = inEvent[p] || CLONE_DEFAULTS[i]; 436 437 // Work around SVGInstanceElement shadow tree 438 // Return the <use> element that is represented by the instance for Safari, Chrome, IE. 439 // This is the behavior implemented by Firefox. 440 if (HAS_SVG_INSTANCE && (p === 'target' || p === 'relatedTarget')) { 441 if (eventCopy[p] instanceof SVGElementInstance) { 442 eventCopy[p] = eventCopy[p].correspondingUseElement; 443 } 444 } 445 } 446 447 // keep the semantics of preventDefault 448 if (inEvent.preventDefault) { 449 eventCopy.preventDefault = function() { 450 inEvent.preventDefault(); 451 }; 452 } 453 return eventCopy; 454 }, 455 getTarget: function(inEvent) { 456 var capture = this.captureInfo[inEvent.pointerId]; 457 if (!capture) { 458 return inEvent._target; 459 } 460 if (inEvent._target === capture || !(inEvent.type in BOUNDARY_EVENTS)) { 461 return capture; 462 } 463 }, 464 propagate: function(event, fn, propagateDown) { 465 var target = event.target; 466 var targets = []; 467 468 // Order of conditions due to document.contains() missing in IE. 469 while (target !=
vendor: 4,502 bytes, lines 469-629
469= document && !target.contains(event.relatedTarget)) { 470 targets.push(target); 471 target = target.parentNode; 472 473 // Touch: Do not propagate if node is detached. 474 if (!target) { 475 return; 476 } 477 } 478 if (propagateDown) { 479 targets.reverse(); 480 } 481 targets.forEach(function(target) { 482 event.target = target; 483 fn.call(this, event); 484 }, this); 485 }, 486 setCapture: function(inPointerId, inTarget, skipDispatch) { 487 if (this.captureInfo[inPointerId]) { 488 this.releaseCapture(inPointerId, skipDispatch); 489 } 490 491 this.captureInfo[inPointerId] = inTarget; 492 this.implicitRelease = this.releaseCapture.bind(this, inPointerId, skipDispatch); 493 document.addEventListener('pointerup', this.implicitRelease); 494 document.addEventListener('pointercancel', this.implicitRelease); 495 496 var e = new PointerEvent('gotpointercapture'); 497 e.pointerId = inPointerId; 498 e._target = inTarget; 499 500 if (!skipDispatch) { 501 this.asyncDispatchEvent(e); 502 } 503 }, 504 releaseCapture: function(inPointerId, skipDispatch) { 505 var t = this.captureInfo[inPointerId]; 506 if (!t) { 507 return; 508 } 509 510 this.captureInfo[inPointerId] = undefined; 511 document.removeEventListener('pointerup', this.implicitRelease); 512 document.removeEventListener('pointercancel', this.implicitRelease); 513 514 var e = new PointerEvent('lostpointercapture'); 515 e.pointerId = inPointerId; 516 e._target = t; 517 518 if (!skipDispatch) { 519 this.asyncDispatchEvent(e); 520 } 521 }, 522 /** 523 * Dispatches the event to its target. 524 * 525 * @param {Event} inEvent The event to be dispatched. 526 * @return {Boolean} True if an event handler returns true, false otherwise. 527 */ 528 dispatchEvent: /*scope.external.dispatchEvent || */function(inEvent) { 529 var t = this.getTarget(inEvent); 530 if (t) { 531 return t.dispatchEvent(inEvent); 532 } 533 }, 534 asyncDispatchEvent: function(inEvent) { 535 requestAnimationFrame(this.dispatchEvent.bind(this, inEvent)); 536 } 537 }; 538 dispatcher.boundHandler = dispatcher.eventHandler.bind(dispatcher); 539 540 var targeting = { 541 shadow: function(inEl) { 542 if (inEl) { 543 return inEl.shadowRoot || inEl.webkitShadowRoot; 544 } 545 }, 546 canTarget: function(shadow) { 547 return shadow && Boolean(shadow.elementFromPoint); 548 }, 549 targetingShadow: function(inEl) { 550 var s = this.shadow(inEl); 551 if (this.canTarget(s)) { 552 return s; 553 } 554 }, 555 olderShadow: function(shadow) { 556 var os = shadow.olderShadowRoot; 557 if (!os) { 558 var se = shadow.querySelector('shadow'); 559 if (se) { 560 os = se.olderShadowRoot; 561 } 562 } 563 return os; 564 }, 565 allShadows: function(element) { 566 var shadows = []; 567 var s = this.shadow(element); 568 while (s) { 569 shadows.push(s); 570 s = this.olderShadow(s); 571 } 572 return shadows; 573 }, 574 searchRoot: function(inRoot, x, y) { 575 if (inRoot) { 576 var t = inRoot.elementFromPoint(x, y); 577 var st, sr; 578 579 // is element a shadow host? 580 sr = this.targetingShadow(t); 581 while (sr) { 582 583 // find the the element inside the shadow root 584 st = sr.elementFromPoint(x, y); 585 if (!st) { 586 587 // check for older shadows 588 sr = this.olderShadow(sr); 589 } else { 590 591 // shadowed element may contain a shadow root 592 var ssr = this.targetingShadow(st); 593 return this.searchRoot(ssr, x, y) || st; 594 } 595 } 596 597 // light dom element is the target 598 return t; 599 } 600 }, 601 owner: function(element) { 602 var s = element; 603 604 // walk up until you hit the shadow root or document 605 while (s.parentNode) { 606 s = s.parentNode; 607 } 608 609 // the owner element is expected to be a Document or ShadowRoot 610 if (s.nodeType !== Node.DOCUMENT_NODE && s.nodeType !== Node.DOCUMENT_FRAGMENT_NODE) { 611 s = document; 612 } 613 return s; 614 }, 615 findTarget: function(inEvent) { 616 var x = inEvent.clientX; 617 var y = inEvent.clientY; 618 619 // if the listener is in the shadow root, it is much faster to start there 620 var s = this.owner(inEvent.target); 621 622 // if x, y is not in this root, fall back to document search 623 if (!s.elementFromPoint(x, y)) { 624 s = document; 625 } 626 return this.searchRoot(s, x, y); 627 } 628 }; 629
630 var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach); 631 var map = Array.prototype.map.call.bind(Array.prototype.map); 632 var toArray = Array.prototype.slice.call.bind(Array.prototype.slice); 633 var filter = Array.prototype.filter.call.bind(Array.prototype.filter); 634 var MO = window.MutationObserver || window.WebKitMutationObserver; 635 var SELECTOR = '[touch-action]'; 636 var OBSERVER_INIT = { 637 subtree: true, 638 childList: true, 639 attributes: true, 640 attributeOldValue: true, 641 attributeFilter: ['touch-action'] 642 }; 643 644 function Installer(add, remove, changed, binder) { 645 this.addCallback = add.bind(binder); 646 this.removeCallback = remove.bind(binder); 647 this.changedCallback = changed.bind(binder); 648 if (MO) { 649 this.observer = new MO(this.mutationWatcher.bind(this)); 650 } 651 } 652 653 Installer.prototype = { 654 watchSubtree: function(target) { 655 656 // Only watch scopes that can target find, as these are top-level. 657 // Otherwise we can see duplicate additions and removals that add noise. 658 // 659 // TODO(dfreedman): For some instances with ShadowDOMPolyfill, we can see 660 // a removal without an insertion when a node is redistributed among 661 // shadows. Since it all ends up correct in the document, watching only 662 // the document will yield the correct mutations to watch. 663 if (this.observer && targeting.canTarget(target)) { 664 this.observer.observe(target, OBSERVER_INIT); 665 } 666 }, 667 enableOnSubtree: function(target) { 668 this.watchSubtree(target); 669 if (target === document && document.readyState !== 'complete') { 670 this.installOnLoad(); 671 } else { 672 this.installNewSubtree(target); 673 } 674 }, 675 installNewSubtree: function(target) { 676 forEach(this.findElements(target), this.addElement, this); 677 }, 678 findElements: function(target) { 679 if (target.querySelectorAll) { 680 return target.querySelectorAll(SELECTOR); 681 } 682 return []; 683 }, 684 removeElement: function(el) { 685 this.removeCallback(el); 686 }, 687 addElement: function(el) { 688 this.addCallback(el); 689 }, 690 elementChanged: function(el, oldValue) { 691 this.changedCallback(el, oldValue); 692 }, 693 concatLists: function(accum, list) { 694 return accum.concat(toArray(list)); 695 }, 696 697 // register all touch-action = none nodes on document load 698 installOnLoad: function() { 699 document.addEventListener('readystatechange', function() { 700 if (document.readyState === 'complete') { 701 this.installNewSubtree(document); 702 } 703 }.bind(this)); 704 }, 705 isElement: function(n) { 706 return n.nodeType === Node.ELEMENT_NODE; 707 }, 708 flattenMutationTree: function(inNodes) { 709 710 // find children with touch-action 711 var tree = map(inNodes, this.findElements, this); 712 713 // make sure the added nodes are accounted for 714 tree.push(filter(inNodes, this.isElement)); 715 716 // flatten the list 717 return tree.reduce(this.concatLists, []); 718 }, 719 mutationWatcher: function(mutations) { 720 mutations.forEach(this.mutationHandler, this); 721 }, 722 mutationHandler: function(m) { 723 if (m.type === 'childList') { 724 var added = this.flattenMutationTree(m.addedNodes); 725 added.forEach(this.addElement, this); 726 var removed = this.flattenMutationTree(m.removedNodes); 727 removed.forEach(this.removeElement, this); 728 } else if (m.type === 'attributes') { 729 this.elementChanged(m.target, m.oldValue); 730 } 731 } 732 }; 733 734 function shadowSelector(v) { 735 return 'body /shadow-deep/ ' + selector(v); 736 } 737 function selector(v) { 738 return '[touch-action="' + v + '"]'; 739 } 740 function rule(v) { 741 return '{ -ms-touch-action: ' + v + '; touch-action: ' + v + '; }'; 742 } 743 var attrib2css = [ 744 'none', 745 'auto', 746 'pan-x', 747 'pan-y', 748 { 749 rule: 'pan-x pan-y', 750 selectors: [ 751 'pan-x pan-y', 752 'pan-y pan-x' 753 ] 754 } 755 ]; 756 var styles = ''; 757 758 // only install stylesheet if the browser has touch action support 759 var hasNativePE = window.PointerEvent || window.MSPointerEvent; 760 761 // only add shadow selectors if shadowdom is supported 762 var hasShadowRoot = !window.ShadowDOMPolyfill && document.head.createShadowRoot; 763 764 function applyAttributeStyles() { 765 if (hasNativePE) { 766 attrib2css.forEach(function(r) { 767 if (String(r) === r) { 768 styles += selector(r) + rule(r) + '\n'; 769 if (hasShadowRoot) { 770 styles += shadowSelector(r) + rule(r) + '\n'; 771 } 772 } else { 773 styles += r.selectors.map(selector) + rule(r.rule) + '\n'; 774 if (hasShadowRoot) { 775 styles += r.selectors.map(shadowSelector) + rule(r.rule) + '\n'; 776 } 777 } 778 }); 779 780 var el = document.createElement('style'); 781 el.textContent = styles; 782 document.head.appendChild(el); 783 } 784 } 785 786 var pointermap = dispatcher.pointermap; 787 788 // radius around touchend that swallows mouse events 789 var DEDUP_DIST = 25; 790 791 // left, middle, right, back, forward 792 var BUTTON_TO_BUTTONS = [1, 4, 2, 8, 16]; 793 794 var HAS_BUTTONS = false;
vendor: 4,435 bytes, lines 795-937
795 try { 796 HAS_BUTTONS = new MouseEvent('test', { buttons: 1 }).buttons === 1; 797 } catch (e) {} 798 799 // handler block for native mouse events 800 var mouseEvents = { 801 POINTER_ID: 1, 802 POINTER_TYPE: 'mouse', 803 events: [ 804 'mousedown', 805 'mousemove', 806 'mouseup', 807 'mouseover', 808 'mouseout' 809 ], 810 register: function(target) { 811 dispatcher.listen(target, this.events); 812 }, 813 unregister: function(target) { 814 dispatcher.unlisten(target, this.events); 815 }, 816 lastTouches: [], 817 818 // collide with the global mouse listener 819 isEventSimulatedFromTouch: function(inEvent) { 820 var lts = this.lastTouches; 821 var x = inEvent.clientX; 822 var y = inEvent.clientY; 823 for (var i = 0, l = lts.length, t; i < l && (t = lts[i]); i++) { 824 825 // simulated mouse events will be swallowed near a primary touchend 826 var dx = Math.abs(x - t.x); 827 var dy = Math.abs(y - t.y); 828 if (dx <= DEDUP_DIST && dy <= DEDUP_DIST) { 829 return true; 830 } 831 } 832 }, 833 prepareEvent: function(inEvent) { 834 var e = dispatcher.cloneEvent(inEvent); 835 836 // forward mouse preventDefault 837 var pd = e.preventDefault; 838 e.preventDefault = function() { 839 inEvent.preventDefault(); 840 pd(); 841 }; 842 e.pointerId = this.POINTER_ID; 843 e.isPrimary = true; 844 e.pointerType = this.POINTER_TYPE; 845 return e; 846 }, 847 prepareButtonsForMove: function(e, inEvent) { 848 var p = pointermap.get(this.POINTER_ID); 849 850 // Update buttons state after possible out-of-document mouseup. 851 if (inEvent.which === 0 || !p) { 852 e.buttons = 0; 853 } else { 854 e.buttons = p.buttons; 855 } 856 inEvent.buttons = e.buttons; 857 }, 858 mousedown: function(inEvent) { 859 if (!this.isEventSimulatedFromTouch(inEvent)) { 860 var p = pointermap.get(this.POINTER_ID); 861 var e = this.prepareEvent(inEvent); 862 if (!HAS_BUTTONS) { 863 e.buttons = BUTTON_TO_BUTTONS[e.button]; 864 if (p) { e.buttons |= p.buttons; } 865 inEvent.buttons = e.buttons; 866 } 867 pointermap.set(this.POINTER_ID, inEvent); 868 if (!p || p.buttons === 0) { 869 dispatcher.down(e); 870 } else { 871 dispatcher.move(e); 872 } 873 } 874 }, 875 mousemove: function(inEvent) { 876 if (!this.isEventSimulatedFromTouch(inEvent)) { 877 var e = this.prepareEvent(inEvent); 878 if (!HAS_BUTTONS) { this.prepareButtonsForMove(e, inEvent); } 879 e.button = -1; 880 pointermap.set(this.POINTER_ID, inEvent); 881 dispatcher.move(e); 882 } 883 }, 884 mouseup: function(inEvent) { 885 if (!this.isEventSimulatedFromTouch(inEvent)) { 886 var p = pointermap.get(this.POINTER_ID); 887 var e = this.prepareEvent(inEvent); 888 if (!HAS_BUTTONS) { 889 var up = BUTTON_TO_BUTTONS[e.button]; 890 891 // Produces wrong state of buttons in Browsers without `buttons` support 892 // when a mouse button that was pressed outside the document is released 893 // inside and other buttons are still pressed down. 894 e.buttons = p ? p.buttons & ~up : 0; 895 inEvent.buttons = e.buttons; 896 } 897 pointermap.set(this.POINTER_ID, inEvent); 898 899 // Support: Firefox <=44 only 900 // FF Ubuntu includes the lifted button in the `buttons` property on 901 // mouseup. 902 // https://bugzilla.mozilla.org/show_bug.cgi?id=1223366 903 e.buttons &= ~BUTTON_TO_BUTTONS[e.button]; 904 if (e.buttons === 0) { 905 dispatcher.up(e); 906 } else { 907 dispatcher.move(e); 908 } 909 } 910 }, 911 mouseover: function(inEvent) { 912 if (!this.isEventSimulatedFromTouch(inEvent)) { 913 var e = this.prepareEvent(inEvent); 914 if (!HAS_BUTTONS) { this.prepareButtonsForMove(e, inEvent); } 915 e.button = -1; 916 pointermap.set(this.POINTER_ID, inEvent); 917 dispatcher.enterOver(e); 918 } 919 }, 920 mouseout: function(inEvent) { 921 if (!this.isEventSimulatedFromTouch(inEvent)) { 922 var e = this.prepareEvent(inEvent); 923 if (!HAS_BUTTONS) { this.prepareButtonsForMove(e, inEvent); } 924 e.button = -1; 925 dispatcher.leaveOut(e); 926 } 927 }, 928 cancel: function(inEvent) { 929 var e = this.prepareEvent(inEvent); 930 dispatcher.cancel(e); 931 this.deactivateMouse(); 932 }, 933 deactivateMouse: function() { 934 pointermap.delete(this.POINTER_ID); 935 } 936 }; 937
938 var captureInfo = dispatcher.captureInfo; 939 var findTarget = targeting.findTarget.bind(targeting); 940 var allShadows = targeting.allShadows.bind(targeting); 941 var pointermap$1 = dispatcher.pointermap; 942 943 // This should be long enough to ignore compat mouse events made by touch 944 var DEDUP_TIMEOUT = 2500; 945 var CLICK_COUNT_TIMEOUT = 200; 946 var ATTRIB = 'touch-action'; 947 var INSTALLER; 948 949 // handler block for native touch events 950 var touchEvents = { 951 events: [ 952 'touchstart', 953 'touchmove', 954 'touchend', 955 'touchcancel' 956 ], 957 register: function(target) { 958 INSTALLER.enableOnSubtree(target); 959 }, 960 unregister: function() { 961 962 // TODO(dfreedman): is it worth it to disconnect the MO? 963 }, 964 elementAdded: function(el) { 965 var a = el.getAttribute(ATTRIB); 966 var st = this.touchActionToScrollType(a); 967 if (st) { 968 el._scrollType = st; 969 dispatcher.listen(el, this.events); 970 971 // set touch-action on shadows as well 972 allShadows(el).forEach(function(s) { 973 s._scrollType = st; 974 dispatcher.listen(s, this.events); 975 }, this); 976 } 977 }, 978 elementRemoved: function(el) { 979 el._scrollType = undefined; 980 dispatcher.unlisten(el, this.events); 981 982 // remove touch-action from shadow 983 allShadows(el).forEach(function(s) { 984 s._scrollType = undefined; 985 dispatcher.unlisten(s, this.events); 986 }, this); 987 }, 988 elementChanged: function(el, oldValue) { 989 var a = el.getAttribute(ATTRIB); 990 var st = this.touchActionToScrollType(a); 991 var oldSt = this.touchActionToScrollType(oldValue); 992 993 // simply update scrollType if listeners are already established 994 if (st && oldSt) { 995 el._scrollType = st; 996 allShadows(el).forEach(function(s) { 997 s._scrollType = st; 998 }, this); 999 } else if (oldSt) { 1000 this.elementRemoved(el); 1001 } else if (st) { 1002 this.elementAdded(el); 1003 } 1004 }, 1005 scrollTypes: { 1006 EMITTER: 'none', 1007 XSCROLLER: 'pan-x', 1008 YSCROLLER: 'pan-y', 1009 SCROLLER: /^(?:pan-x pan-y)|(?:pan-y pan-x)|auto$/ 1010 }, 1011 touchActionToScrollType: function(touchAction) { 1012 var t = touchAction; 1013 var st = this.scrollTypes; 1014 if (t === 'none') { 1015 return 'none'; 1016 } else if (t === st.XSCROLLER) { 1017 return 'X'; 1018 } else if (t === st.YSCROLLER) { 1019 return 'Y'; 1020 } else if (st.SCROLLER.exec(t)) { 1021 return 'XY'; 1022 } 1023 }, 1024 POINTER_TYPE: 'touch', 1025 firstTouch: null, 1026 isPrimaryTouch: function(inTouch) { 1027 return this.firstTouch === inTouch.identifier; 1028 }, 1029 setPrimaryTouch: function(inTouch) { 1030 1031 // set primary touch if there no pointers, or the only pointer is the mouse 1032 if (pointermap$1.size === 0 || (pointermap$1.size === 1 && pointermap$1.has(1))) { 1033 this.firstTouch = inTouch.identifier; 1034 this.firstXY = { X: inTouch.clientX, Y: inTouch.clientY }; 1035 this.scrolling = false; 1036 this.cancelResetClickCount(); 1037 } 1038 }, 1039 removePrimaryPointer: function(inPointer) { 1040 if (inPointer.isPrimary) { 1041 this.firstTouch = null; 1042 this.firstXY = null; 1043 this.resetClickCount(); 1044 } 1045 }, 1046 clickCount: 0, 1047 resetId: null, 1048 resetClickCount: function() { 1049 var fn = function() { 1050 this.clickCount = 0; 1051 this.resetId = null; 1052 }.bind(this); 1053 this.resetId = setTimeout(fn, CLICK_COUNT_TIMEOUT); 1054 }, 1055 cancelResetClickCount: function() { 1056 if (this.resetId) { 1057 clearTimeout(this.resetId); 1058 } 1059 }, 1060 typeToButtons: function(type) { 1061 var ret = 0; 1062 if (type === 'touchstart' || type === 'touchmove') { 1063 ret = 1; 1064 } 1065 return ret; 1066 }, 1067 touchToPointer: function(inTouch) { 1068 var cte = this.currentTouchEvent; 1069 var e = dispatcher.cloneEvent(inTouch); 1070 1071 // We reserve pointerId 1 for Mouse. 1072 // Touch identifiers can start at 0. 1073 // Add 2 to the touch identifier for compatibility. 1074 var id = e.pointerId = inTouch.identifier + 2; 1075 e.target = captureInfo[id] || findTarget(e); 1076 e.bubbles = true; 1077 e.cancelable = true; 1078 e.detail = this.clickCount; 1079 e.button = 0; 1080 e.buttons = this.typeToButtons(cte.type); 1081 e.width = (inTouch.radiusX || inTouch.webkitRadiusX || 0) * 2; 1082 e.height = (inTouch.radiusY || inTouch.webkitRadiusY || 0) * 2; 1083 e.pressure = inTouch.force || inTouch.webkitForce || 0.5; 1084 e.isPrimary = this.isPrimaryTouch(inTouch); 1085 e.pointerType = this.POINTER_TYPE; 1086 1087 // forward modifier keys 1088 e.altKey = cte.altKey; 1089 e.ctrlKey = cte.ctrlKey; 1090 e.metaKey = cte.metaKey; 1091 e.shiftKey = cte.shiftKey; 1092 1093 // forward touch preventDefaults 1094 var self = this; 1095 e.preventDefault = function() { 1096 self.scrolling = false;
1097 self.firstXY = null; 1098 cte.preventDefault(); 1099 }; 1100 return e; 1101 }, 1102 processTouches: function(inEvent, inFunction) { 1103 var tl = inEvent.changedTouches; 1104 this.currentTouchEvent = inEvent; 1105 for (var i = 0, t; i < tl.length; i++) { 1106 t = tl[i]; 1107 inFunction.call(this, this.touchToPointer(t)); 1108 } 1109 }, 1110 1111 // For single axis scrollers, determines whether the element should emit 1112 // pointer events or behave as a scroller 1113 shouldScroll: function(inEvent) { 1114 if (this.firstXY) { 1115 var ret; 1116 var scrollAxis = inEvent.currentTarget._scrollType; 1117 if (scrollAxis === 'none') { 1118 1119 // this element is a touch-action: none, should never scroll 1120 ret = false; 1121 } else if (scrollAxis === 'XY') { 1122 1123 // this element should always scroll 1124 ret = true; 1125 } else { 1126 var t = inEvent.changedTouches[0]; 1127 1128 // check the intended scroll axis, and other axis 1129 var a = scrollAxis; 1130 var oa = scrollAxis === 'Y' ? 'X' : 'Y'; 1131 var da = Math.abs(t['client' + a] - this.firstXY[a]); 1132 var doa = Math.abs(t['client' + oa] - this.firstXY[oa]); 1133 1134 // if delta in the scroll axis > delta other axis, scroll instead of 1135 // making events 1136 ret = da >= doa; 1137 } 1138 this.firstXY = null; 1139 return ret; 1140 } 1141 }, 1142 findTouch: function(inTL, inId) { 1143 for (var i = 0, l = inTL.length, t; i < l && (t = inTL[i]); i++) { 1144 if (t.identifier === inId) { 1145 return true; 1146 } 1147 } 1148 }, 1149 1150 // In some instances, a touchstart can happen without a touchend. This 1151 // leaves the pointermap in a broken state. 1152 // Therefore, on every touchstart, we remove the touches that did not fire a 1153 // touchend event. 1154 // To keep state globally consistent, we fire a 1155 // pointercancel for this "abandoned" touch 1156 vacuumTouches: function(inEvent) { 1157 var tl = inEvent.touches; 1158 1159 // pointermap.size should be < tl.length here, as the touchstart has not 1160 // been processed yet. 1161 if (pointermap$1.size >= tl.length) { 1162 var d = []; 1163 pointermap$1.forEach(function(value, key) { 1164 1165 // Never remove pointerId == 1, which is mouse. 1166 // Touch identifiers are 2 smaller than their pointerId, which is the 1167 // index in pointermap. 1168 if (key !== 1 && !this.findTouch(tl, key - 2)) { 1169 var p = value.out; 1170 d.push(p); 1171 } 1172 }, this); 1173 d.forEach(this.cancelOut, this); 1174 } 1175 }, 1176 touchstart: function(inEvent) { 1177 this.vacuumTouches(inEvent); 1178 this.setPrimaryTouch(inEvent.changedTouches[0]); 1179 this.dedupSynthMouse(inEvent); 1180 if (!this.scrolling) { 1181 this.clickCount++; 1182 this.processTouches(inEvent, this.overDown); 1183 } 1184 }, 1185 overDown: function(inPointer) { 1186 pointermap$1.set(inPointer.pointerId, { 1187 target: inPointer.target, 1188 out: inPointer, 1189 outTarget: inPointer.target 1190 }); 1191 dispatcher.enterOver(inPointer); 1192 dispatcher.down(inPointer); 1193 }, 1194 touchmove: function(inEvent) { 1195 if (!this.scrolling) { 1196 if (this.shouldScroll(inEvent)) { 1197 this.scrolling = true; 1198 this.touchcancel(inEvent); 1199 } else { 1200 inEvent.preventDefault(); 1201 this.processTouches(inEvent, this.moveOverOut); 1202 } 1203 } 1204 }, 1205 moveOverOut: function(inPointer) { 1206 var event = inPointer; 1207 var pointer = pointermap$1.get(event.pointerId); 1208 1209 // a finger drifted off the screen, ignore it 1210 if (!pointer) { 1211 return; 1212 } 1213 var outEvent = pointer.out; 1214 var outTarget = pointer.outTarget; 1215 dispatcher.move(event); 1216 if (outEvent && outTarget !== event.target) { 1217 outEvent.relatedTarget = event.target; 1218 event.relatedTarget = outTarget; 1219 1220 // recover from retargeting by shadow 1221 outEvent.target = outTarget; 1222 if (event.target) { 1223 dispatcher.leaveOut(outEvent); 1224 dispatcher.enterOver(event); 1225 } else { 1226 1227 // clean up case when finger leaves the screen 1228 event.target = outTarget; 1229 event.relatedTarget = null; 1230 this.cancelOut(event); 1231 } 1232 } 1233 pointer.out = event; 1234 pointer.outTarget = event.target; 1235 }, 1236 touchend: function(inEvent) { 1237 this.dedupSynthMouse(inEvent); 1238 this.processTouches(inEvent, this.upOut); 1239 }, 1240 upOut: function(inPointer) { 1241 if (!this.scrolling) { 1242 dispatcher.up(inPointer); 1243 dispatcher.leaveOut(inPointer); 1244 } 1245 this.cleanUpPointer(inPointer); 1246 }, 1247 touchcancel: function(inEvent) { 1248 this.processTouches(inEvent, this.cancelOut); 1249 }, 1250 cancelOut: function(inPointer) { 1251 dispatcher.cancel(inPointer); 1252 dispatcher.leaveOut(inPointer); 1253 this.cleanUpPointer(inPointer); 1254 }, 1255 cleanUpPointer: function(inPointer) { 1256 pointermap$1.delete(inPointer.pointerId); 1257 this.removePrimaryPointer(inPointer); 1258 }, 1259 1260 // prevent synth mouse events from creating pointer events 1261 dedupSynthMouse: function(inEvent) { 1262 var lts = mouseEvents.lastTouches; 1263 var t = inEvent.changedTouches[0]; 1264 1265 // only the primary finger will synth mouse events 1266 if (this.isPrimaryTouch(t)) { 1267 1268 // remember x/y of last touch 1269 var lt = { x: t.clientX, y: t.clientY }; 1270 lts.push(lt); 1271 var fn = (function(lts, lt) { 1272 var i = lts.indexOf(lt); 1273 if (i > -1) { 1274 lts.splice(i, 1); 1275 } 1276 }).bind(null, lts, lt); 1277 setTimeout(fn, DEDUP_TIMEOUT); 1278 } 1279 } 1280 }; 1281 1282 INSTALLER = new Installer(touchEvents.elementAdded, touchEvents.elementRemoved, 1283 touchEvents.elementChanged, touchEvents); 1284 1285 var pointermap$2 = dispatcher.pointermap; 1286 var HAS_BITMAP_TYPE = window.MSPointerEvent && 1287 typeof window.MSPointerEvent.MSPOINTER_TYPE_MOUSE === 'number'; 1288 var msEvents = { 1289 events: [ 1290 'MSPointerDown', 1291 'MSPointerMove', 1292 'MSPointerUp', 1293 'MSPointerOut', 1294 'MSPointerOver', 1295 'MSPointerCancel', 1296 'MSGotPointerCapture', 1297 'MSLostPointerCapture' 1298 ], 1299 register: function(target) { 1300 dispatcher.listen(target, this.events); 1301 }, 1302 unregister: function(target) { 1303 dispatcher.unlisten(target, this.events); 1304 }, 1305 POINTER_TYPES: [ 1306 '', 1307 'unavailable', 1308 'touch', 1309 'pen', 1310 'mouse' 1311 ], 1312 prepareEvent: function(inEvent) { 1313 var e = inEvent; 1314 if (HAS_BITMAP_TYPE) { 1315 e = dispatcher.cloneEvent(inEvent); 1316 e.pointerType = this.POINTER_TYPES[inEvent.pointerType]; 1317 } 1318 return e; 1319 }, 1320 cleanup: function(id) { 1321 pointermap$2.delete(id); 1322 }, 1323 MSPointerDown: function(inEvent) { 1324 pointermap$2.set(inEvent.pointerId, inEvent); 1325 var e = this.prepareEvent(inEvent); 1326 dispatcher.down(e); 1327 }, 1328 MSPointerMove: function(inEvent) { 1329 var e = this.prepareEvent(inEvent); 1330 dispatcher.move(e); 1331 }, 1332 MSPointerUp: function(inEvent) { 1333 var e = this.prepareEvent(inEvent); 1334 dispatcher.up(e); 1335 this.cleanup(inEvent.pointerId); 1336 }, 1337 MSPointerOut: function(inEvent) { 1338 var e = this.prepareEvent(inEvent); 1339 dispatcher.leaveOut(e); 1340 }, 1341 MSPointerOver: function(inEvent) { 1342 var e = this.prepareEvent(inEvent); 1343 dispatcher.enterOver(e); 1344 }, 1345 MSPointerCancel: function(inEvent) { 1346 var e = this.prepareEvent(inEvent); 1347 dispatcher.cancel(e); 1348 this.cleanup(inEvent.pointerId); 1349 }, 1350 MSLostPointerCapture: function(inEvent) { 1351 var e = dispatcher.makeEvent('lostpointercapture', inEvent); 1352 dispatcher.dispatchEvent(e); 1353 }, 1354 MSGotPointerCapture: function(inEvent) { 1355 var e = dispatcher.makeEvent('gotpointercapture', inEvent); 1356 dispatcher.dispatchEvent(e); 1357 } 1358 }; 1359 1360 function applyPolyfill() { 1361 1362 // only activate if this platform does not have pointer events 1363 if (!window.PointerEvent) { 1364 window.PointerEvent = PointerEvent; 1365 1366 if (window.navigator.msPointerEnabled) { 1367 var tp = window.navigator.msMaxTouchPoints; 1368 Object.defineProperty(window.navigator, 'maxTouchPoints', { 1369 value: tp, 1370 enumerable: true 1371 }); 1372 dispatcher.registerSource('ms', msEvents); 1373 } else { 1374 Object.defineProperty(window.navigator, 'maxTouchPoints', { 1375 value: 0, 1376 enumerable: true 1377 });
vendor: 2,590 bytes, lines 1378-1477
1378 dispatcher.registerSource('mouse', mouseEvents); 1379 if (window.ontouchstart !== undefined) { 1380 dispatcher.registerSource('touch', touchEvents); 1381 } 1382 } 1383 1384 dispatcher.register(document); 1385 } 1386 } 1387 1388 var n = window.navigator; 1389 var s; 1390 var r; 1391 var h; 1392 function assertActive(id) { 1393 if (!dispatcher.pointermap.has(id)) { 1394 var error = new Error('InvalidPointerId'); 1395 error.name = 'InvalidPointerId'; 1396 throw error; 1397 } 1398 } 1399 function assertConnected(elem) { 1400 var parent = elem.parentNode; 1401 while (parent && parent !== elem.ownerDocument) { 1402 parent = parent.parentNode; 1403 } 1404 if (!parent) { 1405 var error = new Error('InvalidStateError'); 1406 error.name = 'InvalidStateError'; 1407 throw error; 1408 } 1409 } 1410 function inActiveButtonState(id) { 1411 var p = dispatcher.pointermap.get(id); 1412 return p.buttons !== 0; 1413 } 1414 if (n.msPointerEnabled) { 1415 s = function(pointerId) { 1416 assertActive(pointerId); 1417 assertConnected(this); 1418 if (inActiveButtonState(pointerId)) { 1419 dispatcher.setCapture(pointerId, this, true); 1420 this.msSetPointerCapture(pointerId); 1421 } 1422 }; 1423 r = function(pointerId) { 1424 assertActive(pointerId); 1425 dispatcher.releaseCapture(pointerId, true); 1426 this.msReleasePointerCapture(pointerId); 1427 }; 1428 } else { 1429 s = function setPointerCapture(pointerId) { 1430 assertActive(pointerId); 1431 assertConnected(this); 1432 if (inActiveButtonState(pointerId)) { 1433 dispatcher.setCapture(pointerId, this); 1434 } 1435 }; 1436 r = function releasePointerCapture(pointerId) { 1437 assertActive(pointerId); 1438 dispatcher.releaseCapture(pointerId); 1439 }; 1440 } 1441 h = function hasPointerCapture(pointerId) { 1442 return !!dispatcher.captureInfo[pointerId]; 1443 }; 1444 1445 function applyPolyfill$1() { 1446 if (window.Element && !Element.prototype.setPointerCapture) { 1447 Object.defineProperties(Element.prototype, { 1448 'setPointerCapture': { 1449 value: s 1450 }, 1451 'releasePointerCapture': { 1452 value: r 1453 }, 1454 'hasPointerCapture': { 1455 value: h 1456 } 1457 }); 1458 } 1459 } 1460 1461 applyAttributeStyles(); 1462 applyPolyfill(); 1463 applyPolyfill$1(); 1464 1465 var pointerevents = { 1466 dispatcher: dispatcher, 1467 Installer: Installer, 1468 PointerEvent: PointerEvent, 1469 PointerMap: PointerMap, 1470 targetFinding: targeting 1471 }; 1472 1473 return pointerevents; 1474 1475})); 1476 1477/* Source and licensing information for the above line(s) can be found at https://www.justformen.com/sites/g/files/sgirzt191/files/cohesion/scripts/drupal-menu/pep.js. */
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.