-
-
Notifications
You must be signed in to change notification settings - Fork 75
/
Copy pathbrowser.js
81 lines (66 loc) · 2.14 KB
/
browser.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import isValidReplacement from './is-valid-replacement.mjs';
function generateHandler(replaceWith) {
let selector;
let remove;
let add;
const lastElements = [];
if (replaceWith[0] === '.') {
selector = replaceWith.slice(1);
remove = (el) => el.classList.remove(selector);
add = (el) => el.classList.add(selector);
} else {
// A bit naive
selector = replaceWith.slice(1, -1);
remove = (el) => el.removeAttribute(selector, '');
add = (el) => el.setAttribute(selector, '');
}
return function handleFocusChange() {
lastElements.forEach(lastElement => remove(lastElement));
lastElements.length = 0;
let activeElement = document.activeElement;
// only add focus if it has not been added and is not the document element
if (!/^(#document|HTML|BODY)$/.test(Object(activeElement).nodeName)) {
while (activeElement && activeElement.nodeType === 1) {
add(activeElement);
lastElements.push(activeElement);
activeElement = activeElement.parentNode;
}
}
};
}
export default function focusWithin(opts) {
// configuration
const options = {
force: false,
replaceWith: '[focus-within]',
};
if (typeof opts !== 'undefined' && 'force' in opts) {
options.force = opts.force;
}
if (typeof opts !== 'undefined' && 'replaceWith' in opts) {
options.replaceWith = opts.replaceWith;
}
if (!isValidReplacement(options.replaceWith)) {
throw new Error(`${options.replaceWith} is not a valid replacement since it can't be applied to single elements.`);
}
try {
document.querySelector(':focus-within');
if (!options.force) {
return;
}
} catch (_) {}
const handleFocusChange = generateHandler(options.replaceWith);
const initialize = function initializeEventListeners() {
if (document.documentElement.className.indexOf('js-focus-within') > -1) {
return;
}
document.documentElement.className = document.documentElement.className + ' js-focus-within';
document.addEventListener('focus', handleFocusChange, true);
document.addEventListener('blur', handleFocusChange, true);
};
if (document.readyState === 'complete') {
initialize();
} else {
document.addEventListener('DOMContentLoaded', initialize);
}
}