@wordpress/dom 4.57.0 → 5.1.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/README.md +23 -23
- package/build/data-transfer.cjs +20 -38
- package/build/data-transfer.cjs.map +1 -7
- package/build/dom/caret-range-from-point.cjs +31 -38
- package/build/dom/caret-range-from-point.cjs.map +1 -7
- package/build/dom/clean-node-list.cjs +88 -133
- package/build/dom/clean-node-list.cjs.map +1 -7
- package/build/dom/compute-caret-rect.cjs +36 -36
- package/build/dom/compute-caret-rect.cjs.map +1 -7
- package/build/dom/document-has-selection.cjs +36 -31
- package/build/dom/document-has-selection.cjs.map +1 -7
- package/build/dom/document-has-text-selection.cjs +24 -30
- package/build/dom/document-has-text-selection.cjs.map +1 -7
- package/build/dom/document-has-uncollapsed-selection.cjs +35 -30
- package/build/dom/document-has-uncollapsed-selection.cjs.map +1 -7
- package/build/dom/get-computed-style.cjs +14 -30
- package/build/dom/get-computed-style.cjs.map +1 -7
- package/build/dom/get-offset-parent.cjs +41 -48
- package/build/dom/get-offset-parent.cjs.map +1 -7
- package/build/dom/get-range-height.cjs +18 -31
- package/build/dom/get-range-height.cjs.map +1 -7
- package/build/dom/get-rectangle-from-range.cjs +82 -133
- package/build/dom/get-rectangle-from-range.cjs.map +1 -7
- package/build/dom/get-scroll-container.cjs +47 -55
- package/build/dom/get-scroll-container.cjs.map +1 -7
- package/build/dom/hidden-caret-range-from-point.cjs +49 -43
- package/build/dom/hidden-caret-range-from-point.cjs.map +1 -7
- package/build/dom/index.cjs +233 -110
- package/build/dom/input-field-has-uncollapsed-selection.cjs +49 -47
- package/build/dom/input-field-has-uncollapsed-selection.cjs.map +1 -7
- package/build/dom/insert-after.cjs +17 -27
- package/build/dom/insert-after.cjs.map +1 -7
- package/build/dom/is-edge.cjs +83 -98
- package/build/dom/is-edge.cjs.map +1 -7
- package/build/dom/is-element.cjs +12 -25
- package/build/dom/is-element.cjs.map +1 -7
- package/build/dom/is-empty.cjs +23 -40
- package/build/dom/is-empty.cjs.map +1 -7
- package/build/dom/is-entirely-selected.cjs +71 -71
- package/build/dom/is-entirely-selected.cjs.map +1 -7
- package/build/dom/is-form-element.cjs +34 -34
- package/build/dom/is-form-element.cjs.map +1 -7
- package/build/dom/is-horizontal-edge.cjs +32 -29
- package/build/dom/is-horizontal-edge.cjs.map +1 -7
- package/build/dom/is-html-input-element.cjs +12 -25
- package/build/dom/is-html-input-element.cjs.map +1 -7
- package/build/dom/is-input-or-text-area.cjs +12 -25
- package/build/dom/is-input-or-text-area.cjs.map +1 -7
- package/build/dom/is-number-input.cjs +37 -34
- package/build/dom/is-number-input.cjs.map +1 -7
- package/build/dom/is-rtl.cjs +31 -29
- package/build/dom/is-rtl.cjs.map +1 -7
- package/build/dom/is-selection-forward.cjs +26 -39
- package/build/dom/is-selection-forward.cjs.map +1 -7
- package/build/dom/is-text-field.cjs +46 -44
- package/build/dom/is-text-field.cjs.map +1 -7
- package/build/dom/is-vertical-edge.cjs +32 -29
- package/build/dom/is-vertical-edge.cjs.map +1 -7
- package/build/dom/place-caret-at-edge.cjs +76 -79
- package/build/dom/place-caret-at-edge.cjs.map +1 -7
- package/build/dom/place-caret-at-horizontal-edge.cjs +30 -29
- package/build/dom/place-caret-at-horizontal-edge.cjs.map +1 -7
- package/build/dom/place-caret-at-vertical-edge.cjs +31 -29
- package/build/dom/place-caret-at-vertical-edge.cjs.map +1 -7
- package/build/dom/remove-invalid-html.cjs +36 -32
- package/build/dom/remove-invalid-html.cjs.map +1 -7
- package/build/dom/remove.cjs +15 -27
- package/build/dom/remove.cjs.map +1 -7
- package/build/dom/replace-tag.cjs +21 -32
- package/build/dom/replace-tag.cjs.map +1 -7
- package/build/dom/replace.cjs +35 -33
- package/build/dom/replace.cjs.map +1 -7
- package/build/dom/safe-html.cjs +46 -47
- package/build/dom/safe-html.cjs.map +1 -7
- package/build/dom/scroll-if-no-range.cjs +24 -37
- package/build/dom/scroll-if-no-range.cjs.map +1 -7
- package/build/dom/strip-html.cjs +34 -32
- package/build/dom/strip-html.cjs.map +1 -7
- package/build/dom/types.cjs +5 -0
- package/build/dom/unwrap.cjs +17 -31
- package/build/dom/unwrap.cjs.map +1 -7
- package/build/dom/wrap.cjs +17 -28
- package/build/dom/wrap.cjs.map +1 -7
- package/build/focusable.cjs +99 -77
- package/build/focusable.cjs.map +1 -7
- package/build/index.cjs +58 -39
- package/build/index.cjs.map +1 -7
- package/build/phrasing-content.cjs +163 -159
- package/build/phrasing-content.cjs.map +1 -7
- package/build/tabbable.cjs +123 -78
- package/build/tabbable.cjs.map +1 -7
- package/build/types.cjs +5 -0
- package/build/utils/assert-is-defined.cjs +8 -33
- package/build/utils/assert-is-defined.cjs.map +1 -7
- package/build-module/data-transfer.mjs +17 -15
- package/build-module/data-transfer.mjs.map +1 -7
- package/build-module/dom/caret-range-from-point.mjs +28 -19
- package/build-module/dom/caret-range-from-point.mjs.map +1 -7
- package/build-module/dom/clean-node-list.mjs +60 -105
- package/build-module/dom/clean-node-list.mjs.map +1 -7
- package/build-module/dom/compute-caret-rect.mjs +16 -12
- package/build-module/dom/compute-caret-rect.mjs.map +1 -7
- package/build-module/dom/document-has-selection.mjs +13 -6
- package/build-module/dom/document-has-selection.mjs.map +1 -7
- package/build-module/dom/document-has-text-selection.mjs +20 -10
- package/build-module/dom/document-has-text-selection.mjs.map +1 -7
- package/build-module/dom/document-has-uncollapsed-selection.mjs +14 -6
- package/build-module/dom/document-has-uncollapsed-selection.mjs.map +1 -7
- package/build-module/dom/get-computed-style.mjs +10 -10
- package/build-module/dom/get-computed-style.mjs.map +1 -7
- package/build-module/dom/get-offset-parent.mjs +21 -25
- package/build-module/dom/get-offset-parent.mjs.map +1 -7
- package/build-module/dom/get-range-height.mjs +15 -12
- package/build-module/dom/get-range-height.mjs.map +1 -7
- package/build-module/dom/get-rectangle-from-range.mjs +78 -113
- package/build-module/dom/get-rectangle-from-range.mjs.map +1 -7
- package/build-module/dom/get-scroll-container.mjs +28 -32
- package/build-module/dom/get-scroll-container.mjs.map +1 -7
- package/build-module/dom/hidden-caret-range-from-point.mjs +28 -19
- package/build-module/dom/hidden-caret-range-from-point.mjs.map +1 -7
- package/build-module/dom/index.mjs +28 -58
- package/build-module/dom/input-field-has-uncollapsed-selection.mjs +28 -23
- package/build-module/dom/input-field-has-uncollapsed-selection.mjs.map +1 -7
- package/build-module/dom/insert-after.mjs +13 -7
- package/build-module/dom/insert-after.mjs.map +1 -7
- package/build-module/dom/is-edge.mjs +53 -69
- package/build-module/dom/is-edge.mjs.map +1 -7
- package/build-module/dom/is-element.mjs +9 -6
- package/build-module/dom/is-element.mjs.map +1 -7
- package/build-module/dom/is-empty.mjs +20 -21
- package/build-module/dom/is-empty.mjs.map +1 -7
- package/build-module/dom/is-entirely-selected.mjs +51 -47
- package/build-module/dom/is-entirely-selected.mjs.map +1 -7
- package/build-module/dom/is-form-element.mjs +15 -11
- package/build-module/dom/is-form-element.mjs.map +1 -7
- package/build-module/dom/is-horizontal-edge.mjs +13 -6
- package/build-module/dom/is-horizontal-edge.mjs.map +1 -7
- package/build-module/dom/is-html-input-element.mjs +9 -6
- package/build-module/dom/is-html-input-element.mjs.map +1 -7
- package/build-module/dom/is-input-or-text-area.mjs +9 -6
- package/build-module/dom/is-input-or-text-area.mjs.map +1 -7
- package/build-module/dom/is-number-input.mjs +16 -10
- package/build-module/dom/is-number-input.mjs.map +1 -7
- package/build-module/dom/is-rtl.mjs +12 -6
- package/build-module/dom/is-rtl.mjs.map +1 -7
- package/build-module/dom/is-selection-forward.mjs +22 -19
- package/build-module/dom/is-selection-forward.mjs.map +1 -7
- package/build-module/dom/is-text-field.mjs +27 -21
- package/build-module/dom/is-text-field.mjs.map +1 -7
- package/build-module/dom/is-vertical-edge.mjs +13 -6
- package/build-module/dom/is-vertical-edge.mjs.map +1 -7
- package/build-module/dom/place-caret-at-edge.mjs +51 -52
- package/build-module/dom/place-caret-at-edge.mjs.map +1 -7
- package/build-module/dom/place-caret-at-horizontal-edge.mjs +11 -6
- package/build-module/dom/place-caret-at-horizontal-edge.mjs.map +1 -7
- package/build-module/dom/place-caret-at-vertical-edge.mjs +12 -6
- package/build-module/dom/place-caret-at-vertical-edge.mjs.map +1 -7
- package/build-module/dom/remove-invalid-html.mjs +17 -9
- package/build-module/dom/remove-invalid-html.mjs.map +1 -7
- package/build-module/dom/remove.mjs +11 -7
- package/build-module/dom/remove.mjs.map +1 -7
- package/build-module/dom/replace-tag.mjs +17 -12
- package/build-module/dom/replace-tag.mjs.map +1 -7
- package/build-module/dom/replace.mjs +13 -8
- package/build-module/dom/replace.mjs.map +1 -7
- package/build-module/dom/safe-html.mjs +27 -24
- package/build-module/dom/safe-html.mjs.map +1 -7
- package/build-module/dom/scroll-if-no-range.mjs +21 -14
- package/build-module/dom/scroll-if-no-range.mjs.map +1 -7
- package/build-module/dom/strip-html.mjs +15 -9
- package/build-module/dom/strip-html.mjs.map +1 -7
- package/build-module/dom/types.mjs +0 -0
- package/build-module/dom/unwrap.mjs +13 -11
- package/build-module/dom/unwrap.mjs.map +1 -7
- package/build-module/dom/wrap.mjs +13 -8
- package/build-module/dom/wrap.mjs.map +1 -7
- package/build-module/focusable.mjs +96 -54
- package/build-module/focusable.mjs.map +1 -7
- package/build-module/index.mjs +11 -5
- package/build-module/index.mjs.map +1 -7
- package/build-module/phrasing-content.mjs +158 -134
- package/build-module/phrasing-content.mjs.map +1 -7
- package/build-module/tabbable.mjs +117 -52
- package/build-module/tabbable.mjs.map +1 -7
- package/build-module/types.mjs +0 -0
- package/build-module/utils/assert-is-defined.mjs +4 -9
- package/build-module/utils/assert-is-defined.mjs.map +1 -7
- package/build-types/data-transfer.d.ts +2 -2
- package/build-types/data-transfer.d.ts.map +1 -1
- package/build-types/dom/caret-range-from-point.d.ts +4 -4
- package/build-types/dom/caret-range-from-point.d.ts.map +1 -1
- package/build-types/dom/clean-node-list.d.ts +6 -46
- package/build-types/dom/clean-node-list.d.ts.map +1 -1
- package/build-types/dom/compute-caret-rect.d.ts +2 -2
- package/build-types/dom/compute-caret-rect.d.ts.map +1 -1
- package/build-types/dom/document-has-selection.d.ts +2 -2
- package/build-types/dom/document-has-selection.d.ts.map +1 -1
- package/build-types/dom/document-has-text-selection.d.ts +2 -2
- package/build-types/dom/document-has-text-selection.d.ts.map +1 -1
- package/build-types/dom/document-has-uncollapsed-selection.d.ts +2 -2
- package/build-types/dom/document-has-uncollapsed-selection.d.ts.map +1 -1
- package/build-types/dom/get-computed-style.d.ts +3 -3
- package/build-types/dom/get-computed-style.d.ts.map +1 -1
- package/build-types/dom/get-offset-parent.d.ts +2 -2
- package/build-types/dom/get-offset-parent.d.ts.map +1 -1
- package/build-types/dom/get-range-height.d.ts +2 -2
- package/build-types/dom/get-range-height.d.ts.map +1 -1
- package/build-types/dom/get-rectangle-from-range.d.ts +2 -2
- package/build-types/dom/get-rectangle-from-range.d.ts.map +1 -1
- package/build-types/dom/get-scroll-container.d.ts +5 -5
- package/build-types/dom/get-scroll-container.d.ts.map +1 -1
- package/build-types/dom/hidden-caret-range-from-point.d.ts +5 -5
- package/build-types/dom/hidden-caret-range-from-point.d.ts.map +1 -1
- package/build-types/dom/index.d.ts.map +1 -1
- package/build-types/dom/input-field-has-uncollapsed-selection.d.ts +2 -2
- package/build-types/dom/input-field-has-uncollapsed-selection.d.ts.map +1 -1
- package/build-types/dom/insert-after.d.ts +2 -3
- package/build-types/dom/insert-after.d.ts.map +1 -1
- package/build-types/dom/is-edge.d.ts +4 -4
- package/build-types/dom/is-edge.d.ts.map +1 -1
- package/build-types/dom/is-element.d.ts.map +1 -1
- package/build-types/dom/is-empty.d.ts +3 -3
- package/build-types/dom/is-empty.d.ts.map +1 -1
- package/build-types/dom/is-entirely-selected.d.ts +2 -2
- package/build-types/dom/is-entirely-selected.d.ts.map +1 -1
- package/build-types/dom/is-form-element.d.ts +3 -3
- package/build-types/dom/is-form-element.d.ts.map +1 -1
- package/build-types/dom/is-horizontal-edge.d.ts.map +1 -1
- package/build-types/dom/is-html-input-element.d.ts +1 -1
- package/build-types/dom/is-html-input-element.d.ts.map +1 -1
- package/build-types/dom/is-input-or-text-area.d.ts.map +1 -1
- package/build-types/dom/is-number-input.d.ts +2 -2
- package/build-types/dom/is-number-input.d.ts.map +1 -1
- package/build-types/dom/is-rtl.d.ts +2 -2
- package/build-types/dom/is-rtl.d.ts.map +1 -1
- package/build-types/dom/is-selection-forward.d.ts +2 -2
- package/build-types/dom/is-selection-forward.d.ts.map +1 -1
- package/build-types/dom/is-text-field.d.ts +2 -2
- package/build-types/dom/is-text-field.d.ts.map +1 -1
- package/build-types/dom/is-vertical-edge.d.ts.map +1 -1
- package/build-types/dom/place-caret-at-edge.d.ts +3 -3
- package/build-types/dom/place-caret-at-edge.d.ts.map +1 -1
- package/build-types/dom/place-caret-at-horizontal-edge.d.ts.map +1 -1
- package/build-types/dom/place-caret-at-vertical-edge.d.ts.map +1 -1
- package/build-types/dom/remove-invalid-html.d.ts +5 -4
- package/build-types/dom/remove-invalid-html.d.ts.map +1 -1
- package/build-types/dom/remove.d.ts +1 -2
- package/build-types/dom/remove.d.ts.map +1 -1
- package/build-types/dom/replace-tag.d.ts +3 -3
- package/build-types/dom/replace-tag.d.ts.map +1 -1
- package/build-types/dom/replace.d.ts +2 -3
- package/build-types/dom/replace.d.ts.map +1 -1
- package/build-types/dom/safe-html.d.ts +2 -2
- package/build-types/dom/safe-html.d.ts.map +1 -1
- package/build-types/dom/scroll-if-no-range.d.ts +5 -5
- package/build-types/dom/scroll-if-no-range.d.ts.map +1 -1
- package/build-types/dom/strip-html.d.ts +2 -2
- package/build-types/dom/strip-html.d.ts.map +1 -1
- package/build-types/dom/types.d.ts +32 -0
- package/build-types/dom/types.d.ts.map +1 -0
- package/build-types/dom/unwrap.d.ts +1 -3
- package/build-types/dom/unwrap.d.ts.map +1 -1
- package/build-types/dom/wrap.d.ts +2 -2
- package/build-types/dom/wrap.d.ts.map +1 -1
- package/build-types/focusable.d.ts +11 -30
- package/build-types/focusable.d.ts.map +1 -1
- package/build-types/index.d.ts +17 -0
- package/build-types/index.d.ts.map +1 -1
- package/build-types/phrasing-content.d.ts +9 -24
- package/build-types/phrasing-content.d.ts.map +1 -1
- package/build-types/tabbable.d.ts +10 -15
- package/build-types/tabbable.d.ts.map +1 -1
- package/build-types/types.d.ts +29 -0
- package/build-types/types.d.ts.map +1 -0
- package/package.json +6 -7
- package/src/{data-transfer.js → data-transfer.ts} +3 -3
- package/src/dom/{caret-range-from-point.js → caret-range-from-point.ts} +9 -5
- package/src/dom/{clean-node-list.js → clean-node-list.ts} +16 -24
- package/src/dom/{compute-caret-rect.js → compute-caret-rect.ts} +3 -3
- package/src/dom/{document-has-selection.js → document-has-selection.ts} +3 -3
- package/src/dom/{document-has-text-selection.js → document-has-text-selection.ts} +3 -3
- package/src/dom/{document-has-uncollapsed-selection.js → document-has-uncollapsed-selection.ts} +5 -3
- package/src/dom/{get-computed-style.js → get-computed-style.ts} +5 -3
- package/src/dom/{get-offset-parent.js → get-offset-parent.ts} +9 -14
- package/src/dom/{get-range-height.js → get-range-height.ts} +3 -3
- package/src/dom/{get-rectangle-from-range.js → get-rectangle-from-range.ts} +6 -12
- package/src/dom/{get-scroll-container.js → get-scroll-container.ts} +9 -9
- package/src/dom/{hidden-caret-range-from-point.js → hidden-caret-range-from-point.ts} +11 -6
- package/src/dom/{input-field-has-uncollapsed-selection.js → input-field-has-uncollapsed-selection.ts} +7 -5
- package/src/dom/{insert-after.js → insert-after.ts} +6 -4
- package/src/dom/{is-edge.js → is-edge.ts} +44 -48
- package/src/dom/{is-element.js → is-element.ts} +3 -1
- package/src/dom/{is-empty.js → is-empty.ts} +5 -7
- package/src/dom/{is-entirely-selected.js → is-entirely-selected.ts} +14 -11
- package/src/dom/{is-form-element.js → is-form-element.ts} +5 -3
- package/src/dom/{is-horizontal-edge.js → is-horizontal-edge.ts} +4 -1
- package/src/dom/{is-html-input-element.js → is-html-input-element.ts} +3 -1
- package/src/dom/{is-input-or-text-area.js → is-input-or-text-area.ts} +3 -1
- package/src/dom/{is-number-input.js → is-number-input.ts} +3 -3
- package/src/dom/{is-rtl.js → is-rtl.ts} +3 -3
- package/src/dom/{is-selection-forward.js → is-selection-forward.ts} +3 -3
- package/src/dom/{is-text-field.js → is-text-field.ts} +4 -4
- package/src/dom/{is-vertical-edge.js → is-vertical-edge.ts} +4 -1
- package/src/dom/{place-caret-at-edge.js → place-caret-at-edge.ts} +17 -9
- package/src/dom/{place-caret-at-horizontal-edge.js → place-caret-at-horizontal-edge.ts} +4 -1
- package/src/dom/{place-caret-at-vertical-edge.js → place-caret-at-vertical-edge.ts} +5 -1
- package/src/dom/{remove-invalid-html.js → remove-invalid-html.ts} +9 -4
- package/src/dom/{remove.js → remove.ts} +2 -3
- package/src/dom/{replace-tag.js → replace-tag.ts} +4 -4
- package/src/dom/{replace.js → replace.ts} +6 -4
- package/src/dom/{safe-html.js → safe-html.ts} +3 -3
- package/src/dom/{scroll-if-no-range.js → scroll-if-no-range.ts} +9 -5
- package/src/dom/{strip-html.js → strip-html.ts} +3 -3
- package/src/dom/test/{get-rectangle-from-range.browser.test.js → get-rectangle-from-range.browser.test.ts} +25 -25
- package/src/dom/types.ts +28 -0
- package/src/dom/{unwrap.js → unwrap.ts} +2 -4
- package/src/dom/{wrap.js → wrap.ts} +3 -3
- package/src/{focusable.js → focusable.ts} +34 -32
- package/src/index.ts +33 -0
- package/src/{phrasing-content.js → phrasing-content.ts} +15 -30
- package/src/{tabbable.js → tabbable.ts} +48 -39
- package/src/test/{dom.jsdom.test.js → dom.jsdom.test.ts} +30 -6
- package/src/test/{focusable.browser.test.js → focusable.browser.test.ts} +14 -13
- package/src/test/{tabbable.browser.test.js → tabbable.browser.test.ts} +3 -2
- package/src/types.ts +32 -0
- package/CHANGELOG.md +0 -317
- package/build/dom/index.cjs.map +0 -7
- package/build-module/dom/index.mjs.map +0 -7
- package/src/index.js +0 -12
- /package/src/dom/{index.js → index.ts} +0 -0
- /package/src/dom/test/{safe-html.jsdom.test.js → safe-html.jsdom.test.ts} +0 -0
- /package/src/dom/test/{strip-html.jsdom.test.js → strip-html.jsdom.test.ts} +0 -0
- /package/src/test/{focusable-area.jsdom.test.js → focusable-area.jsdom.test.ts} +0 -0
- /package/src/test/{utils.js → utils.ts} +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { MaybeHTMLInputElement, ObjectTabbable } from './types';
|
|
1
2
|
import { find as findFocusable } from './focusable';
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -8,11 +9,11 @@ import { find as findFocusable } from './focusable';
|
|
|
8
9
|
*
|
|
9
10
|
* @see https://bugzilla.mozilla.org/show_bug.cgi?id=1190261
|
|
10
11
|
*
|
|
11
|
-
* @param
|
|
12
|
+
* @param element Element from which to retrieve.
|
|
12
13
|
*
|
|
13
|
-
* @return
|
|
14
|
+
* @return Tab index of element (default 0).
|
|
14
15
|
*/
|
|
15
|
-
function getTabIndex( element ) {
|
|
16
|
+
function getTabIndex( element: Element ): number {
|
|
16
17
|
const tabIndex = element.getAttribute( 'tabindex' );
|
|
17
18
|
return tabIndex === null ? 0 : parseInt( tabIndex, 10 );
|
|
18
19
|
}
|
|
@@ -20,31 +21,31 @@ function getTabIndex( element ) {
|
|
|
20
21
|
/**
|
|
21
22
|
* Returns true if the specified element is tabbable, or false otherwise.
|
|
22
23
|
*
|
|
23
|
-
* @param
|
|
24
|
+
* @param element Element to test.
|
|
24
25
|
*
|
|
25
|
-
* @return
|
|
26
|
+
* @return Whether element is tabbable.
|
|
26
27
|
*/
|
|
27
|
-
export function isTabbableIndex( element ) {
|
|
28
|
+
export function isTabbableIndex( element: Element ): boolean {
|
|
28
29
|
return getTabIndex( element ) !== -1;
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
/** @typedef {HTMLElement & { type?: string, checked?: boolean, name?: string }} MaybeHTMLInputElement */
|
|
32
|
-
|
|
33
32
|
/**
|
|
34
33
|
* Returns a stateful reducer function which constructs a filtered array of
|
|
35
34
|
* tabbable elements, where at most one radio input is selected for a given
|
|
36
35
|
* name, giving priority to checked input, falling back to the first
|
|
37
36
|
* encountered.
|
|
38
37
|
*
|
|
39
|
-
* @return
|
|
38
|
+
* @return Radio group collapse reducer.
|
|
40
39
|
*/
|
|
41
|
-
function createStatefulCollapseRadioGroup()
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
function createStatefulCollapseRadioGroup(): (
|
|
41
|
+
acc: MaybeHTMLInputElement[],
|
|
42
|
+
el: MaybeHTMLInputElement
|
|
43
|
+
) => MaybeHTMLInputElement[] {
|
|
44
|
+
const CHOSEN_RADIO_BY_NAME: Record< string, MaybeHTMLInputElement > = {};
|
|
44
45
|
|
|
45
46
|
return function collapseRadioGroup(
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
result: MaybeHTMLInputElement[],
|
|
48
|
+
element: MaybeHTMLInputElement
|
|
48
49
|
) {
|
|
49
50
|
const { nodeName, type, checked, name } = element;
|
|
50
51
|
|
|
@@ -81,12 +82,15 @@ function createStatefulCollapseRadioGroup() {
|
|
|
81
82
|
* sort where equal tabIndex should be left in order of their occurrence in the
|
|
82
83
|
* document.
|
|
83
84
|
*
|
|
84
|
-
* @param
|
|
85
|
-
* @param
|
|
85
|
+
* @param element Element.
|
|
86
|
+
* @param index Array index of element.
|
|
86
87
|
*
|
|
87
|
-
* @return
|
|
88
|
+
* @return Mapped object with element, index.
|
|
88
89
|
*/
|
|
89
|
-
function mapElementToObjectTabbable(
|
|
90
|
+
function mapElementToObjectTabbable(
|
|
91
|
+
element: HTMLElement,
|
|
92
|
+
index: number
|
|
93
|
+
): ObjectTabbable {
|
|
90
94
|
return { element, index };
|
|
91
95
|
}
|
|
92
96
|
|
|
@@ -94,11 +98,13 @@ function mapElementToObjectTabbable( element, index ) {
|
|
|
94
98
|
* An array map callback, returning an element of the given mapped object's
|
|
95
99
|
* element value.
|
|
96
100
|
*
|
|
97
|
-
* @param
|
|
101
|
+
* @param object Mapped object with element.
|
|
98
102
|
*
|
|
99
|
-
* @return
|
|
103
|
+
* @return Mapped object element.
|
|
100
104
|
*/
|
|
101
|
-
function mapObjectTabbableToElement(
|
|
105
|
+
function mapObjectTabbableToElement(
|
|
106
|
+
object: Pick< ObjectTabbable, 'element' >
|
|
107
|
+
): HTMLElement {
|
|
102
108
|
return object.element;
|
|
103
109
|
}
|
|
104
110
|
|
|
@@ -107,12 +113,15 @@ function mapObjectTabbableToElement( object ) {
|
|
|
107
113
|
*
|
|
108
114
|
* @see mapElementToObjectTabbable
|
|
109
115
|
*
|
|
110
|
-
* @param
|
|
111
|
-
* @param
|
|
116
|
+
* @param a First object to compare.
|
|
117
|
+
* @param b Second object to compare.
|
|
112
118
|
*
|
|
113
|
-
* @return
|
|
119
|
+
* @return Comparator result.
|
|
114
120
|
*/
|
|
115
|
-
function compareObjectTabbables(
|
|
121
|
+
function compareObjectTabbables(
|
|
122
|
+
a: ObjectTabbable,
|
|
123
|
+
b: ObjectTabbable
|
|
124
|
+
): number {
|
|
116
125
|
const aTabIndex = getTabIndex( a.element );
|
|
117
126
|
const bTabIndex = getTabIndex( b.element );
|
|
118
127
|
|
|
@@ -126,11 +135,11 @@ function compareObjectTabbables( a, b ) {
|
|
|
126
135
|
/**
|
|
127
136
|
* Given focusable elements, filters out tabbable element.
|
|
128
137
|
*
|
|
129
|
-
* @param
|
|
138
|
+
* @param focusables Focusable elements to filter.
|
|
130
139
|
*
|
|
131
|
-
* @return
|
|
140
|
+
* @return Tabbable elements.
|
|
132
141
|
*/
|
|
133
|
-
function filterTabbable( focusables ) {
|
|
142
|
+
function filterTabbable( focusables: HTMLElement[] ): HTMLElement[] {
|
|
134
143
|
return focusables
|
|
135
144
|
.filter( isTabbableIndex )
|
|
136
145
|
.map( mapElementToObjectTabbable )
|
|
@@ -140,22 +149,22 @@ function filterTabbable( focusables ) {
|
|
|
140
149
|
}
|
|
141
150
|
|
|
142
151
|
/**
|
|
143
|
-
* @param
|
|
144
|
-
* @return
|
|
152
|
+
* @param context
|
|
153
|
+
* @return Tabbable elements within the context.
|
|
145
154
|
*/
|
|
146
|
-
export function find( context ) {
|
|
155
|
+
export function find( context: Element ): HTMLElement[] {
|
|
147
156
|
return filterTabbable( findFocusable( context ) );
|
|
148
157
|
}
|
|
149
158
|
|
|
150
159
|
/**
|
|
151
160
|
* Given a focusable element, find the preceding tabbable element.
|
|
152
161
|
*
|
|
153
|
-
* @param
|
|
154
|
-
*
|
|
162
|
+
* @param element The focusable element before which to look. Defaults
|
|
163
|
+
* to the active element.
|
|
155
164
|
*
|
|
156
|
-
* @return
|
|
165
|
+
* @return Preceding tabbable element.
|
|
157
166
|
*/
|
|
158
|
-
export function findPrevious( element ) {
|
|
167
|
+
export function findPrevious( element: Element ): HTMLElement | undefined {
|
|
159
168
|
return filterTabbable( findFocusable( element.ownerDocument.body ) )
|
|
160
169
|
.reverse()
|
|
161
170
|
.find(
|
|
@@ -169,12 +178,12 @@ export function findPrevious( element ) {
|
|
|
169
178
|
/**
|
|
170
179
|
* Given a focusable element, find the next tabbable element.
|
|
171
180
|
*
|
|
172
|
-
* @param
|
|
173
|
-
*
|
|
181
|
+
* @param element The focusable element after which to look. Defaults
|
|
182
|
+
* to the active element.
|
|
174
183
|
*
|
|
175
|
-
* @return
|
|
184
|
+
* @return Next tabbable element.
|
|
176
185
|
*/
|
|
177
|
-
export function findNext( element ) {
|
|
186
|
+
export function findNext( element: Element ): HTMLElement | undefined {
|
|
178
187
|
return filterTabbable( findFocusable( element.ownerDocument.body ) ).find(
|
|
179
188
|
( focusable ) =>
|
|
180
189
|
// eslint-disable-next-line no-bitwise
|
|
@@ -5,11 +5,12 @@ import {
|
|
|
5
5
|
isTextField,
|
|
6
6
|
removeInvalidHTML,
|
|
7
7
|
isEmpty,
|
|
8
|
+
getOffsetParent,
|
|
8
9
|
} from '../dom';
|
|
9
10
|
import { getPhrasingContentSchema } from '../phrasing-content';
|
|
10
11
|
|
|
11
12
|
describe( 'DOM', () => {
|
|
12
|
-
let parent;
|
|
13
|
+
let parent: HTMLDivElement;
|
|
13
14
|
|
|
14
15
|
beforeEach( () => {
|
|
15
16
|
parent = document.createElement( 'div' );
|
|
@@ -109,9 +110,8 @@ describe( 'DOM', () => {
|
|
|
109
110
|
/**
|
|
110
111
|
* A sampling of input types expected not to be text eligible.
|
|
111
112
|
*
|
|
112
|
-
* @type {string[]}
|
|
113
113
|
*/
|
|
114
|
-
const NON_TEXT_INPUT_TYPES = [
|
|
114
|
+
const NON_TEXT_INPUT_TYPES: string[] = [
|
|
115
115
|
'button',
|
|
116
116
|
'checkbox',
|
|
117
117
|
'hidden',
|
|
@@ -128,9 +128,13 @@ describe( 'DOM', () => {
|
|
|
128
128
|
/**
|
|
129
129
|
* A sampling of input types expected to be text eligible.
|
|
130
130
|
*
|
|
131
|
-
* @type {string[]}
|
|
132
131
|
*/
|
|
133
|
-
const TEXT_INPUT_TYPES = [
|
|
132
|
+
const TEXT_INPUT_TYPES: string[] = [
|
|
133
|
+
'text',
|
|
134
|
+
'password',
|
|
135
|
+
'search',
|
|
136
|
+
'url',
|
|
137
|
+
];
|
|
134
138
|
|
|
135
139
|
it( 'should return false for non-text input elements', () => {
|
|
136
140
|
NON_TEXT_INPUT_TYPES.forEach( ( type ) => {
|
|
@@ -170,6 +174,26 @@ describe( 'DOM', () => {
|
|
|
170
174
|
);
|
|
171
175
|
} );
|
|
172
176
|
} );
|
|
177
|
+
|
|
178
|
+
describe( 'getOffsetParent', () => {
|
|
179
|
+
it( 'should return the closest element when it is positioned', () => {
|
|
180
|
+
parent.style.position = 'relative';
|
|
181
|
+
const text = document.createTextNode( 'text' );
|
|
182
|
+
parent.appendChild( text );
|
|
183
|
+
|
|
184
|
+
expect( getOffsetParent( text ) ).toBe( parent );
|
|
185
|
+
} );
|
|
186
|
+
|
|
187
|
+
it( 'should return null when no ancestor is an element', () => {
|
|
188
|
+
expect( getOffsetParent( document.documentElement ) ).toBe( null );
|
|
189
|
+
|
|
190
|
+
const fragment = document.createDocumentFragment();
|
|
191
|
+
const text = document.createTextNode( 'text' );
|
|
192
|
+
fragment.appendChild( text );
|
|
193
|
+
|
|
194
|
+
expect( getOffsetParent( text ) ).toBe( null );
|
|
195
|
+
} );
|
|
196
|
+
} );
|
|
173
197
|
} );
|
|
174
198
|
|
|
175
199
|
describe( 'removeInvalidHTML', () => {
|
|
@@ -304,7 +328,7 @@ describe( 'removeInvalidHTML', () => {
|
|
|
304
328
|
} );
|
|
305
329
|
|
|
306
330
|
describe( 'isEmpty', () => {
|
|
307
|
-
function isEmptyHTML( HTML ) {
|
|
331
|
+
function isEmptyHTML( HTML: string ) {
|
|
308
332
|
const doc = document.implementation.createHTMLDocument( '' );
|
|
309
333
|
|
|
310
334
|
doc.body.innerHTML = HTML;
|
|
@@ -2,7 +2,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
|
2
2
|
import { find } from '../focusable';
|
|
3
3
|
|
|
4
4
|
describe( 'focusable.find() CSS visibility', () => {
|
|
5
|
-
let node;
|
|
5
|
+
let node: HTMLDivElement;
|
|
6
6
|
|
|
7
7
|
beforeEach( () => {
|
|
8
8
|
node = document.createElement( 'div' );
|
|
@@ -28,7 +28,7 @@ describe( 'focusable.find() CSS visibility', () => {
|
|
|
28
28
|
'excludes inputs with %s even when they have layout boxes',
|
|
29
29
|
( _, html ) => {
|
|
30
30
|
node.innerHTML = html;
|
|
31
|
-
const input = node.querySelector( 'input' )
|
|
31
|
+
const input = node.querySelector( 'input' )!;
|
|
32
32
|
const checkVisibility = vi.spyOn( input, 'checkVisibility' );
|
|
33
33
|
|
|
34
34
|
expect( input.offsetWidth ).toBeGreaterThan( 0 );
|
|
@@ -46,7 +46,7 @@ describe( 'focusable.find() CSS visibility', () => {
|
|
|
46
46
|
it( 'includes inputs that restore visibility inside a hidden ancestor', () => {
|
|
47
47
|
node.style.visibility = 'hidden';
|
|
48
48
|
node.innerHTML = '<input style="visibility: visible">';
|
|
49
|
-
const input = node.querySelector( 'input' )
|
|
49
|
+
const input = node.querySelector( 'input' )!;
|
|
50
50
|
|
|
51
51
|
input.focus();
|
|
52
52
|
expect( input ).toHaveFocus();
|
|
@@ -56,7 +56,7 @@ describe( 'focusable.find() CSS visibility', () => {
|
|
|
56
56
|
it( 'uses the owning window for the computed-style fallback', () => {
|
|
57
57
|
const iframe = document.createElement( 'iframe' );
|
|
58
58
|
node.appendChild( iframe );
|
|
59
|
-
const iframeDocument = iframe.contentDocument
|
|
59
|
+
const iframeDocument = iframe.contentDocument!;
|
|
60
60
|
iframeDocument.body.innerHTML = `
|
|
61
61
|
<div style="visibility: hidden">
|
|
62
62
|
<input>
|
|
@@ -72,7 +72,7 @@ describe( 'focusable.find() CSS visibility', () => {
|
|
|
72
72
|
checkVisibility: { value: undefined },
|
|
73
73
|
} );
|
|
74
74
|
const getComputedStyle = vi.spyOn(
|
|
75
|
-
iframeDocument.defaultView
|
|
75
|
+
iframeDocument.defaultView!,
|
|
76
76
|
'getComputedStyle'
|
|
77
77
|
);
|
|
78
78
|
|
|
@@ -82,11 +82,12 @@ describe( 'focusable.find() CSS visibility', () => {
|
|
|
82
82
|
} );
|
|
83
83
|
} );
|
|
84
84
|
|
|
85
|
-
const createElement =
|
|
85
|
+
const createElement = < K extends keyof HTMLElementTagNameMap >( type: K ) =>
|
|
86
|
+
document.createElement( type );
|
|
86
87
|
const IMAGE_SOURCE =
|
|
87
88
|
'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
|
|
88
89
|
|
|
89
|
-
function findFocusable( context ) {
|
|
90
|
+
function findFocusable( context: Element ) {
|
|
90
91
|
if ( ! context.isConnected ) {
|
|
91
92
|
document.body.appendChild( context );
|
|
92
93
|
}
|
|
@@ -125,7 +126,7 @@ describe( 'focusable', () => {
|
|
|
125
126
|
it( 'finds nested focusable child', () => {
|
|
126
127
|
const node = createElement( 'div' );
|
|
127
128
|
node.appendChild( createElement( 'div' ) );
|
|
128
|
-
node.firstChild
|
|
129
|
+
node.firstChild!.appendChild( createElement( 'input' ) );
|
|
129
130
|
|
|
130
131
|
const focusable = findFocusable( node );
|
|
131
132
|
|
|
@@ -150,8 +151,8 @@ describe( 'focusable', () => {
|
|
|
150
151
|
</map>
|
|
151
152
|
<img src="${ IMAGE_SOURCE }" usemap="#testfocus" width="40" height="40" alt="">
|
|
152
153
|
`;
|
|
153
|
-
const area = node.querySelector( 'area' )
|
|
154
|
-
const image = node.querySelector( 'img' )
|
|
154
|
+
const area = node.querySelector( 'area' )!;
|
|
155
|
+
const image = node.querySelector( 'img' )!;
|
|
155
156
|
|
|
156
157
|
document.body.appendChild( node );
|
|
157
158
|
await image.decode();
|
|
@@ -171,7 +172,7 @@ describe( 'focusable', () => {
|
|
|
171
172
|
</map>
|
|
172
173
|
<img src="${ IMAGE_SOURCE }" usemap="#testfocus" width="40" height="40" alt="" style="visibility: hidden">
|
|
173
174
|
`;
|
|
174
|
-
const image = node.querySelector( 'img' )
|
|
175
|
+
const image = node.querySelector( 'img' )!;
|
|
175
176
|
|
|
176
177
|
document.body.appendChild( node );
|
|
177
178
|
|
|
@@ -203,8 +204,8 @@ describe( 'focusable', () => {
|
|
|
203
204
|
</div>
|
|
204
205
|
<img src="${ IMAGE_SOURCE }" usemap="#testfocus" width="40" height="40" alt="">
|
|
205
206
|
`;
|
|
206
|
-
const area = node.querySelector( 'area' )
|
|
207
|
-
const image = node.querySelector( 'img' )
|
|
207
|
+
const area = node.querySelector( 'area' )!;
|
|
208
|
+
const image = node.querySelector( 'img' )!;
|
|
208
209
|
|
|
209
210
|
document.body.appendChild( node );
|
|
210
211
|
await image.decode();
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, it } from 'vitest';
|
|
2
2
|
import { find } from '../tabbable';
|
|
3
3
|
|
|
4
|
-
const createElement =
|
|
4
|
+
const createElement = < K extends keyof HTMLElementTagNameMap >( type: K ) =>
|
|
5
|
+
document.createElement( type );
|
|
5
6
|
|
|
6
|
-
function findTabbable( context ) {
|
|
7
|
+
function findTabbable( context: Element ) {
|
|
7
8
|
document.body.appendChild( context );
|
|
8
9
|
return find( context );
|
|
9
10
|
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface SemanticElementDefinition {
|
|
2
|
+
/**
|
|
3
|
+
* Content attributes
|
|
4
|
+
*/
|
|
5
|
+
attributes?: string[];
|
|
6
|
+
/**
|
|
7
|
+
* Allowed child elements, or `'*'` for any
|
|
8
|
+
*/
|
|
9
|
+
children?: ContentSchema | '*';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type ContentSchema = Record< string, SemanticElementDefinition >;
|
|
13
|
+
|
|
14
|
+
export interface FindFocusableOptions {
|
|
15
|
+
/**
|
|
16
|
+
* If set, only return elements that are sequentially focusable.
|
|
17
|
+
* Non-interactive elements with a negative `tabindex` are focusable but
|
|
18
|
+
* not sequentially focusable.
|
|
19
|
+
*/
|
|
20
|
+
sequential?: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type MaybeHTMLInputElement = HTMLElement & {
|
|
24
|
+
type?: string;
|
|
25
|
+
checked?: boolean;
|
|
26
|
+
name?: string;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export interface ObjectTabbable {
|
|
30
|
+
element: HTMLElement;
|
|
31
|
+
index: number;
|
|
32
|
+
}
|