@oscarpalmer/atoms 0.42.0 → 0.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/js/array.js +56 -56
- package/dist/js/array.mjs +56 -56
- package/dist/js/element/focusable.js +36 -36
- package/dist/js/element/focusable.mjs +36 -36
- package/dist/js/element/index.js +88 -6
- package/dist/js/element/index.mjs +64 -6
- package/dist/js/index.js +416 -245
- package/dist/js/index.mjs +2 -0
- package/dist/js/log.js +65 -0
- package/dist/js/log.mjs +65 -0
- package/dist/js/math.js +19 -0
- package/dist/js/math.mjs +19 -0
- package/dist/js/string.js +43 -2
- package/dist/js/string.mjs +39 -2
- package/dist/js/value.js +93 -77
- package/dist/js/value.mjs +75 -77
- package/package.json +1 -1
- package/src/js/array.ts +149 -149
- package/src/js/element/focusable.ts +52 -53
- package/src/js/element/index.ts +174 -14
- package/src/js/index.ts +2 -0
- package/src/js/is.ts +3 -0
- package/src/js/log.ts +146 -0
- package/src/js/math.ts +27 -0
- package/src/js/string.ts +98 -4
- package/src/js/timer.ts +16 -9
- package/src/js/value.ts +130 -133
- package/types/element/index.d.ts +25 -0
- package/types/index.d.ts +2 -0
- package/types/is.d.ts +3 -0
- package/types/log.d.ts +60 -0
- package/types/math.d.ts +16 -0
- package/types/string.d.ts +27 -0
- package/types/timer.d.ts +7 -0
package/dist/js/array.js
CHANGED
|
@@ -1,21 +1,29 @@
|
|
|
1
1
|
// src/js/array.ts
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
return { key };
|
|
2
|
+
function chunk(array, size) {
|
|
3
|
+
const { length } = array;
|
|
4
|
+
const chunkSize = typeof size === "number" && size > 0 ? size : 32000;
|
|
5
|
+
if (length <= chunkSize) {
|
|
6
|
+
return [array];
|
|
8
7
|
}
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
const chunks = [];
|
|
9
|
+
let remaining = Number(length);
|
|
10
|
+
while (remaining > 0) {
|
|
11
|
+
chunks.push(array.splice(0, chunkSize));
|
|
12
|
+
remaining -= chunkSize;
|
|
12
13
|
}
|
|
13
|
-
return
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
return chunks;
|
|
15
|
+
}
|
|
16
|
+
function exists(array, value, key) {
|
|
17
|
+
return findValue("index", array, value, key) > -1;
|
|
18
|
+
}
|
|
19
|
+
function filter(array, value, key) {
|
|
20
|
+
return findValues("all", array, value, key);
|
|
21
|
+
}
|
|
22
|
+
function find(array, value, key) {
|
|
23
|
+
return findValue("value", array, value, key);
|
|
24
|
+
}
|
|
25
|
+
var findValue = function(type, array, value, key) {
|
|
26
|
+
const callbacks = getCallbacks(value, key);
|
|
19
27
|
if (callbacks?.bool == null && callbacks?.key == null) {
|
|
20
28
|
return type === "index" ? array.indexOf(value) : array.find((item) => item === value);
|
|
21
29
|
}
|
|
@@ -33,8 +41,8 @@ var _findValue = function(type, array, value, key) {
|
|
|
33
41
|
}
|
|
34
42
|
return type === "index" ? -1 : undefined;
|
|
35
43
|
};
|
|
36
|
-
var
|
|
37
|
-
const callbacks =
|
|
44
|
+
var findValues = function(type, array, value, key) {
|
|
45
|
+
const callbacks = getCallbacks(value, key);
|
|
38
46
|
const { length } = array;
|
|
39
47
|
if (type === "unique" && callbacks?.key == null && length >= 100) {
|
|
40
48
|
return Array.from(new Set(array));
|
|
@@ -61,44 +69,23 @@ var _findValues = function(type, array, value, key) {
|
|
|
61
69
|
}
|
|
62
70
|
return result;
|
|
63
71
|
};
|
|
64
|
-
var
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
let index = 0;
|
|
68
|
-
let returned;
|
|
69
|
-
for (;index < length; index += 1) {
|
|
70
|
-
const result = array.splice(start, index === 0 ? deleteCount : 0, ...chunked[index]);
|
|
71
|
-
if (returned == null) {
|
|
72
|
-
returned = result;
|
|
73
|
-
}
|
|
72
|
+
var getCallbacks = function(bool, key) {
|
|
73
|
+
if (typeof bool === "function") {
|
|
74
|
+
return { bool };
|
|
74
75
|
}
|
|
75
|
-
|
|
76
|
-
};
|
|
77
|
-
function chunk(array, size) {
|
|
78
|
-
const { length } = array;
|
|
79
|
-
const chunkSize = typeof size === "number" && size > 0 ? size : 32000;
|
|
80
|
-
if (length <= chunkSize) {
|
|
81
|
-
return [array];
|
|
76
|
+
if (typeof key === "function") {
|
|
77
|
+
return { key };
|
|
82
78
|
}
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
chunks.push(array.splice(0, chunkSize));
|
|
87
|
-
remaining -= chunkSize;
|
|
79
|
+
const isString = typeof key === "string";
|
|
80
|
+
if (!isString && typeof key !== "number" || isString && key.includes(".")) {
|
|
81
|
+
return;
|
|
88
82
|
}
|
|
89
|
-
return
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
function filter(array, value, key) {
|
|
95
|
-
return _findValues("all", array, value, key);
|
|
96
|
-
}
|
|
97
|
-
function find(array, value, key) {
|
|
98
|
-
return _findValue("value", array, value, key);
|
|
99
|
-
}
|
|
83
|
+
return {
|
|
84
|
+
key: (value) => value?.[key]
|
|
85
|
+
};
|
|
86
|
+
};
|
|
100
87
|
function groupBy(array, key) {
|
|
101
|
-
const callbacks =
|
|
88
|
+
const callbacks = getCallbacks(undefined, key);
|
|
102
89
|
if (callbacks?.key == null) {
|
|
103
90
|
return {};
|
|
104
91
|
}
|
|
@@ -117,20 +104,33 @@ function groupBy(array, key) {
|
|
|
117
104
|
return grouped;
|
|
118
105
|
}
|
|
119
106
|
function indexOf(array, value, key) {
|
|
120
|
-
return
|
|
107
|
+
return findValue("index", array, value, key);
|
|
121
108
|
}
|
|
122
109
|
function insert(array, index, values) {
|
|
123
|
-
|
|
110
|
+
insertValues("splice", array, values, index, 0);
|
|
124
111
|
}
|
|
112
|
+
var insertValues = function(type, array, values, start, deleteCount) {
|
|
113
|
+
const chunked = chunk(values).reverse();
|
|
114
|
+
const { length } = chunked;
|
|
115
|
+
let index = 0;
|
|
116
|
+
let returned;
|
|
117
|
+
for (;index < length; index += 1) {
|
|
118
|
+
const result = array.splice(start, index === 0 ? deleteCount : 0, ...chunked[index]);
|
|
119
|
+
if (returned == null) {
|
|
120
|
+
returned = result;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return type === "splice" ? returned : array.length;
|
|
124
|
+
};
|
|
125
125
|
function push(array, values) {
|
|
126
|
-
return
|
|
126
|
+
return insertValues("push", array, values, array.length, 0);
|
|
127
127
|
}
|
|
128
128
|
function splice(array, start, amountOrValues, values) {
|
|
129
129
|
const amoutOrValuesIsArray = Array.isArray(amountOrValues);
|
|
130
|
-
return
|
|
130
|
+
return insertValues("splice", array, amoutOrValuesIsArray ? amountOrValues : values ?? [], start, amoutOrValuesIsArray ? array.length : typeof amountOrValues === "number" && amountOrValues > 0 ? amountOrValues : 0);
|
|
131
131
|
}
|
|
132
132
|
function unique(array, key) {
|
|
133
|
-
return
|
|
133
|
+
return findValues("unique", array, undefined, key);
|
|
134
134
|
}
|
|
135
135
|
export {
|
|
136
136
|
unique,
|
package/dist/js/array.mjs
CHANGED
|
@@ -1,21 +1,29 @@
|
|
|
1
1
|
// src/js/array.ts
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
return { key };
|
|
2
|
+
function chunk(array, size) {
|
|
3
|
+
const { length } = array;
|
|
4
|
+
const chunkSize = typeof size === "number" && size > 0 ? size : 32000;
|
|
5
|
+
if (length <= chunkSize) {
|
|
6
|
+
return [array];
|
|
8
7
|
}
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
const chunks = [];
|
|
9
|
+
let remaining = Number(length);
|
|
10
|
+
while (remaining > 0) {
|
|
11
|
+
chunks.push(array.splice(0, chunkSize));
|
|
12
|
+
remaining -= chunkSize;
|
|
12
13
|
}
|
|
13
|
-
return
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
return chunks;
|
|
15
|
+
}
|
|
16
|
+
function exists(array, value, key) {
|
|
17
|
+
return findValue("index", array, value, key) > -1;
|
|
18
|
+
}
|
|
19
|
+
function filter(array, value, key) {
|
|
20
|
+
return findValues("all", array, value, key);
|
|
21
|
+
}
|
|
22
|
+
function find(array, value, key) {
|
|
23
|
+
return findValue("value", array, value, key);
|
|
24
|
+
}
|
|
25
|
+
var findValue = function(type, array, value, key) {
|
|
26
|
+
const callbacks = getCallbacks(value, key);
|
|
19
27
|
if (callbacks?.bool == null && callbacks?.key == null) {
|
|
20
28
|
return type === "index" ? array.indexOf(value) : array.find((item) => item === value);
|
|
21
29
|
}
|
|
@@ -33,8 +41,8 @@ var _findValue = function(type, array, value, key) {
|
|
|
33
41
|
}
|
|
34
42
|
return type === "index" ? -1 : undefined;
|
|
35
43
|
};
|
|
36
|
-
var
|
|
37
|
-
const callbacks =
|
|
44
|
+
var findValues = function(type, array, value, key) {
|
|
45
|
+
const callbacks = getCallbacks(value, key);
|
|
38
46
|
const { length } = array;
|
|
39
47
|
if (type === "unique" && callbacks?.key == null && length >= 100) {
|
|
40
48
|
return Array.from(new Set(array));
|
|
@@ -61,44 +69,23 @@ var _findValues = function(type, array, value, key) {
|
|
|
61
69
|
}
|
|
62
70
|
return result;
|
|
63
71
|
};
|
|
64
|
-
var
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
let index = 0;
|
|
68
|
-
let returned;
|
|
69
|
-
for (;index < length; index += 1) {
|
|
70
|
-
const result = array.splice(start, index === 0 ? deleteCount : 0, ...chunked[index]);
|
|
71
|
-
if (returned == null) {
|
|
72
|
-
returned = result;
|
|
73
|
-
}
|
|
72
|
+
var getCallbacks = function(bool, key) {
|
|
73
|
+
if (typeof bool === "function") {
|
|
74
|
+
return { bool };
|
|
74
75
|
}
|
|
75
|
-
|
|
76
|
-
};
|
|
77
|
-
function chunk(array, size) {
|
|
78
|
-
const { length } = array;
|
|
79
|
-
const chunkSize = typeof size === "number" && size > 0 ? size : 32000;
|
|
80
|
-
if (length <= chunkSize) {
|
|
81
|
-
return [array];
|
|
76
|
+
if (typeof key === "function") {
|
|
77
|
+
return { key };
|
|
82
78
|
}
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
chunks.push(array.splice(0, chunkSize));
|
|
87
|
-
remaining -= chunkSize;
|
|
79
|
+
const isString = typeof key === "string";
|
|
80
|
+
if (!isString && typeof key !== "number" || isString && key.includes(".")) {
|
|
81
|
+
return;
|
|
88
82
|
}
|
|
89
|
-
return
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
function filter(array, value, key) {
|
|
95
|
-
return _findValues("all", array, value, key);
|
|
96
|
-
}
|
|
97
|
-
function find(array, value, key) {
|
|
98
|
-
return _findValue("value", array, value, key);
|
|
99
|
-
}
|
|
83
|
+
return {
|
|
84
|
+
key: (value) => value?.[key]
|
|
85
|
+
};
|
|
86
|
+
};
|
|
100
87
|
function groupBy(array, key) {
|
|
101
|
-
const callbacks =
|
|
88
|
+
const callbacks = getCallbacks(undefined, key);
|
|
102
89
|
if (callbacks?.key == null) {
|
|
103
90
|
return {};
|
|
104
91
|
}
|
|
@@ -117,20 +104,33 @@ function groupBy(array, key) {
|
|
|
117
104
|
return grouped;
|
|
118
105
|
}
|
|
119
106
|
function indexOf(array, value, key) {
|
|
120
|
-
return
|
|
107
|
+
return findValue("index", array, value, key);
|
|
121
108
|
}
|
|
122
109
|
function insert(array, index, values) {
|
|
123
|
-
|
|
110
|
+
insertValues("splice", array, values, index, 0);
|
|
124
111
|
}
|
|
112
|
+
var insertValues = function(type, array, values, start, deleteCount) {
|
|
113
|
+
const chunked = chunk(values).reverse();
|
|
114
|
+
const { length } = chunked;
|
|
115
|
+
let index = 0;
|
|
116
|
+
let returned;
|
|
117
|
+
for (;index < length; index += 1) {
|
|
118
|
+
const result = array.splice(start, index === 0 ? deleteCount : 0, ...chunked[index]);
|
|
119
|
+
if (returned == null) {
|
|
120
|
+
returned = result;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return type === "splice" ? returned : array.length;
|
|
124
|
+
};
|
|
125
125
|
function push(array, values) {
|
|
126
|
-
return
|
|
126
|
+
return insertValues("push", array, values, array.length, 0);
|
|
127
127
|
}
|
|
128
128
|
function splice(array, start, amountOrValues, values) {
|
|
129
129
|
const amoutOrValuesIsArray = Array.isArray(amountOrValues);
|
|
130
|
-
return
|
|
130
|
+
return insertValues("splice", array, amoutOrValuesIsArray ? amountOrValues : values ?? [], start, amoutOrValuesIsArray ? array.length : typeof amountOrValues === "number" && amountOrValues > 0 ? amountOrValues : 0);
|
|
131
131
|
}
|
|
132
132
|
function unique(array, key) {
|
|
133
|
-
return
|
|
133
|
+
return findValues("unique", array, undefined, key);
|
|
134
134
|
}
|
|
135
135
|
export {
|
|
136
136
|
unique,
|
|
@@ -1,25 +1,31 @@
|
|
|
1
1
|
// src/js/element/focusable.ts
|
|
2
|
-
|
|
2
|
+
function getFocusableElements(parent) {
|
|
3
|
+
return getValidElements(parent, getFocusableFilters(), false);
|
|
4
|
+
}
|
|
5
|
+
var getFocusableFilters = function() {
|
|
6
|
+
return [isDisabled, isInert, isHidden, isSummarised];
|
|
7
|
+
};
|
|
8
|
+
var getItem = function(element, tabbable) {
|
|
3
9
|
return {
|
|
4
10
|
element,
|
|
5
|
-
tabIndex: tabbable ?
|
|
11
|
+
tabIndex: tabbable ? getTabIndex(element) : -1
|
|
6
12
|
};
|
|
7
13
|
};
|
|
8
|
-
var
|
|
9
|
-
return [
|
|
14
|
+
var getTabbableFilters = function() {
|
|
15
|
+
return [isNotTabbable, isNotTabbableRadio, ...getFocusableFilters()];
|
|
10
16
|
};
|
|
11
|
-
|
|
12
|
-
return
|
|
13
|
-
}
|
|
14
|
-
var
|
|
17
|
+
function getTabbableElements(parent) {
|
|
18
|
+
return getValidElements(parent, getTabbableFilters(), true);
|
|
19
|
+
}
|
|
20
|
+
var getTabIndex = function(element) {
|
|
15
21
|
const tabIndex = element?.tabIndex ?? -1;
|
|
16
|
-
if (tabIndex < 0 && (/^(audio|details|video)$/i.test(element.tagName) ||
|
|
22
|
+
if (tabIndex < 0 && (/^(audio|details|video)$/i.test(element.tagName) || isEditable(element)) && !hasTabIndex(element)) {
|
|
17
23
|
return 0;
|
|
18
24
|
}
|
|
19
25
|
return tabIndex;
|
|
20
26
|
};
|
|
21
|
-
var
|
|
22
|
-
const items = Array.from(parent.querySelectorAll(selector)).map((element) =>
|
|
27
|
+
var getValidElements = function(parent, filters, tabbable) {
|
|
28
|
+
const items = Array.from(parent.querySelectorAll(selector)).map((element) => getItem(element, tabbable)).filter((item) => !filters.some((filter) => filter(item)));
|
|
23
29
|
if (!tabbable) {
|
|
24
30
|
return items.map((item) => item.element);
|
|
25
31
|
}
|
|
@@ -40,16 +46,16 @@ var _getValidElements = function(parent, filters, tabbable) {
|
|
|
40
46
|
}
|
|
41
47
|
return [...indiced.flat(), ...zeroed];
|
|
42
48
|
};
|
|
43
|
-
var
|
|
49
|
+
var hasTabIndex = function(element) {
|
|
44
50
|
return !Number.isNaN(Number.parseInt(element.getAttribute("tabindex"), 10));
|
|
45
51
|
};
|
|
46
|
-
var
|
|
47
|
-
if (/^(button|input|select|textarea)$/i.test(item.element.tagName) &&
|
|
52
|
+
var isDisabled = function(item) {
|
|
53
|
+
if (/^(button|input|select|textarea)$/i.test(item.element.tagName) && isDisabledFromFieldset(item.element)) {
|
|
48
54
|
return true;
|
|
49
55
|
}
|
|
50
56
|
return (item.element.disabled ?? false) || item.element.getAttribute("aria-disabled") === "true";
|
|
51
57
|
};
|
|
52
|
-
var
|
|
58
|
+
var isDisabledFromFieldset = function(element) {
|
|
53
59
|
let parent = element.parentElement;
|
|
54
60
|
while (parent !== null) {
|
|
55
61
|
if (parent instanceof HTMLFieldSetElement && parent.disabled) {
|
|
@@ -68,10 +74,13 @@ var _isDisabledFromFieldset = function(element) {
|
|
|
68
74
|
}
|
|
69
75
|
return false;
|
|
70
76
|
};
|
|
71
|
-
var
|
|
77
|
+
var isEditable = function(element) {
|
|
72
78
|
return /^(|true)$/i.test(element.getAttribute("contenteditable"));
|
|
73
79
|
};
|
|
74
|
-
|
|
80
|
+
function isFocusableElement(element) {
|
|
81
|
+
return isValidElement(element, getFocusableFilters(), false);
|
|
82
|
+
}
|
|
83
|
+
var isHidden = function(item) {
|
|
75
84
|
if ((item.element.hidden ?? false) || item.element instanceof HTMLInputElement && item.element.type === "hidden") {
|
|
76
85
|
return true;
|
|
77
86
|
}
|
|
@@ -87,16 +96,16 @@ var _isHidden = function(item) {
|
|
|
87
96
|
const { height, width } = item.element.getBoundingClientRect();
|
|
88
97
|
return height === 0 && width === 0;
|
|
89
98
|
};
|
|
90
|
-
var
|
|
91
|
-
return (item.element.inert ?? false) || /^(|true)$/i.test(item.element.getAttribute("inert")) || item.element.parentElement !== null &&
|
|
99
|
+
var isInert = function(item) {
|
|
100
|
+
return (item.element.inert ?? false) || /^(|true)$/i.test(item.element.getAttribute("inert")) || item.element.parentElement !== null && isInert({
|
|
92
101
|
element: item.element.parentElement,
|
|
93
102
|
tabIndex: -1
|
|
94
103
|
});
|
|
95
104
|
};
|
|
96
|
-
var
|
|
105
|
+
var isNotTabbable = function(item) {
|
|
97
106
|
return (item.tabIndex ?? -1) < 0;
|
|
98
107
|
};
|
|
99
|
-
var
|
|
108
|
+
var isNotTabbableRadio = function(item) {
|
|
100
109
|
if (!(item.element instanceof HTMLInputElement) || item.element.type !== "radio" || !item.element.name || item.element.checked) {
|
|
101
110
|
return false;
|
|
102
111
|
}
|
|
@@ -106,25 +115,16 @@ var _isNotTabbableRadio = function(item) {
|
|
|
106
115
|
const checked = radios.find((radio) => radio.checked);
|
|
107
116
|
return checked !== undefined && checked !== item.element;
|
|
108
117
|
};
|
|
109
|
-
var
|
|
118
|
+
var isSummarised = function(item) {
|
|
110
119
|
return item.element instanceof HTMLDetailsElement && Array.from(item.element.children).some((child) => /^summary$/i.test(child.tagName));
|
|
111
120
|
};
|
|
112
|
-
var _isValidElement = function(element, filters, tabbable) {
|
|
113
|
-
const item = _getItem(element, tabbable);
|
|
114
|
-
return !filters.some((filter) => filter(item));
|
|
115
|
-
};
|
|
116
|
-
function getFocusableElements(parent) {
|
|
117
|
-
return _getValidElements(parent, _getFocusableFilters(), false);
|
|
118
|
-
}
|
|
119
|
-
function getTabbableElements(parent) {
|
|
120
|
-
return _getValidElements(parent, _getTabbableFilters(), true);
|
|
121
|
-
}
|
|
122
|
-
function isFocusableElement(element) {
|
|
123
|
-
return _isValidElement(element, _getFocusableFilters(), false);
|
|
124
|
-
}
|
|
125
121
|
function isTabbableElement(element) {
|
|
126
|
-
return
|
|
122
|
+
return isValidElement(element, getTabbableFilters(), true);
|
|
127
123
|
}
|
|
124
|
+
var isValidElement = function(element, filters, tabbable) {
|
|
125
|
+
const item = getItem(element, tabbable);
|
|
126
|
+
return !filters.some((filter) => filter(item));
|
|
127
|
+
};
|
|
128
128
|
var selector = [
|
|
129
129
|
'[contenteditable]:not([contenteditable="false"])',
|
|
130
130
|
"[tabindex]:not(slot)",
|
|
@@ -1,25 +1,31 @@
|
|
|
1
1
|
// src/js/element/focusable.ts
|
|
2
|
-
|
|
2
|
+
function getFocusableElements(parent) {
|
|
3
|
+
return getValidElements(parent, getFocusableFilters(), false);
|
|
4
|
+
}
|
|
5
|
+
var getFocusableFilters = function() {
|
|
6
|
+
return [isDisabled, isInert, isHidden, isSummarised];
|
|
7
|
+
};
|
|
8
|
+
var getItem = function(element, tabbable) {
|
|
3
9
|
return {
|
|
4
10
|
element,
|
|
5
|
-
tabIndex: tabbable ?
|
|
11
|
+
tabIndex: tabbable ? getTabIndex(element) : -1
|
|
6
12
|
};
|
|
7
13
|
};
|
|
8
|
-
var
|
|
9
|
-
return [
|
|
14
|
+
var getTabbableFilters = function() {
|
|
15
|
+
return [isNotTabbable, isNotTabbableRadio, ...getFocusableFilters()];
|
|
10
16
|
};
|
|
11
|
-
|
|
12
|
-
return
|
|
13
|
-
}
|
|
14
|
-
var
|
|
17
|
+
function getTabbableElements(parent) {
|
|
18
|
+
return getValidElements(parent, getTabbableFilters(), true);
|
|
19
|
+
}
|
|
20
|
+
var getTabIndex = function(element) {
|
|
15
21
|
const tabIndex = element?.tabIndex ?? -1;
|
|
16
|
-
if (tabIndex < 0 && (/^(audio|details|video)$/i.test(element.tagName) ||
|
|
22
|
+
if (tabIndex < 0 && (/^(audio|details|video)$/i.test(element.tagName) || isEditable(element)) && !hasTabIndex(element)) {
|
|
17
23
|
return 0;
|
|
18
24
|
}
|
|
19
25
|
return tabIndex;
|
|
20
26
|
};
|
|
21
|
-
var
|
|
22
|
-
const items = Array.from(parent.querySelectorAll(selector)).map((element) =>
|
|
27
|
+
var getValidElements = function(parent, filters, tabbable) {
|
|
28
|
+
const items = Array.from(parent.querySelectorAll(selector)).map((element) => getItem(element, tabbable)).filter((item) => !filters.some((filter) => filter(item)));
|
|
23
29
|
if (!tabbable) {
|
|
24
30
|
return items.map((item) => item.element);
|
|
25
31
|
}
|
|
@@ -40,16 +46,16 @@ var _getValidElements = function(parent, filters, tabbable) {
|
|
|
40
46
|
}
|
|
41
47
|
return [...indiced.flat(), ...zeroed];
|
|
42
48
|
};
|
|
43
|
-
var
|
|
49
|
+
var hasTabIndex = function(element) {
|
|
44
50
|
return !Number.isNaN(Number.parseInt(element.getAttribute("tabindex"), 10));
|
|
45
51
|
};
|
|
46
|
-
var
|
|
47
|
-
if (/^(button|input|select|textarea)$/i.test(item.element.tagName) &&
|
|
52
|
+
var isDisabled = function(item) {
|
|
53
|
+
if (/^(button|input|select|textarea)$/i.test(item.element.tagName) && isDisabledFromFieldset(item.element)) {
|
|
48
54
|
return true;
|
|
49
55
|
}
|
|
50
56
|
return (item.element.disabled ?? false) || item.element.getAttribute("aria-disabled") === "true";
|
|
51
57
|
};
|
|
52
|
-
var
|
|
58
|
+
var isDisabledFromFieldset = function(element) {
|
|
53
59
|
let parent = element.parentElement;
|
|
54
60
|
while (parent !== null) {
|
|
55
61
|
if (parent instanceof HTMLFieldSetElement && parent.disabled) {
|
|
@@ -68,10 +74,13 @@ var _isDisabledFromFieldset = function(element) {
|
|
|
68
74
|
}
|
|
69
75
|
return false;
|
|
70
76
|
};
|
|
71
|
-
var
|
|
77
|
+
var isEditable = function(element) {
|
|
72
78
|
return /^(|true)$/i.test(element.getAttribute("contenteditable"));
|
|
73
79
|
};
|
|
74
|
-
|
|
80
|
+
function isFocusableElement(element) {
|
|
81
|
+
return isValidElement(element, getFocusableFilters(), false);
|
|
82
|
+
}
|
|
83
|
+
var isHidden = function(item) {
|
|
75
84
|
if ((item.element.hidden ?? false) || item.element instanceof HTMLInputElement && item.element.type === "hidden") {
|
|
76
85
|
return true;
|
|
77
86
|
}
|
|
@@ -87,16 +96,16 @@ var _isHidden = function(item) {
|
|
|
87
96
|
const { height, width } = item.element.getBoundingClientRect();
|
|
88
97
|
return height === 0 && width === 0;
|
|
89
98
|
};
|
|
90
|
-
var
|
|
91
|
-
return (item.element.inert ?? false) || /^(|true)$/i.test(item.element.getAttribute("inert")) || item.element.parentElement !== null &&
|
|
99
|
+
var isInert = function(item) {
|
|
100
|
+
return (item.element.inert ?? false) || /^(|true)$/i.test(item.element.getAttribute("inert")) || item.element.parentElement !== null && isInert({
|
|
92
101
|
element: item.element.parentElement,
|
|
93
102
|
tabIndex: -1
|
|
94
103
|
});
|
|
95
104
|
};
|
|
96
|
-
var
|
|
105
|
+
var isNotTabbable = function(item) {
|
|
97
106
|
return (item.tabIndex ?? -1) < 0;
|
|
98
107
|
};
|
|
99
|
-
var
|
|
108
|
+
var isNotTabbableRadio = function(item) {
|
|
100
109
|
if (!(item.element instanceof HTMLInputElement) || item.element.type !== "radio" || !item.element.name || item.element.checked) {
|
|
101
110
|
return false;
|
|
102
111
|
}
|
|
@@ -106,25 +115,16 @@ var _isNotTabbableRadio = function(item) {
|
|
|
106
115
|
const checked = radios.find((radio) => radio.checked);
|
|
107
116
|
return checked !== undefined && checked !== item.element;
|
|
108
117
|
};
|
|
109
|
-
var
|
|
118
|
+
var isSummarised = function(item) {
|
|
110
119
|
return item.element instanceof HTMLDetailsElement && Array.from(item.element.children).some((child) => /^summary$/i.test(child.tagName));
|
|
111
120
|
};
|
|
112
|
-
var _isValidElement = function(element, filters, tabbable) {
|
|
113
|
-
const item = _getItem(element, tabbable);
|
|
114
|
-
return !filters.some((filter) => filter(item));
|
|
115
|
-
};
|
|
116
|
-
function getFocusableElements(parent) {
|
|
117
|
-
return _getValidElements(parent, _getFocusableFilters(), false);
|
|
118
|
-
}
|
|
119
|
-
function getTabbableElements(parent) {
|
|
120
|
-
return _getValidElements(parent, _getTabbableFilters(), true);
|
|
121
|
-
}
|
|
122
|
-
function isFocusableElement(element) {
|
|
123
|
-
return _isValidElement(element, _getFocusableFilters(), false);
|
|
124
|
-
}
|
|
125
121
|
function isTabbableElement(element) {
|
|
126
|
-
return
|
|
122
|
+
return isValidElement(element, getTabbableFilters(), true);
|
|
127
123
|
}
|
|
124
|
+
var isValidElement = function(element, filters, tabbable) {
|
|
125
|
+
const item = getItem(element, tabbable);
|
|
126
|
+
return !filters.some((filter) => filter(item));
|
|
127
|
+
};
|
|
128
128
|
var selector = [
|
|
129
129
|
'[contenteditable]:not([contenteditable="false"])',
|
|
130
130
|
"[tabindex]:not(slot)",
|