PageSourceSearch

https://www.usna.edu/CMS/_standard4.0/assets/js/vendor/what-input.js

js usna.edu collected 2026-09-24 08:41:22 UTC 14,907 bytes, 517 lines download raw bytes

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.