power-focusable 2.1.11 → 2.1.13

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/index.cjs CHANGED
@@ -24,14 +24,25 @@ function getFocusables(container = document.body, options = {}) {
24
24
  const assigneds = node.assignedElements({ flatten: true });
25
25
  if (assigneds.length) {
26
26
  for (let i = 0, l = assigneds.length; i < l; i++) {
27
- traverse2(assigneds[i]);
27
+ const assigned = assigneds[i];
28
+ if (!assigned) {
29
+ continue;
30
+ }
31
+ traverse2(assigned);
28
32
  }
29
33
  return;
30
34
  }
31
35
  }
32
- const children = node.childNodes;
36
+ if (!(node instanceof Element || node instanceof ShadowRoot)) {
37
+ return;
38
+ }
39
+ const children = node.children;
33
40
  for (let i = 0, l = children.length; i < l; i++) {
34
- traverse2(children[i]);
41
+ const child = children[i];
42
+ if (!child) {
43
+ continue;
44
+ }
45
+ traverse2(child);
35
46
  }
36
47
  };
37
48
  traverse2(container);
@@ -39,6 +50,9 @@ function getFocusables(container = document.body, options = {}) {
39
50
  const candidates = container.querySelectorAll(FOCUSABLE_SELECTOR);
40
51
  for (let i = 0, l = candidates.length; i < l; i++) {
41
52
  const candidate = candidates[i];
53
+ if (!(candidate instanceof HTMLElement)) {
54
+ continue;
55
+ }
42
56
  if (isFocusable(candidate)) {
43
57
  elements[elements.length] = candidate;
44
58
  }
@@ -107,6 +121,9 @@ function getRelativeFocusable(container, offset, options) {
107
121
  if (!active || !containsDeep(container, active)) {
108
122
  return null;
109
123
  }
124
+ if (!(active instanceof HTMLElement)) {
125
+ return null;
126
+ }
110
127
  const currentIndex = focusables.indexOf(active);
111
128
  if (currentIndex === -1) {
112
129
  return null;
@@ -177,6 +194,9 @@ function normalizeRadioGroup(elements) {
177
194
  let map = null;
178
195
  for (let i = 0, l = elements.length; i < l; i++) {
179
196
  const element = elements[i];
197
+ if (!(element instanceof HTMLInputElement)) {
198
+ continue;
199
+ }
180
200
  if (!isUngroupedRadio(element)) {
181
201
  continue;
182
202
  }
@@ -208,6 +228,9 @@ function sortByTabIndex(elements) {
208
228
  const natural = [];
209
229
  for (let i = 0, l = elements.length; i < l; i++) {
210
230
  const element = elements[i];
231
+ if (!element) {
232
+ continue;
233
+ }
211
234
  const target = element.tabIndex > 0 ? ordered : natural;
212
235
  target[target.length] = element;
213
236
  }
@@ -227,7 +250,7 @@ function sortByTabIndex(elements) {
227
250
  * High-precision focus management utility with shadow DOM support.
228
251
  * Handles complex focus rules including tabindex ordering, radio groups, etc.
229
252
  *
230
- * @version 2.1.11
253
+ * @version 2.1.13
231
254
  * @author Yusuke Kamiyamane
232
255
  * @license MIT
233
256
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.d.cts CHANGED
@@ -3,7 +3,7 @@
3
3
  * High-precision focus management utility with shadow DOM support.
4
4
  * Handles complex focus rules including tabindex ordering, radio groups, etc.
5
5
  *
6
- * @version 2.1.11
6
+ * @version 2.1.13
7
7
  * @author Yusuke Kamiyamane
8
8
  * @license MIT
9
9
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * High-precision focus management utility with shadow DOM support.
4
4
  * Handles complex focus rules including tabindex ordering, radio groups, etc.
5
5
  *
6
- * @version 2.1.11
6
+ * @version 2.1.13
7
7
  * @author Yusuke Kamiyamane
8
8
  * @license MIT
9
9
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.js CHANGED
@@ -22,14 +22,25 @@ function getFocusables(container = document.body, options = {}) {
22
22
  const assigneds = node.assignedElements({ flatten: true });
23
23
  if (assigneds.length) {
24
24
  for (let i = 0, l = assigneds.length; i < l; i++) {
25
- traverse2(assigneds[i]);
25
+ const assigned = assigneds[i];
26
+ if (!assigned) {
27
+ continue;
28
+ }
29
+ traverse2(assigned);
26
30
  }
27
31
  return;
28
32
  }
29
33
  }
30
- const children = node.childNodes;
34
+ if (!(node instanceof Element || node instanceof ShadowRoot)) {
35
+ return;
36
+ }
37
+ const children = node.children;
31
38
  for (let i = 0, l = children.length; i < l; i++) {
32
- traverse2(children[i]);
39
+ const child = children[i];
40
+ if (!child) {
41
+ continue;
42
+ }
43
+ traverse2(child);
33
44
  }
34
45
  };
35
46
  traverse2(container);
@@ -37,6 +48,9 @@ function getFocusables(container = document.body, options = {}) {
37
48
  const candidates = container.querySelectorAll(FOCUSABLE_SELECTOR);
38
49
  for (let i = 0, l = candidates.length; i < l; i++) {
39
50
  const candidate = candidates[i];
51
+ if (!(candidate instanceof HTMLElement)) {
52
+ continue;
53
+ }
40
54
  if (isFocusable(candidate)) {
41
55
  elements[elements.length] = candidate;
42
56
  }
@@ -105,6 +119,9 @@ function getRelativeFocusable(container, offset, options) {
105
119
  if (!active || !containsDeep(container, active)) {
106
120
  return null;
107
121
  }
122
+ if (!(active instanceof HTMLElement)) {
123
+ return null;
124
+ }
108
125
  const currentIndex = focusables.indexOf(active);
109
126
  if (currentIndex === -1) {
110
127
  return null;
@@ -175,6 +192,9 @@ function normalizeRadioGroup(elements) {
175
192
  let map = null;
176
193
  for (let i = 0, l = elements.length; i < l; i++) {
177
194
  const element = elements[i];
195
+ if (!(element instanceof HTMLInputElement)) {
196
+ continue;
197
+ }
178
198
  if (!isUngroupedRadio(element)) {
179
199
  continue;
180
200
  }
@@ -206,6 +226,9 @@ function sortByTabIndex(elements) {
206
226
  const natural = [];
207
227
  for (let i = 0, l = elements.length; i < l; i++) {
208
228
  const element = elements[i];
229
+ if (!element) {
230
+ continue;
231
+ }
209
232
  const target = element.tabIndex > 0 ? ordered : natural;
210
233
  target[target.length] = element;
211
234
  }
@@ -225,7 +248,7 @@ function sortByTabIndex(elements) {
225
248
  * High-precision focus management utility with shadow DOM support.
226
249
  * Handles complex focus rules including tabindex ordering, radio groups, etc.
227
250
  *
228
- * @version 2.1.11
251
+ * @version 2.1.13
229
252
  * @author Yusuke Kamiyamane
230
253
  * @license MIT
231
254
  * @copyright Copyright (c) Yusuke Kamiyamane
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "power-focusable",
3
- "version": "2.1.11",
3
+ "version": "2.1.13",
4
4
  "description": "High-precision focus management utility with shadow DOM support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -20,6 +20,7 @@
20
20
  ],
21
21
  "scripts": {
22
22
  "build": "tsup",
23
+ "test": "vitest run",
23
24
  "prepublishOnly": "npm run build",
24
25
  "lint": "tsc --noEmit"
25
26
  },
@@ -46,8 +47,10 @@
46
47
  "homepage": "https://github.com/y14e/power-focusable#readme",
47
48
  "devDependencies": {
48
49
  "bun-types": "latest",
50
+ "happy-dom": "^20.9.0",
49
51
  "tsup": "^8.0.0",
50
- "typescript": "^5.6.0"
52
+ "typescript": "^5.6.0",
53
+ "vitest": "^4.1.5"
51
54
  },
52
55
  "engines": {
53
56
  "node": ">=18"