PageSourceSearch

https://paijat-hame.fi/wp-content/themes/Divi-phliitto/js/focus-visible.js?ver=7.0.6

js paijat-hame.fi collected 2026-10-02 04:19:13 UTC 11,622 bytes, 304 lines download raw bytes

vendor: 11,622 bytes, lines 1-304
1/**
2 * Applies the :focus-visible polyfill at the given scope.
3 * A scope in this case is either the top-level Document or a Shadow Root.
4 *
5 * @param {(Document|ShadowRoot)} scope
6 * @see https://github.com/WICG/focus-visible
7 */
8function applyFocusVisiblePolyfill(scope) {
9    var hadKeyboardEvent = true;
10    var hadFocusVisibleRecently = false;
11    var hadFocusVisibleRecentlyTimeout = null;
12  
13    var inputTypesAllowlist = {
14      text: true,
15      search: true,
16      url: true,
17      tel: true,
18      email: true,
19      password: true,
20      number: true,
21      date: true,
22      month: true,
23      week: true,
24      time: true,
25      datetime: true,
26      'datetime-local': true
27    };
28  
29    /**
30     * Helper function for legacy browsers and iframes which sometimes focus
31     * elements like document, body, and non-interactive SVG.
32     * @param {Element} el
33     */
34    function isValidFocusTarget(el) {
35      if (
36        el &&
37        el !== document &&
38        el.nodeName !== 'HTML' &&
39        el.nodeName !== 'BODY' &&
40        'classList' in el &&
41        'contains' in el.classList
42      ) {
43        return true;
44      }
45      return false;
46    }
47  
48    /**
49     * Computes whether the given element should automatically trigger the
50     * `focus-visible` class being added, i.e. whether it should always match
51     * `:focus-visible` when focused.
52     * @param {Element} el
53     * @return {boolean}
54     */
55    function focusTriggersKeyboardModality(el) {
56      var type = el.type;
57      var tagName = el.tagName;
58  
59      if (tagName === 'INPUT' && inputTypesAllowlist[type] && !el.readOnly) {
60        return true;
61      }
62  
63      if (tagName === 'TEXTAREA' && !el.readOnly) {
64        return true;
65      }
66  
67      if (el.isContentEditable) {
68        return true;
69      }
70  
71      return false;
72    }
73  
74    /**
75     * Add the `focus-visible` class to the given element if it was not added by
76     * the author.
77     * @param {Element} el
78     */
79    function addFocusVisibleClass(el) {
80      if (el.classList.contains('focus-visible')) {
81        return;
82      }
83      el.classList.add('focus-visible');
84      el.setAttribute('data-focus-visible-added', '');
85    }
86  
87    /**
88     * Remove the `focus-visible` class from the given element if it was not
89     * originally added by the author.
90     * @param {Element} el
91     */
92    function removeFocusVisibleClass(el) {
93      if (!el.hasAttribute('data-focus-visible-added')) {
94        return;
95      }
96      el.classList.remove('focus-visible');
97      el.removeAttribute('data-focus-visible-added');
98    }
99  
100    /**
101     * If the most recent user interaction was via the keyboard;
102     * and the key press did not include a meta, alt/option, or control key;
103     * then the modality is keyboard. Otherwise, the modality is not keyboard.
104     * Apply `focus-visible` to any current active element and keep track
105     * of our keyboard modality state with `hadKeyboardEvent`.
106     * @param {KeyboardEvent} e
107     */
108    function onKeyDown(e) {
109      if (e.metaKey || e.altKey || e.ctrlKey) {
110        return;
111      }
112  
113      if (isValidFocusTarget(scope.activeElement)) {
114        addFocusVisibleClass(scope.activeElement);
115      }
116  
117      hadKeyboardEvent = true;
118    }
119  
120    /**
121     * If at any point a user clicks with a pointing device, ensure that we change
122     * the modality away from keyboard.
123     * This avoids the situation where a user presses a key on an already focused
124     * element, and then clicks on a different element, focusing it with a
125     * pointing device, while we still think we're in keyboard modality.
126     * @param {Event} e
127     */
128    function onPointerDown(e) {
129      hadKeyboardEvent = false;
130    }
131  
132    /**
133     * On `focus`, add the `focus-visible` class to the target if:
134     * - the target received focus as a result of keyboard navigation, or
135     * - the event target is an element that will likely require interaction
136     *   via the keyboard (e.g. a text box)
137     * @param {Event} e
138     */
139    function onFocus(e) {
140      // Prevent IE from focusing the document or HTML element.
141      if (!isValidFocusTarget(e.target)) {
142        return;
143      }
144  
145      if (hadKeyboardEvent || focusTriggersKeyboardModality(e.target)) {
146        addFocusVisibleClass(e.target);
147      }
148    }
149  
150    /**
151     * On `blur`, remove the `focus-visible` class from the target.
152     * @param {Event} e
153     */
154    function onBlur(e) {
155      if (!isValidFocusTarget(e.target)) {
156        return;
157      }
158  
159      if (
160        e.target.classList.contains('focus-visible') ||
161        e.target.hasAttribute('data-focus-visible-added')
162      ) {
163        // To detect a tab/window switch, we look for a blur event followed
164        // rapidly by a visibility change.
165        // If we don't see a visibility change within 100ms, it's probably a
166        // regular focus change.
167        hadFocusVisibleRecently = true;
168        window.clearTimeout(hadFocusVisibleRecentlyTimeout);
169        hadFocusVisibleRecentlyTimeout = window.setTimeout(function() {
170          hadFocusVisibleRecently = false;
171        }, 100);
172        removeFocusVisibleClass(e.target);
173      }
174    }
175  
176    /**
177     * If the user changes tabs, keep track of whether or not the previously
178     * focused element had .focus-visible.
179     * @param {Event} e
180     */
181    function onVisibilityChange(e) {
182      if (document.visibilityState === 'hidden') {
183        // If the tab becomes active again, the browser will handle calling focus
184        // on the element (Safari actually calls it twice).
185        // If this tab change caused a blur on an element with focus-visible,
186        // re-apply the class when the user switches back to the tab.
187        if (hadFocusVisibleRecently) {
188          hadKeyboardEvent = true;
189        }
190        addInitialPointerMoveListeners();
191      }
192    }
193  
194    /**
195     * Add a group of listeners to detect usage of any pointing devices.
196     * These listeners will be added when the polyfill first loads, and anytime
197     * the window is blurred, so that they are active when the window regains
198     * focus.
199     */
200    function addInitialPointerMoveListeners() {
201      document.addEventListener('mousemove', onInitialPointerMove);
202      document.addEventListener('mousedown', onInitialPointerMove);
203      document.addEventListener('mouseup', onInitialPointerMove);
204      document.addEventListener('pointermove', onInitialPointerMove);
205      document.addEventListener('pointerdown', onInitialPointerMove);
206      document.addEventListener('pointerup', onInitialPointerMove);
207      document.addEventListener('touchmove', onInitialPointerMove);
208      document.addEventListener('touchstart', onInitialPointerMove);
209      document.addEventListener('touchend', onInitialPointerMove);
210    }
211  
212    function removeInitialPointerMoveListeners() {
213      document.removeEventListener('mousemove', onInitialPointerMove);
214      document.removeEventListener('mousedown', onInitialPointerMove);
215      document.removeEventListener('mouseup', onInitialPointerMove);
216      document.removeEventListener('pointermove', onInitialPointerMove);
217      document.removeEventListener('pointerdown', onInitialPointerMove);
218      document.removeEventListener('pointerup', onInitialPointerMove);
219      document.removeEventListener('touchmove', onInitialPointerMove);
220      document.removeEventListener('touchstart', onInitialPointerMove);
221      document.removeEventListener('touchend', onInitialPointerMove);
222    }
223  
224    /**
225     * When the polfyill first loads, assume the user is in keyboard modality.
226     * If any event is received from a pointing device (e.g. mouse, pointer,
227     * touch), turn off keyboard modality.
228     * This accounts for situations where focus enters the page from the URL bar.
229     * @param {Event} e
230     */
231    function onInitialPointerMove(e) {
232      // Work around a Safari quirk that fires a mousemove on <html> whenever the
233      // window blurs, even if you're tabbing out of the page. ¯\_(ツ)_/¯
234      if (e.target.nodeName && e.target.nodeName.toLowerCase() === 'html') {
235        return;
236      }
237  
238      hadKeyboardEvent = false;
239      removeInitialPointerMoveListeners();
240    }
241  
242    // For some kinds of state, we are interested in changes at the global scope
243    // only. For example, global pointer input, global key presses and global
244    // visibility change should affect the state at every scope:
245    document.addEventListener('keydown', onKeyDown, true);
246    document.addEventListener('mousedown', onPointerDown, true);
247    document.addEventListener('pointerdown', onPointerDown, true);
248    document.addEventListener('touchstart', onPointerDown, true);
249    document.addEventListener('visibilitychange', onVisibilityChange, true);
250  
251    addInitialPointerMoveListeners();
252  
253    // For focus and blur, we specifically care about state changes in the local
254    // scope. This is because focus / blur events that originate from within a
255    // shadow root are not re-dispatched from the host element if it was already
256    // the active element in its own scope:
257    scope.addEventListener('focus', onFocus, true);
258    scope.addEventListener('blur', onBlur, true);
259  
260    // We detect that a node is a ShadowRoot by ensuring that it is a
261    // DocumentFragment and also has a host property. This check covers native
262    // implementation and polyfill implementation transparently. If we only cared
263    // about the native implementation, we could just check if the scope was
264    // an instance of a ShadowRoot.
265    if (scope.nodeType === Node.DOCUMENT_FRAGMENT_NODE && scope.host) {
266      // Since a ShadowRoot is a special kind of DocumentFragment, it does not
267      // have a root element to add a class to. So, we add this attribute to the
268      // host element instead:
269      scope.host.setAttribute('data-js-focus-visible', '');
270    } else if (scope.nodeType === Node.DOCUMENT_NODE) {
271      document.documentElement.classList.add('js-focus-visible');
272      document.documentElement.setAttribute('data-js-focus-visible', '');
273    }
274  }
275  
276  // It is important to wrap all references to global window and document in
277  // these checks to support server-side rendering use cases
278  // @see https://github.com/WICG/focus-visible/issues/199
279  if (typeof window !== 'undefined' && typeof document !== 'undefined') {
280    // Make the polyfill helper globally available. This can be used as a signal
281    // to interested libraries that wish to coordinate with the polyfill for e.g.,
282    // applying the polyfill to a shadow root:
283    window.applyFocusVisiblePolyfill = applyFocusVisiblePolyfill;
284  
285    // Notify interested libraries of the polyfill's presence, in case the
286    // polyfill was loaded lazily:
287    var event;
288  
289    try {
290      event = new CustomEvent('focus-visible-polyfill-ready');
291    } catch (error) {
292      // IE11 does not support using CustomEvent as a constructor directly:
293      event = document.createEvent('CustomEvent');
294      event.initCustomEvent('focus-visible-polyfill-ready', false, false, {});
295    }
296  
297    window.dispatchEvent(event);
298  }
299  
300  if (typeof document !== 'undefined') {
301    // Apply the polyfill to the global document, so that no JavaScript
302    // coordination is required to use the polyfill in the top-level document:
303    applyFocusVisiblePolyfill(document);
304  }

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.