1 | 'use strict';
|
2 |
|
3 | const ION_FOCUSED = 'ion-focused';
|
4 | const ION_FOCUSABLE = 'ion-focusable';
|
5 | const FOCUS_KEYS = ['Tab', 'ArrowDown', 'Space', 'Escape', ' ', 'Shift', 'Enter', 'ArrowLeft', 'ArrowRight', 'ArrowUp'];
|
6 | const startFocusVisible = () => {
|
7 | let currentFocus = [];
|
8 | let keyboardMode = true;
|
9 | const doc = document;
|
10 | const setFocus = (elements) => {
|
11 | currentFocus.forEach(el => el.classList.remove(ION_FOCUSED));
|
12 | elements.forEach(el => el.classList.add(ION_FOCUSED));
|
13 | currentFocus = elements;
|
14 | };
|
15 | const pointerDown = () => {
|
16 | keyboardMode = false;
|
17 | setFocus([]);
|
18 | };
|
19 | doc.addEventListener('keydown', ev => {
|
20 | keyboardMode = FOCUS_KEYS.includes(ev.key);
|
21 | if (!keyboardMode) {
|
22 | setFocus([]);
|
23 | }
|
24 | });
|
25 | doc.addEventListener('focusin', ev => {
|
26 | if (keyboardMode && ev.composedPath) {
|
27 | const toFocus = ev.composedPath().filter((el) => {
|
28 | if (el.classList) {
|
29 | return el.classList.contains(ION_FOCUSABLE);
|
30 | }
|
31 | return false;
|
32 | });
|
33 | setFocus(toFocus);
|
34 | }
|
35 | });
|
36 | doc.addEventListener('focusout', () => {
|
37 | if (doc.activeElement === doc.body) {
|
38 | setFocus([]);
|
39 | }
|
40 | });
|
41 | doc.addEventListener('touchstart', pointerDown);
|
42 | doc.addEventListener('mousedown', pointerDown);
|
43 | };
|
44 |
|
45 | exports.startFocusVisible = startFocusVisible;
|