vendor: 14,907 bytes, lines 1-517
1/** 2 * what-input - A global utility for tracking the current input method (mouse, keyboard or touch). 3 * @version v5.2.12 4 * @link https://github.com/ten1seven/what-input 5 * @license MIT 6 */ 7(function webpackUniversalModuleDefinition(root, factory) { 8 if(typeof exports === 'object' && typeof module === 'object') 9 module.exports = factory(); 10 else if(typeof define === 'function' && define.amd) 11 define("whatInput", [], factory); 12 else if(typeof exports === 'object') 13 exports["whatInput"] = factory(); 14 else 15 root["whatInput"] = factory(); 16})(this, function() { 17return /******/ (function(modules) { // webpackBootstrap 18/******/ // The module cache 19/******/ var installedModules = {}; 20 21/******/ // The require function 22/******/ function __webpack_require__(moduleId) { 23 24/******/ // Check if module is in cache 25/******/ if(installedModules[moduleId]) 26/******/ return installedModules[moduleId].exports; 27 28/******/ // Create a new module (and put it into the cache) 29/******/ var module = installedModules[moduleId] = { 30/******/ exports: {}, 31/******/ id: moduleId, 32/******/ loaded: false 33/******/ }; 34 35/******/ // Execute the module function 36/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 37 38/******/ // Flag the module as loaded 39/******/ module.loaded = true; 40 41/******/ // Return the exports of the module 42/******/ return module.exports; 43/******/ } 44 45 46/******/ // expose the modules object (__webpack_modules__) 47/******/ __webpack_require__.m = modules; 48 49/******/ // expose the module cache 50/******/ __webpack_require__.c = installedModules; 51 52/******/ // __webpack_public_path__ 53/******/ __webpack_require__.p = ""; 54 55/******/ // Load entry module and return exports 56/******/ return __webpack_require__(0); 57/******/ }) 58/************************************************************************/ 59/******/ ([ 60/* 0 */ 61/***/ (function(module, exports) { 62 63 'use strict'; 64 65 module.exports = function () { 66 /* 67 * bail out if there is no document or window 68 * (i.e. in a node/non-DOM environment) 69 * 70 * Return a stubbed API instead 71 */ 72 if (typeof document === 'undefined' || typeof window === 'undefined') { 73 return { 74 // always return "initial" because no interaction will ever be detected 75 ask: function ask() { 76 return 'initial'; 77 }, 78 79 // always return null 80 element: function element() { 81 return null; 82 }, 83 84 // no-op 85 ignoreKeys: function ignoreKeys() {}, 86 87 // no-op 88 specificKeys: function specificKeys() {}, 89 90 // no-op 91 registerOnChange: function registerOnChange() {}, 92 93 // no-op 94 unRegisterOnChange: function unRegisterOnChange() {} 95 }; 96 } 97 98 /* 99 * variables 100 */ 101 102 // cache document.documentElement 103 var docElem = document.documentElement; 104 105 // currently focused dom element 106 var currentElement = null; 107 108 // last used input type 109 var currentInput = 'initial'; 110 111 // last used input intent 112 var currentIntent = currentInput; 113 114 // UNIX timestamp of current event 115 var currentTimestamp = Date.now(); 116 117 // check for a `data-whatpersist` attribute on either the `html` or `body` elements, defaults to `true` 118 var shouldPersist = false; 119 120 // form input types 121 var formInputs = ['button', 'input', 'select', 'textarea']; 122 123 // empty array for holding callback functions 124 var functionList = []; 125 126 // list of modifier keys commonly used with the mouse and 127 // can be safely ignored to prevent false keyboard detection 128 var ignoreMap = [16, // shift 129 17, // control 130 18, // alt 131 91, // Windows key / left Apple cmd 132 93 // Windows menu / right Apple cmd 133 ]; 134 135 var specificMap = []; 136 137 // mapping of events to input types 138 var inputMap = { 139 keydown: 'keyboard', 140 keyup: 'keyboard', 141 mousedown: 'mouse', 142 mousemove: 'mouse', 143 MSPointerDown: 'pointer', 144 MSPointerMove: 'pointer', 145 pointerdown: 'pointer', 146 pointermove: 'pointer', 147 touchstart: 'touch', 148 touchend: 'touch' 149 150 // boolean: true if the page is being scrolled 151 };var isScrolling = false; 152 153 // store current mouse position 154 var mousePos = { 155 x: null, 156 y: null 157 158 // map of IE 10 pointer events 159 };var pointerMap = { 160 2: 'touch', 161 3: 'touch', // treat pen like touch 162 4: 'mouse' 163 164 // check support for passive event listeners 165 };var supportsPassive = false; 166 167 try { 168 var opts = Object.defineProperty({}, 'passive', { 169 get: function get() { 170 supportsPassive = true; 171 } 172 }); 173 174 window.addEventListener('test', null, opts); 175 } catch (e) {} 176 // fail silently 177 178 179 /* 180 * set up 181 */ 182 183 var setUp = function setUp() { 184 // add correct mouse wheel event mapping to `inputMap` 185 inputMap[detectWheel()] = 'mouse'; 186 187 addListeners(); 188 }; 189 190 /* 191 * events 192 */ 193 194 var addListeners = function addListeners() { 195 // `pointermove`, `MSPointerMove`, `mousemove` and mouse wheel event binding 196 // can only demonstrate potential, but not actual, interaction 197 // and are treated separately 198 var options = supportsPassive ? { passive: true, capture: true } : true; 199 200 document.addEventListener('DOMContentLoaded', setPersist, true); 201 202 // pointer events (mouse, pen, touch) 203 if (window.PointerEvent) { 204 window.addEventListener('pointerdown', setInput, true); 205 window.addEventListener('pointermove', setIntent, true); 206 } else if (window.MSPointerEvent) { 207 window.addEventListener('MSPointerDown', setInput, true); 208 window.addEventListener('MSPointerMove', setIntent, true); 209 } else { 210 // mouse events 211 window.addEventListener('mousedown', setInput, true); 212 window.addEventListener('mousemove', setIntent, true); 213 214 // touch events 215 if ('ontouchstart' in window) { 216 window.addEventListener('touchstart', setInput, options); 217 window.addEventListener('touchend', setInput, true); 218 } 219 } 220 221 // mouse wheel 222 window.addEventListener(detectWheel(), setIntent, options); 223 224 // keyboard events 225 window.addEventListener('keydown', setInput, true); 226 window.addEventListener('keyup', setInput, true); 227 228 // focus events 229 window.addEventListener('focusin', setElement, true); 230 window.addEventListener('focusout', clearElement, true); 231 }; 232 233 // checks if input persistence should happen and 234 // get saved state from session storage if true (defaults to `false`) 235 var setPersist = function setPersist() { 236 shouldPersist = !(docElem.getAttribute('data-whatpersist') === 'false' || document.body.getAttribute('data-whatpersist') === 'false'); 237 238 if (shouldPersist) { 239 // check for session variables and use if available 240 try { 241 if (window.sessionStorage.getItem('what-input')) { 242 currentInput = window.sessionStorage.getItem('what-input'); 243 } 244 245 if (window.sessionStorage.getItem('what-intent')) { 246 currentIntent = window.sessionStorage.getItem('what-intent'); 247 } 248 } catch (e) { 249 // fail silently 250 } 251 } 252 253 // always run these so at least `initial` state is set 254 doUpdate('input'); 255 doUpdate('intent'); 256 }; 257 258 // checks conditions before updating new input 259 var setInput = function setInput(event) { 260 var eventKey = event.which; 261 var value = inputMap[event.type]; 262 263 if (value === 'pointer') { 264 value = pointerType(event); 265 } 266 267 var ignoreMatch = !specificMap.length && ignoreMap.indexOf(eventKey) === -1; 268 269 var specificMatch = specificMap.length && specificMap.indexOf(eventKey) !== -1; 270 271 var shouldUpdate = value === 'keyboard' && eventKey && (ignoreMatch || specificMatch) || value === 'mouse' || value === 'touch'; 272 273 // prevent touch detection from being overridden by event execution order 274 if (validateTouch(value)) { 275 shouldUpdate = false; 276 } 277 278 if (shouldUpdate && currentInput !== value) { 279 currentInput = value; 280 281 persistInput('input', currentInput); 282 doUpdate('input'); 283 } 284 285 if (shouldUpdate && currentIntent !== value) { 286 // preserve intent for keyboard interaction with form fields 287 var activeElem = document.activeElement; 288 var notFormInput = activeElem && activeElem.nodeName && (formInputs.indexOf(activeElem.nodeName.toLowerCase()) === -1 || activeElem.nodeName.toLowerCase() === 'button' && !checkClosest(activeElem, 'form')); 289 290 if (notFormInput) { 291 currentIntent = value; 292 293 persistInput('intent', currentIntent); 294 doUpdate('intent'); 295 } 296 } 297 }; 298 299 // updates the doc and `inputTypes` array with new input 300 var doUpdate = function doUpdate(which) { 301 docElem.setAttribute('data-what' + which, which === 'input' ? currentInput : currentIntent); 302 303 fireFunctions(which); 304 }; 305 306 // updates input intent for `mousemove` and `pointermove` 307 var setIntent = function setIntent(event) { 308 var value = inputMap[event.type]; 309 310 if (value === 'pointer') { 311 value = pointerType(event); 312 } 313 314 // test to see if `mousemove` happened relative to the screen to detect scrolling versus mousemove 315 detectScrolling(event); 316 317 // only execute if scrolling isn't happening 318 if ((!isScrolling && !validateTouch(value) || isScrolling && event.type === 'wheel' || event.type === 'mousewheel' || event.type === 'DOMMouseScroll') && currentIntent !== value) { 319 currentIntent = value; 320 321 persistInput('intent', currentIntent); 322 doUpdate('intent'); 323 } 324 }; 325 326 var setElement = function setElement(event) { 327 if (!event.target.nodeName) { 328 // If nodeName is undefined, clear the element 329 // This can happen if click inside an <svg> element. 330 clearElement(); 331 return; 332 } 333 334 currentElement = event.target.nodeName.toLowerCase(); 335 docElem.setAttribute('data-whatelement', currentElement); 336 337 if (event.target.classList && event.target.classList.length) { 338 docElem.setAttribute('data-whatclasses', event.target.classList.toString().replace(' ', ',')); 339 } 340 }; 341 342 var clearElement = function clearElement() { 343 currentElement = null; 344 345 docElem.removeAttribute('data-whatelement'); 346 docElem.removeAttribute('data-whatclasses'); 347 }; 348 349 var persistInput = function persistInput(which, value) { 350 if (shouldPersist) { 351 try { 352 window.sessionStorage.setItem('what-' + which, value); 353 } catch (e) { 354 // fail silently 355 } 356 } 357 }; 358 359 /* 360 * utilities 361 */ 362 363 var pointerType = function pointerType(event) { 364 if (typeof event.pointerType === 'number') { 365 return pointerMap[event.pointerType]; 366 } else { 367 // treat pen like touch 368 return event.pointerType === 'pen' ? 'touch' : event.pointerType; 369 } 370 }; 371 372 // prevent touch detection from being overridden by event execution order 373 var validateTouch = function validateTouch(value) { 374 var timestamp = Date.now(); 375 376 var touchIsValid = value === 'mouse' && currentInput === 'touch' && timestamp - currentTimestamp < 200; 377 378 currentTimestamp = timestamp; 379 380 return touchIsValid; 381 }; 382 383 // detect version of mouse wheel event to use 384 // via https://developer.mozilla.org/en-US/docs/Web/API/Element/wheel_event 385 var detectWheel = function detectWheel() { 386 var wheelType = null; 387 388 // Modern browsers support "wheel" 389 if ('onwheel' in document.createElement('div')) { 390 wheelType = 'wheel'; 391 } else { 392 // Webkit and IE support at least "mousewheel" 393 // or assume that remaining browsers are older Firefox 394 wheelType = document.onmousewheel !== undefined ? 'mousewheel' : 'DOMMouseScroll'; 395 } 396 397 return wheelType; 398 }; 399 400 // runs callback functions 401 var fireFunctions = function fireFunctions(type) { 402 for (var i = 0, len = functionList.length; i < len; i++) { 403 if (functionList[i].type === type) { 404 functionList[i].fn.call(undefined, type === 'input' ? currentInput : currentIntent); 405 } 406 } 407 }; 408 409 // finds matching element in an object 410 var objPos = function objPos(match) { 411 for (var i = 0, len = functionList.length; i < len; i++) { 412 if (functionList[i].fn === match) { 413 return i; 414 } 415 } 416 }; 417 418 var detectScrolling = function detectScrolling(event) { 419 if (mousePos.x !== event.screenX || mousePos.y !== event.screenY) { 420 isScrolling = false; 421 422 mousePos.x = event.screenX; 423 mousePos.y = event.screenY; 424 } else { 425 isScrolling = true; 426 } 427 }; 428 429 // manual version of `closest()` 430 var checkClosest = function checkClosest(elem, tag) { 431 var ElementPrototype = window.Element.prototype; 432 433 if (!ElementPrototype.matches) { 434 ElementPrototype.matches = ElementPrototype.msMatchesSelector || ElementPrototype.webkitMatchesSelector; 435 } 436 437 if (!ElementPrototype.closest) { 438 do { 439 if (elem.matches(tag)) { 440 return elem; 441 } 442 443 elem = elem.parentElement || elem.parentNode; 444 } while (elem !== null && elem.nodeType === 1); 445 446 return null; 447 } else { 448 return elem.closest(tag); 449 } 450 }; 451 452 /* 453 * init 454 */ 455 456 // don't start script unless browser cuts the mustard 457 // (also passes if polyfills are used) 458 if ('addEventListener' in window && Array.prototype.indexOf) { 459 setUp(); 460 } 461 462 /* 463 * api 464 */ 465 466 return { 467 // returns string: the current input type 468 // opt: 'intent'|'input' 469 // 'input' (default): returns the same value as the `data-whatinput` attribute 470 // 'intent': includes `data-whatintent` value if it's different than `data-whatinput` 471 ask: function ask(opt) { 472 return opt === 'intent' ? currentIntent : currentInput; 473 }, 474 475 // returns string: the currently focused element or null 476 element: function element() { 477 return currentElement; 478 }, 479 480 // overwrites ignored keys with provided array 481 ignoreKeys: function ignoreKeys(arr) { 482 ignoreMap = arr; 483 }, 484 485 // overwrites specific char keys to update on 486 specificKeys: function specificKeys(arr) { 487 specificMap = arr; 488 }, 489 490 // attach functions to input and intent "events" 491 // funct: function to fire on change 492 // eventType: 'input'|'intent' 493 registerOnChange: function registerOnChange(fn, eventType) { 494 functionList.push({ 495 fn: fn, 496 type: eventType || 'input' 497 }); 498 }, 499 500 unRegisterOnChange: function unRegisterOnChange(fn) { 501 var position = objPos(fn); 502 503 if (position || position === 0) { 504 functionList.splice(position, 1); 505 } 506 }, 507 508 clearStorage: function clearStorage() { 509 window.sessionStorage.clear(); 510 } 511 }; 512 }(); 513 514/***/ }) 515/******/ ]) 516}); 517;
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.