@wordpress/dom 5.0.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 +1 -1
- 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 +87 -132
- package/build/dom/clean-node-list.cjs.map +1 -7
- package/build/dom/compute-caret-rect.cjs +35 -35
- package/build/dom/compute-caret-rect.cjs.map +1 -7
- package/build/dom/document-has-selection.cjs +35 -30
- 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 +34 -29
- 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 +40 -39
- 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 -128
- package/build/dom/get-rectangle-from-range.cjs.map +1 -7
- package/build/dom/get-scroll-container.cjs +46 -50
- package/build/dom/get-scroll-container.cjs.map +1 -7
- package/build/dom/hidden-caret-range-from-point.cjs +48 -42
- 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 +48 -43
- 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 +82 -97
- 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 -37
- package/build/dom/is-empty.cjs.map +1 -7
- package/build/dom/is-entirely-selected.cjs +70 -67
- package/build/dom/is-entirely-selected.cjs.map +1 -7
- package/build/dom/is-form-element.cjs +33 -33
- package/build/dom/is-form-element.cjs.map +1 -7
- package/build/dom/is-horizontal-edge.cjs +31 -28
- 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 +36 -33
- package/build/dom/is-number-input.cjs.map +1 -7
- package/build/dom/is-rtl.cjs +30 -28
- 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 +45 -42
- package/build/dom/is-text-field.cjs.map +1 -7
- package/build/dom/is-vertical-edge.cjs +31 -28
- package/build/dom/is-vertical-edge.cjs.map +1 -7
- package/build/dom/place-caret-at-edge.cjs +75 -78
- package/build/dom/place-caret-at-edge.cjs.map +1 -7
- package/build/dom/place-caret-at-horizontal-edge.cjs +29 -28
- package/build/dom/place-caret-at-horizontal-edge.cjs.map +1 -7
- package/build/dom/place-caret-at-vertical-edge.cjs +30 -28
- package/build/dom/place-caret-at-vertical-edge.cjs.map +1 -7
- package/build/dom/remove-invalid-html.cjs +35 -31
- 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 +34 -32
- package/build/dom/replace.cjs.map +1 -7
- package/build/dom/safe-html.cjs +45 -46
- 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 +33 -31
- package/build/dom/strip-html.cjs.map +1 -7
- package/build/dom/types.cjs +4 -18
- 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 -76
- package/build/focusable.cjs.map +1 -7
- package/build/index.cjs +57 -38
- 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 +4 -18
- 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 +16 -14
- package/build-module/data-transfer.mjs.map +1 -7
- package/build-module/dom/caret-range-from-point.mjs +27 -18
- 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 +20 -16
- package/build-module/dom/get-offset-parent.mjs.map +1 -7
- package/build-module/dom/get-range-height.mjs +14 -11
- package/build-module/dom/get-range-height.mjs.map +1 -7
- package/build-module/dom/get-rectangle-from-range.mjs +78 -108
- package/build-module/dom/get-rectangle-from-range.mjs.map +1 -7
- package/build-module/dom/get-scroll-container.mjs +28 -28
- 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 -20
- 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 +8 -5
- package/build-module/dom/is-element.mjs.map +1 -7
- package/build-module/dom/is-empty.mjs +19 -17
- package/build-module/dom/is-empty.mjs.map +1 -7
- package/build-module/dom/is-entirely-selected.mjs +51 -44
- 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 +8 -5
- package/build-module/dom/is-html-input-element.mjs.map +1 -7
- package/build-module/dom/is-input-or-text-area.mjs +8 -5
- 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 -20
- 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 +20 -13
- 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 -1
- 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 +95 -52
- 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 +157 -133
- package/build-module/phrasing-content.mjs.map +1 -7
- package/build-module/tabbable.mjs +116 -51
- package/build-module/tabbable.mjs.map +1 -7
- package/build-module/types.mjs +0 -1
- package/build-module/utils/assert-is-defined.mjs +4 -9
- package/build-module/utils/assert-is-defined.mjs.map +1 -7
- package/build-types/dom/clean-node-list.d.ts +2 -2
- package/build-types/dom/clean-node-list.d.ts.map +1 -1
- package/build-types/dom/is-edge.d.ts.map +1 -1
- package/build-types/dom/remove-invalid-html.d.ts +4 -4
- package/build-types/dom/remove-invalid-html.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/dom/clean-node-list.ts +2 -2
- package/src/dom/is-edge.ts +35 -43
- package/src/dom/remove-invalid-html.ts +4 -4
- package/src/dom/test/{get-rectangle-from-range.browser.test.js → get-rectangle-from-range.browser.test.ts} +25 -25
- package/src/test/{dom.jsdom.test.js → dom.jsdom.test.ts} +9 -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/build/dom/index.cjs.map +0 -7
- package/build/dom/types.cjs.map +0 -7
- package/build/types.cjs.map +0 -7
- package/build-module/dom/index.mjs.map +0 -7
- package/build-module/dom/types.mjs.map +0 -7
- package/build-module/types.mjs.map +0 -7
- /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,27 +1,30 @@
|
|
|
1
|
-
// packages/dom/src/dom/safe-html.ts
|
|
2
1
|
import remove from "./remove.mjs";
|
|
2
|
+
// packages/dom/src/dom/safe-html.ts
|
|
3
|
+
/**
|
|
4
|
+
* Strips scripts and on* attributes from HTML.
|
|
5
|
+
*
|
|
6
|
+
* @param html HTML to sanitize.
|
|
7
|
+
*
|
|
8
|
+
* @return The sanitized HTML.
|
|
9
|
+
*/
|
|
3
10
|
function safeHTML(html) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
return body.innerHTML;
|
|
11
|
+
const { body } = document.implementation.createHTMLDocument("");
|
|
12
|
+
body.innerHTML = html;
|
|
13
|
+
const elements = body.getElementsByTagName("*");
|
|
14
|
+
let elementIndex = elements.length;
|
|
15
|
+
while (elementIndex--) {
|
|
16
|
+
const element = elements[elementIndex];
|
|
17
|
+
if (element.tagName === "SCRIPT") remove(element);
|
|
18
|
+
else {
|
|
19
|
+
let attributeIndex = element.attributes.length;
|
|
20
|
+
while (attributeIndex--) {
|
|
21
|
+
const { name: key } = element.attributes[attributeIndex];
|
|
22
|
+
if (key.startsWith("on")) element.removeAttribute(key);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return body.innerHTML;
|
|
23
27
|
}
|
|
24
|
-
export {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
//# sourceMappingURL=safe-html.mjs.map
|
|
28
|
+
export { safeHTML as default };
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=safe-html.mjs.map
|
|
@@ -1,7 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/dom/safe-html.ts"],
|
|
4
|
-
"sourcesContent": ["import remove from './remove';\n\n/**\n * Strips scripts and on* attributes from HTML.\n *\n * @param html HTML to sanitize.\n *\n * @return The sanitized HTML.\n */\nexport default function safeHTML( html: string ): string {\n\tconst { body } = document.implementation.createHTMLDocument( '' );\n\tbody.innerHTML = html;\n\tconst elements = body.getElementsByTagName( '*' );\n\tlet elementIndex = elements.length;\n\n\twhile ( elementIndex-- ) {\n\t\tconst element = elements[ elementIndex ];\n\n\t\tif ( element.tagName === 'SCRIPT' ) {\n\t\t\tremove( element );\n\t\t} else {\n\t\t\tlet attributeIndex = element.attributes.length;\n\n\t\t\twhile ( attributeIndex-- ) {\n\t\t\t\tconst { name: key } = element.attributes[ attributeIndex ];\n\n\t\t\t\tif ( key.startsWith( 'on' ) ) {\n\t\t\t\t\telement.removeAttribute( key );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn body.innerHTML;\n}\n"],
|
|
5
|
-
"mappings": ";AAAA,OAAO,YAAY;AASJ,SAAR,SAA2B,MAAuB;AACxD,QAAM,EAAE,KAAK,IAAI,SAAS,eAAe,mBAAoB,EAAG;AAChE,OAAK,YAAY;AACjB,QAAM,WAAW,KAAK,qBAAsB,GAAI;AAChD,MAAI,eAAe,SAAS;AAE5B,SAAQ,gBAAiB;AACxB,UAAM,UAAU,SAAU,YAAa;AAEvC,QAAK,QAAQ,YAAY,UAAW;AACnC,aAAQ,OAAQ;AAAA,IACjB,OAAO;AACN,UAAI,iBAAiB,QAAQ,WAAW;AAExC,aAAQ,kBAAmB;AAC1B,cAAM,EAAE,MAAM,IAAI,IAAI,QAAQ,WAAY,cAAe;AAEzD,YAAK,IAAI,WAAY,IAAK,GAAI;AAC7B,kBAAQ,gBAAiB,GAAI;AAAA,QAC9B;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAEA,SAAO,KAAK;AACb;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
1
|
+
{"version":3,"file":"safe-html.mjs","names":[],"sources":["../../src/dom/safe-html.ts"],"sourcesContent":["import remove from './remove';\n\n/**\n * Strips scripts and on* attributes from HTML.\n *\n * @param html HTML to sanitize.\n *\n * @return The sanitized HTML.\n */\nexport default function safeHTML( html: string ): string {\n\tconst { body } = document.implementation.createHTMLDocument( '' );\n\tbody.innerHTML = html;\n\tconst elements = body.getElementsByTagName( '*' );\n\tlet elementIndex = elements.length;\n\n\twhile ( elementIndex-- ) {\n\t\tconst element = elements[ elementIndex ];\n\n\t\tif ( element.tagName === 'SCRIPT' ) {\n\t\t\tremove( element );\n\t\t} else {\n\t\t\tlet attributeIndex = element.attributes.length;\n\n\t\t\twhile ( attributeIndex-- ) {\n\t\t\t\tconst { name: key } = element.attributes[ attributeIndex ];\n\n\t\t\t\tif ( key.startsWith( 'on' ) ) {\n\t\t\t\t\telement.removeAttribute( key );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn body.innerHTML;\n}\n"],"mappings":";;;;;;;;;AASA,SAAwB,SAAU,MAAuB;CACxD,MAAM,EAAE,SAAS,SAAS,eAAe,mBAAoB,EAAG;CAChE,KAAK,YAAY;CACjB,MAAM,WAAW,KAAK,qBAAsB,GAAI;CAChD,IAAI,eAAe,SAAS;CAE5B,OAAQ,gBAAiB;EACxB,MAAM,UAAU,SAAU;EAE1B,IAAK,QAAQ,YAAY,UACxB,OAAQ,OAAQ;OACV;GACN,IAAI,iBAAiB,QAAQ,WAAW;GAExC,OAAQ,kBAAmB;IAC1B,MAAM,EAAE,MAAM,QAAQ,QAAQ,WAAY;IAE1C,IAAK,IAAI,WAAY,IAAK,GACzB,QAAQ,gBAAiB,GAAI;GAE/B;EACD;CACD;CAEA,OAAO,KAAK;AACb"}
|
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
// packages/dom/src/dom/scroll-if-no-range.ts
|
|
2
|
+
/**
|
|
3
|
+
* If no range range can be created or it is outside the container, the element
|
|
4
|
+
* may be out of view, so scroll it into view and try again.
|
|
5
|
+
*
|
|
6
|
+
* @param container The container to scroll.
|
|
7
|
+
* @param alignToTop True to align to top, false to bottom.
|
|
8
|
+
* @param callback The callback to create the range.
|
|
9
|
+
*
|
|
10
|
+
* @return The range returned by the callback.
|
|
11
|
+
*/
|
|
2
12
|
function scrollIfNoRange(container, alignToTop, callback) {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
return range;
|
|
13
|
+
let range = callback();
|
|
14
|
+
if (!range || !range.startContainer || !container.contains(range.startContainer)) {
|
|
15
|
+
container.scrollIntoView(alignToTop);
|
|
16
|
+
range = callback();
|
|
17
|
+
if (!range || !range.startContainer || !container.contains(range.startContainer)) return null;
|
|
18
|
+
}
|
|
19
|
+
return range;
|
|
12
20
|
}
|
|
13
|
-
export {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
//# sourceMappingURL=scroll-if-no-range.mjs.map
|
|
21
|
+
export { scrollIfNoRange };
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=scroll-if-no-range.mjs.map
|
|
@@ -1,7 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/dom/scroll-if-no-range.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * If no range range can be created or it is outside the container, the element\n * may be out of view, so scroll it into view and try again.\n *\n * @param container The container to scroll.\n * @param alignToTop True to align to top, false to bottom.\n * @param callback The callback to create the range.\n *\n * @return The range returned by the callback.\n */\nexport function scrollIfNoRange(\n\tcontainer: HTMLElement,\n\talignToTop: boolean,\n\tcallback: () => Range | null\n): Range | null {\n\tlet range = callback();\n\n\t// If no range range can be created or it is outside the container, the\n\t// element may be out of view.\n\tif (\n\t\t! range ||\n\t\t! range.startContainer ||\n\t\t! container.contains( range.startContainer )\n\t) {\n\t\tcontainer.scrollIntoView( alignToTop );\n\t\trange = callback();\n\n\t\tif (\n\t\t\t! range ||\n\t\t\t! range.startContainer ||\n\t\t\t! container.contains( range.startContainer )\n\t\t) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\treturn range;\n}\n"],
|
|
5
|
-
"mappings": ";AAUO,SAAS,gBACf,WACA,YACA,UACe;AACf,MAAI,QAAQ,SAAS;AAIrB,MACC,CAAE,SACF,CAAE,MAAM,kBACR,CAAE,UAAU,SAAU,MAAM,cAAe,GAC1C;AACD,cAAU,eAAgB,UAAW;AACrC,YAAQ,SAAS;AAEjB,QACC,CAAE,SACF,CAAE,MAAM,kBACR,CAAE,UAAU,SAAU,MAAM,cAAe,GAC1C;AACD,aAAO;AAAA,IACR;AAAA,EACD;AAEA,SAAO;AACR;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
1
|
+
{"version":3,"file":"scroll-if-no-range.mjs","names":[],"sources":["../../src/dom/scroll-if-no-range.ts"],"sourcesContent":["/**\n * If no range range can be created or it is outside the container, the element\n * may be out of view, so scroll it into view and try again.\n *\n * @param container The container to scroll.\n * @param alignToTop True to align to top, false to bottom.\n * @param callback The callback to create the range.\n *\n * @return The range returned by the callback.\n */\nexport function scrollIfNoRange(\n\tcontainer: HTMLElement,\n\talignToTop: boolean,\n\tcallback: () => Range | null\n): Range | null {\n\tlet range = callback();\n\n\t// If no range range can be created or it is outside the container, the\n\t// element may be out of view.\n\tif (\n\t\t! range ||\n\t\t! range.startContainer ||\n\t\t! container.contains( range.startContainer )\n\t) {\n\t\tcontainer.scrollIntoView( alignToTop );\n\t\trange = callback();\n\n\t\tif (\n\t\t\t! range ||\n\t\t\t! range.startContainer ||\n\t\t\t! container.contains( range.startContainer )\n\t\t) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\treturn range;\n}\n"],"mappings":";;;;;;;;;;;AAUA,SAAgB,gBACf,WACA,YACA,UACe;CACf,IAAI,QAAQ,SAAS;CAIrB,IACC,CAAE,SACF,CAAE,MAAM,kBACR,CAAE,UAAU,SAAU,MAAM,cAAe,GAC1C;EACD,UAAU,eAAgB,UAAW;EACrC,QAAQ,SAAS;EAEjB,IACC,CAAE,SACF,CAAE,MAAM,kBACR,CAAE,UAAU,SAAU,MAAM,cAAe,GAE3C,OAAO;CAET;CAEA,OAAO;AACR"}
|
|
@@ -1,12 +1,18 @@
|
|
|
1
|
-
// packages/dom/src/dom/strip-html.ts
|
|
2
1
|
import safeHTML from "./safe-html.mjs";
|
|
2
|
+
// packages/dom/src/dom/strip-html.ts
|
|
3
|
+
/**
|
|
4
|
+
* Removes any HTML tags from the provided string.
|
|
5
|
+
*
|
|
6
|
+
* @param html The string containing html.
|
|
7
|
+
*
|
|
8
|
+
* @return The text content with any html removed.
|
|
9
|
+
*/
|
|
3
10
|
function stripHTML(html) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
11
|
+
html = safeHTML(html);
|
|
12
|
+
const doc = document.implementation.createHTMLDocument("");
|
|
13
|
+
doc.body.innerHTML = html;
|
|
14
|
+
return doc.body.textContent || "";
|
|
8
15
|
}
|
|
9
|
-
export {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
//# sourceMappingURL=strip-html.mjs.map
|
|
16
|
+
export { stripHTML as default };
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=strip-html.mjs.map
|
|
@@ -1,7 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/dom/strip-html.ts"],
|
|
4
|
-
"sourcesContent": ["import safeHTML from './safe-html';\n\n/**\n * Removes any HTML tags from the provided string.\n *\n * @param html The string containing html.\n *\n * @return The text content with any html removed.\n */\nexport default function stripHTML( html: string ): string {\n\t// Remove any script tags or on* attributes otherwise their *contents* will be left\n\t// in place following removal of HTML tags.\n\thtml = safeHTML( html );\n\n\tconst doc = document.implementation.createHTMLDocument( '' );\n\tdoc.body.innerHTML = html;\n\treturn doc.body.textContent || '';\n}\n"],
|
|
5
|
-
"mappings": ";AAAA,OAAO,cAAc;AASN,SAAR,UAA4B,MAAuB;AAGzD,SAAO,SAAU,IAAK;AAEtB,QAAM,MAAM,SAAS,eAAe,mBAAoB,EAAG;AAC3D,MAAI,KAAK,YAAY;AACrB,SAAO,IAAI,KAAK,eAAe;AAChC;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
1
|
+
{"version":3,"file":"strip-html.mjs","names":[],"sources":["../../src/dom/strip-html.ts"],"sourcesContent":["import safeHTML from './safe-html';\n\n/**\n * Removes any HTML tags from the provided string.\n *\n * @param html The string containing html.\n *\n * @return The text content with any html removed.\n */\nexport default function stripHTML( html: string ): string {\n\t// Remove any script tags or on* attributes otherwise their *contents* will be left\n\t// in place following removal of HTML tags.\n\thtml = safeHTML( html );\n\n\tconst doc = document.implementation.createHTMLDocument( '' );\n\tdoc.body.innerHTML = html;\n\treturn doc.body.textContent || '';\n}\n"],"mappings":";;;;;;;;;AASA,SAAwB,UAAW,MAAuB;CAGzD,OAAO,SAAU,IAAK;CAEtB,MAAM,MAAM,SAAS,eAAe,mBAAoB,EAAG;CAC3D,IAAI,KAAK,YAAY;CACrB,OAAO,IAAI,KAAK,eAAe;AAChC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=types.mjs.map
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
// packages/dom/src/dom/unwrap.ts
|
|
2
1
|
import { assertIsDefined } from "../utils/assert-is-defined.mjs";
|
|
2
|
+
// packages/dom/src/dom/unwrap.ts
|
|
3
|
+
/**
|
|
4
|
+
* Unwrap the given node. This means any child nodes are moved to the parent.
|
|
5
|
+
*
|
|
6
|
+
* @param node The node to unwrap.
|
|
7
|
+
*/
|
|
3
8
|
function unwrap(node) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
parent.removeChild(node);
|
|
9
|
+
const parent = node.parentNode;
|
|
10
|
+
assertIsDefined(parent, "node.parentNode");
|
|
11
|
+
while (node.firstChild) parent.insertBefore(node.firstChild, node);
|
|
12
|
+
parent.removeChild(node);
|
|
10
13
|
}
|
|
11
|
-
export {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
//# sourceMappingURL=unwrap.mjs.map
|
|
14
|
+
export { unwrap as default };
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=unwrap.mjs.map
|
|
@@ -1,7 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/dom/unwrap.ts"],
|
|
4
|
-
"sourcesContent": ["import { assertIsDefined } from '../utils/assert-is-defined';\n\n/**\n * Unwrap the given node. This means any child nodes are moved to the parent.\n *\n * @param node The node to unwrap.\n */\nexport default function unwrap( node: Node ): void {\n\tconst parent = node.parentNode;\n\n\tassertIsDefined( parent, 'node.parentNode' );\n\n\twhile ( node.firstChild ) {\n\t\tparent.insertBefore( node.firstChild, node );\n\t}\n\n\tparent.removeChild( node );\n}\n"],
|
|
5
|
-
"mappings": ";AAAA,SAAS,uBAAuB;AAOjB,SAAR,OAAyB,MAAmB;AAClD,QAAM,SAAS,KAAK;AAEpB,kBAAiB,QAAQ,iBAAkB;AAE3C,SAAQ,KAAK,YAAa;AACzB,WAAO,aAAc,KAAK,YAAY,IAAK;AAAA,EAC5C;AAEA,SAAO,YAAa,IAAK;AAC1B;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
1
|
+
{"version":3,"file":"unwrap.mjs","names":[],"sources":["../../src/dom/unwrap.ts"],"sourcesContent":["import { assertIsDefined } from '../utils/assert-is-defined';\n\n/**\n * Unwrap the given node. This means any child nodes are moved to the parent.\n *\n * @param node The node to unwrap.\n */\nexport default function unwrap( node: Node ): void {\n\tconst parent = node.parentNode;\n\n\tassertIsDefined( parent, 'node.parentNode' );\n\n\twhile ( node.firstChild ) {\n\t\tparent.insertBefore( node.firstChild, node );\n\t}\n\n\tparent.removeChild( node );\n}\n"],"mappings":";;;;;;;AAOA,SAAwB,OAAQ,MAAmB;CAClD,MAAM,SAAS,KAAK;CAEpB,gBAAiB,QAAQ,iBAAkB;CAE3C,OAAQ,KAAK,YACZ,OAAO,aAAc,KAAK,YAAY,IAAK;CAG5C,OAAO,YAAa,IAAK;AAC1B"}
|
|
@@ -1,11 +1,16 @@
|
|
|
1
|
-
// packages/dom/src/dom/wrap.ts
|
|
2
1
|
import { assertIsDefined } from "../utils/assert-is-defined.mjs";
|
|
2
|
+
// packages/dom/src/dom/wrap.ts
|
|
3
|
+
/**
|
|
4
|
+
* Wraps the given node with a new node with the given tag name.
|
|
5
|
+
*
|
|
6
|
+
* @param newNode The node to insert.
|
|
7
|
+
* @param referenceNode The node to wrap.
|
|
8
|
+
*/
|
|
3
9
|
function wrap(newNode, referenceNode) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
10
|
+
assertIsDefined(referenceNode.parentNode, "referenceNode.parentNode");
|
|
11
|
+
referenceNode.parentNode.insertBefore(newNode, referenceNode);
|
|
12
|
+
newNode.appendChild(referenceNode);
|
|
7
13
|
}
|
|
8
|
-
export {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
//# sourceMappingURL=wrap.mjs.map
|
|
14
|
+
export { wrap as default };
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=wrap.mjs.map
|
|
@@ -1,7 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/dom/wrap.ts"],
|
|
4
|
-
"sourcesContent": ["import { assertIsDefined } from '../utils/assert-is-defined';\n\n/**\n * Wraps the given node with a new node with the given tag name.\n *\n * @param newNode The node to insert.\n * @param referenceNode The node to wrap.\n */\nexport default function wrap( newNode: Element, referenceNode: Element ) {\n\tassertIsDefined( referenceNode.parentNode, 'referenceNode.parentNode' );\n\treferenceNode.parentNode.insertBefore( newNode, referenceNode );\n\tnewNode.appendChild( referenceNode );\n}\n"],
|
|
5
|
-
"mappings": ";AAAA,SAAS,uBAAuB;AAQjB,SAAR,KAAuB,SAAkB,eAAyB;AACxE,kBAAiB,cAAc,YAAY,0BAA2B;AACtE,gBAAc,WAAW,aAAc,SAAS,aAAc;AAC9D,UAAQ,YAAa,aAAc;AACpC;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
1
|
+
{"version":3,"file":"wrap.mjs","names":[],"sources":["../../src/dom/wrap.ts"],"sourcesContent":["import { assertIsDefined } from '../utils/assert-is-defined';\n\n/**\n * Wraps the given node with a new node with the given tag name.\n *\n * @param newNode The node to insert.\n * @param referenceNode The node to wrap.\n */\nexport default function wrap( newNode: Element, referenceNode: Element ) {\n\tassertIsDefined( referenceNode.parentNode, 'referenceNode.parentNode' );\n\treferenceNode.parentNode.insertBefore( newNode, referenceNode );\n\tnewNode.appendChild( referenceNode );\n}\n"],"mappings":";;;;;;;;AAQA,SAAwB,KAAM,SAAkB,eAAyB;CACxE,gBAAiB,cAAc,YAAY,0BAA2B;CACtE,cAAc,WAAW,aAAc,SAAS,aAAc;CAC9D,QAAQ,YAAa,aAAc;AACpC"}
|
|
@@ -1,61 +1,104 @@
|
|
|
1
1
|
// packages/dom/src/focusable.ts
|
|
2
|
+
/**
|
|
3
|
+
* References:
|
|
4
|
+
*
|
|
5
|
+
* Focusable:
|
|
6
|
+
* - https://www.w3.org/TR/html5/editing.html#focus-management
|
|
7
|
+
*
|
|
8
|
+
* Sequential focus navigation:
|
|
9
|
+
* - https://www.w3.org/TR/html5/editing.html#sequential-focus-navigation-and-the-tabindex-attribute
|
|
10
|
+
*
|
|
11
|
+
* Disabled elements:
|
|
12
|
+
* - https://www.w3.org/TR/html5/disabled-elements.html#disabled-elements
|
|
13
|
+
*
|
|
14
|
+
* getClientRects algorithm (requiring layout box):
|
|
15
|
+
* - https://www.w3.org/TR/cssom-view-1/#extension-to-the-element-interface
|
|
16
|
+
*
|
|
17
|
+
* AREA elements associated with an IMG:
|
|
18
|
+
* - https://w3c.github.io/html/editing.html#data-model
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Returns a CSS selector used to query for focusable elements.
|
|
22
|
+
*
|
|
23
|
+
* @param sequential If set, only query elements that are sequentially
|
|
24
|
+
* focusable. Non-interactive elements with a
|
|
25
|
+
* negative `tabindex` are focusable but not
|
|
26
|
+
* sequentially focusable.
|
|
27
|
+
* https://html.spec.whatwg.org/multipage/interaction.html#the-tabindex-attribute
|
|
28
|
+
*
|
|
29
|
+
* @return CSS selector.
|
|
30
|
+
*/
|
|
2
31
|
function buildSelector(sequential) {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
32
|
+
return [
|
|
33
|
+
sequential ? "[tabindex]:not([tabindex^=\"-\"])" : "[tabindex]",
|
|
34
|
+
"a[href]",
|
|
35
|
+
"button:not([disabled])",
|
|
36
|
+
"input:not([type=\"hidden\"]):not([disabled])",
|
|
37
|
+
"select:not([disabled])",
|
|
38
|
+
"textarea:not([disabled])",
|
|
39
|
+
"iframe:not([tabindex^=\"-\"])",
|
|
40
|
+
"object",
|
|
41
|
+
"embed",
|
|
42
|
+
"summary",
|
|
43
|
+
"area[href]",
|
|
44
|
+
"[contenteditable]:not([contenteditable=false])"
|
|
45
|
+
].join(",");
|
|
17
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Returns true if the specified element has a layout box and is not hidden by
|
|
49
|
+
* CSS visibility or content visibility.
|
|
50
|
+
*
|
|
51
|
+
* @param element DOM element to test.
|
|
52
|
+
*
|
|
53
|
+
* @return Whether element is visible.
|
|
54
|
+
*/
|
|
18
55
|
function isVisible(element) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
).visibility;
|
|
27
|
-
if (visibility === "hidden" || visibility === "collapse") {
|
|
28
|
-
return false;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return element.offsetWidth > 0 || element.offsetHeight > 0 || element.getClientRects().length > 0;
|
|
56
|
+
if (typeof element.checkVisibility === "function") {
|
|
57
|
+
if (!element.checkVisibility({ visibilityProperty: true })) return false;
|
|
58
|
+
} else {
|
|
59
|
+
const visibility = element.ownerDocument.defaultView?.getComputedStyle(element).visibility;
|
|
60
|
+
if (visibility === "hidden" || visibility === "collapse") return false;
|
|
61
|
+
}
|
|
62
|
+
return element.offsetWidth > 0 || element.offsetHeight > 0 || element.getClientRects().length > 0;
|
|
32
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Returns true if the specified area element is a valid focusable element, or
|
|
66
|
+
* false otherwise. Area is only focusable if within a map where a named map
|
|
67
|
+
* referenced by an image somewhere in the document.
|
|
68
|
+
*
|
|
69
|
+
* @param element DOM area element to test.
|
|
70
|
+
*
|
|
71
|
+
* @return Whether area element is valid for focus.
|
|
72
|
+
*/
|
|
33
73
|
function isValidFocusableArea(element) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const img = element.ownerDocument.querySelector(
|
|
39
|
-
'img[usemap="#' + map.name + '"]'
|
|
40
|
-
);
|
|
41
|
-
return !!img && !img.closest("[inert]") && isVisible(img);
|
|
74
|
+
const map = element.closest("map[name]");
|
|
75
|
+
if (!map) return false;
|
|
76
|
+
const img = element.ownerDocument.querySelector("img[usemap=\"#" + map.name + "\"]");
|
|
77
|
+
return !!img && !img.closest("[inert]") && isVisible(img);
|
|
42
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Returns all focusable elements within a given context.
|
|
81
|
+
*
|
|
82
|
+
* @param context Element in which to search.
|
|
83
|
+
* @param options
|
|
84
|
+
* @param [options.sequential] If set, only return elements that are
|
|
85
|
+
* sequentially focusable.
|
|
86
|
+
* Non-interactive elements with a
|
|
87
|
+
* negative `tabindex` are focusable but
|
|
88
|
+
* not sequentially focusable.
|
|
89
|
+
* https://html.spec.whatwg.org/multipage/interaction.html#the-tabindex-attribute
|
|
90
|
+
*
|
|
91
|
+
* @return Focusable elements.
|
|
92
|
+
*/
|
|
43
93
|
function find(context, { sequential = false } = {}) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
if (element.closest("[inert]")) {
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
return isVisible(element);
|
|
56
|
-
});
|
|
94
|
+
const elements = context.querySelectorAll(buildSelector(sequential));
|
|
95
|
+
return Array.from(elements).filter((element) => {
|
|
96
|
+
const { nodeName } = element;
|
|
97
|
+
if ("AREA" === nodeName) return isValidFocusableArea(element);
|
|
98
|
+
if (element.closest("[inert]")) return false;
|
|
99
|
+
return isVisible(element);
|
|
100
|
+
});
|
|
57
101
|
}
|
|
58
|
-
export {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
//# sourceMappingURL=focusable.mjs.map
|
|
102
|
+
export { find };
|
|
103
|
+
|
|
104
|
+
//# sourceMappingURL=focusable.mjs.map
|
|
@@ -1,7 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/focusable.ts"],
|
|
4
|
-
"sourcesContent": ["import type { FindFocusableOptions } from './types';\n\n/**\n * References:\n *\n * Focusable:\n * - https://www.w3.org/TR/html5/editing.html#focus-management\n *\n * Sequential focus navigation:\n * - https://www.w3.org/TR/html5/editing.html#sequential-focus-navigation-and-the-tabindex-attribute\n *\n * Disabled elements:\n * - https://www.w3.org/TR/html5/disabled-elements.html#disabled-elements\n *\n * getClientRects algorithm (requiring layout box):\n * - https://www.w3.org/TR/cssom-view-1/#extension-to-the-element-interface\n *\n * AREA elements associated with an IMG:\n * - https://w3c.github.io/html/editing.html#data-model\n */\n\n/**\n * Returns a CSS selector used to query for focusable elements.\n *\n * @param sequential If set, only query elements that are sequentially\n * focusable. Non-interactive elements with a\n * negative `tabindex` are focusable but not\n * sequentially focusable.\n * https://html.spec.whatwg.org/multipage/interaction.html#the-tabindex-attribute\n *\n * @return CSS selector.\n */\nfunction buildSelector( sequential: boolean ): string {\n\treturn [\n\t\tsequential ? '[tabindex]:not([tabindex^=\"-\"])' : '[tabindex]',\n\t\t'a[href]',\n\t\t'button:not([disabled])',\n\t\t'input:not([type=\"hidden\"]):not([disabled])',\n\t\t'select:not([disabled])',\n\t\t'textarea:not([disabled])',\n\t\t'iframe:not([tabindex^=\"-\"])',\n\t\t'object',\n\t\t'embed',\n\t\t'summary',\n\t\t'area[href]',\n\t\t'[contenteditable]:not([contenteditable=false])',\n\t].join( ',' );\n}\n\n/**\n * Returns true if the specified element has a layout box and is not hidden by\n * CSS visibility or content visibility.\n *\n * @param element DOM element to test.\n *\n * @return Whether element is visible.\n */\nfunction isVisible( element: HTMLElement ): boolean {\n\tif ( typeof element.checkVisibility === 'function' ) {\n\t\tif ( ! element.checkVisibility( { visibilityProperty: true } ) ) {\n\t\t\treturn false;\n\t\t}\n\t} else {\n\t\tconst visibility =\n\t\t\telement.ownerDocument.defaultView?.getComputedStyle(\n\t\t\t\telement\n\t\t\t).visibility;\n\t\tif ( visibility === 'hidden' || visibility === 'collapse' ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn (\n\t\telement.offsetWidth > 0 ||\n\t\telement.offsetHeight > 0 ||\n\t\telement.getClientRects().length > 0\n\t);\n}\n\n/**\n * Returns true if the specified area element is a valid focusable element, or\n * false otherwise. Area is only focusable if within a map where a named map\n * referenced by an image somewhere in the document.\n *\n * @param element DOM area element to test.\n *\n * @return Whether area element is valid for focus.\n */\nfunction isValidFocusableArea( element: HTMLAreaElement ): boolean {\n\tconst map: HTMLMapElement | null = element.closest( 'map[name]' );\n\tif ( ! map ) {\n\t\treturn false;\n\t}\n\n\tconst img: HTMLImageElement | null = element.ownerDocument.querySelector(\n\t\t'img[usemap=\"#' + map.name + '\"]'\n\t);\n\treturn !! img && ! img.closest( '[inert]' ) && isVisible( img );\n}\n\n/**\n * Returns all focusable elements within a given context.\n *\n * @param context Element in which to search.\n * @param options\n * @param [options.sequential] If set, only return elements that are\n * sequentially focusable.\n * Non-interactive elements with a\n * negative `tabindex` are focusable but\n * not sequentially focusable.\n * https://html.spec.whatwg.org/multipage/interaction.html#the-tabindex-attribute\n *\n * @return Focusable elements.\n */\nexport function find(\n\tcontext: Element,\n\t{ sequential = false }: FindFocusableOptions = {}\n): HTMLElement[] {\n\tconst elements: NodeListOf< HTMLElement > = context.querySelectorAll(\n\t\tbuildSelector( sequential )\n\t);\n\n\treturn Array.from( elements ).filter( ( element ) => {\n\t\tconst { nodeName } = element;\n\t\tif ( 'AREA' === nodeName ) {\n\t\t\t// The mapped image determines whether this region is visible or inert.\n\t\t\treturn isValidFocusableArea( element as HTMLAreaElement );\n\t\t}\n\n\t\t// Elements inside an inert subtree are not focusable.\n\t\tif ( element.closest( '[inert]' ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn isVisible( element );\n\t} );\n}\n"],
|
|
5
|
-
"mappings": ";AAgCA,SAAS,cAAe,YAA8B;AACrD,SAAO;AAAA,IACN,aAAa,oCAAoC;AAAA,IACjD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,EAAE,KAAM,GAAI;AACb;AAUA,SAAS,UAAW,SAAgC;AACnD,MAAK,OAAO,QAAQ,oBAAoB,YAAa;AACpD,QAAK,CAAE,QAAQ,gBAAiB,EAAE,oBAAoB,KAAK,CAAE,GAAI;AAChE,aAAO;AAAA,IACR;AAAA,EACD,OAAO;AACN,UAAM,aACL,QAAQ,cAAc,aAAa;AAAA,MAClC;AAAA,IACD,EAAE;AACH,QAAK,eAAe,YAAY,eAAe,YAAa;AAC3D,aAAO;AAAA,IACR;AAAA,EACD;AAEA,SACC,QAAQ,cAAc,KACtB,QAAQ,eAAe,KACvB,QAAQ,eAAe,EAAE,SAAS;AAEpC;AAWA,SAAS,qBAAsB,SAAoC;AAClE,QAAM,MAA6B,QAAQ,QAAS,WAAY;AAChE,MAAK,CAAE,KAAM;AACZ,WAAO;AAAA,EACR;AAEA,QAAM,MAA+B,QAAQ,cAAc;AAAA,IAC1D,kBAAkB,IAAI,OAAO;AAAA,EAC9B;AACA,SAAO,CAAC,CAAE,OAAO,CAAE,IAAI,QAAS,SAAU,KAAK,UAAW,GAAI;AAC/D;AAgBO,SAAS,KACf,SACA,EAAE,aAAa,MAAM,IAA0B,CAAC,GAChC;AAChB,QAAM,WAAsC,QAAQ;AAAA,IACnD,cAAe,UAAW;AAAA,EAC3B;AAEA,SAAO,MAAM,KAAM,QAAS,EAAE,OAAQ,CAAE,YAAa;AACpD,UAAM,EAAE,SAAS,IAAI;AACrB,QAAK,WAAW,UAAW;AAE1B,aAAO,qBAAsB,OAA2B;AAAA,IACzD;AAGA,QAAK,QAAQ,QAAS,SAAU,GAAI;AACnC,aAAO;AAAA,IACR;AAEA,WAAO,UAAW,OAAQ;AAAA,EAC3B,CAAE;AACH;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
1
|
+
{"version":3,"file":"focusable.mjs","names":[],"sources":["../src/focusable.ts"],"sourcesContent":["import type { FindFocusableOptions } from './types';\n\n/**\n * References:\n *\n * Focusable:\n * - https://www.w3.org/TR/html5/editing.html#focus-management\n *\n * Sequential focus navigation:\n * - https://www.w3.org/TR/html5/editing.html#sequential-focus-navigation-and-the-tabindex-attribute\n *\n * Disabled elements:\n * - https://www.w3.org/TR/html5/disabled-elements.html#disabled-elements\n *\n * getClientRects algorithm (requiring layout box):\n * - https://www.w3.org/TR/cssom-view-1/#extension-to-the-element-interface\n *\n * AREA elements associated with an IMG:\n * - https://w3c.github.io/html/editing.html#data-model\n */\n\n/**\n * Returns a CSS selector used to query for focusable elements.\n *\n * @param sequential If set, only query elements that are sequentially\n * focusable. Non-interactive elements with a\n * negative `tabindex` are focusable but not\n * sequentially focusable.\n * https://html.spec.whatwg.org/multipage/interaction.html#the-tabindex-attribute\n *\n * @return CSS selector.\n */\nfunction buildSelector( sequential: boolean ): string {\n\treturn [\n\t\tsequential ? '[tabindex]:not([tabindex^=\"-\"])' : '[tabindex]',\n\t\t'a[href]',\n\t\t'button:not([disabled])',\n\t\t'input:not([type=\"hidden\"]):not([disabled])',\n\t\t'select:not([disabled])',\n\t\t'textarea:not([disabled])',\n\t\t'iframe:not([tabindex^=\"-\"])',\n\t\t'object',\n\t\t'embed',\n\t\t'summary',\n\t\t'area[href]',\n\t\t'[contenteditable]:not([contenteditable=false])',\n\t].join( ',' );\n}\n\n/**\n * Returns true if the specified element has a layout box and is not hidden by\n * CSS visibility or content visibility.\n *\n * @param element DOM element to test.\n *\n * @return Whether element is visible.\n */\nfunction isVisible( element: HTMLElement ): boolean {\n\tif ( typeof element.checkVisibility === 'function' ) {\n\t\tif ( ! element.checkVisibility( { visibilityProperty: true } ) ) {\n\t\t\treturn false;\n\t\t}\n\t} else {\n\t\tconst visibility =\n\t\t\telement.ownerDocument.defaultView?.getComputedStyle(\n\t\t\t\telement\n\t\t\t).visibility;\n\t\tif ( visibility === 'hidden' || visibility === 'collapse' ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn (\n\t\telement.offsetWidth > 0 ||\n\t\telement.offsetHeight > 0 ||\n\t\telement.getClientRects().length > 0\n\t);\n}\n\n/**\n * Returns true if the specified area element is a valid focusable element, or\n * false otherwise. Area is only focusable if within a map where a named map\n * referenced by an image somewhere in the document.\n *\n * @param element DOM area element to test.\n *\n * @return Whether area element is valid for focus.\n */\nfunction isValidFocusableArea( element: HTMLAreaElement ): boolean {\n\tconst map: HTMLMapElement | null = element.closest( 'map[name]' );\n\tif ( ! map ) {\n\t\treturn false;\n\t}\n\n\tconst img: HTMLImageElement | null = element.ownerDocument.querySelector(\n\t\t'img[usemap=\"#' + map.name + '\"]'\n\t);\n\treturn !! img && ! img.closest( '[inert]' ) && isVisible( img );\n}\n\n/**\n * Returns all focusable elements within a given context.\n *\n * @param context Element in which to search.\n * @param options\n * @param [options.sequential] If set, only return elements that are\n * sequentially focusable.\n * Non-interactive elements with a\n * negative `tabindex` are focusable but\n * not sequentially focusable.\n * https://html.spec.whatwg.org/multipage/interaction.html#the-tabindex-attribute\n *\n * @return Focusable elements.\n */\nexport function find(\n\tcontext: Element,\n\t{ sequential = false }: FindFocusableOptions = {}\n): HTMLElement[] {\n\tconst elements: NodeListOf< HTMLElement > = context.querySelectorAll(\n\t\tbuildSelector( sequential )\n\t);\n\n\treturn Array.from( elements ).filter( ( element ) => {\n\t\tconst { nodeName } = element;\n\t\tif ( 'AREA' === nodeName ) {\n\t\t\t// The mapped image determines whether this region is visible or inert.\n\t\t\treturn isValidFocusableArea( element as HTMLAreaElement );\n\t\t}\n\n\t\t// Elements inside an inert subtree are not focusable.\n\t\tif ( element.closest( '[inert]' ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn isVisible( element );\n\t} );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,SAAS,cAAe,YAA8B;CACrD,OAAO;EACN,aAAa,sCAAoC;EACjD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACD,CAAC,CAAC,KAAM,GAAI;AACb;;;;;;;;;AAUA,SAAS,UAAW,SAAgC;CACnD,IAAK,OAAO,QAAQ,oBAAoB,YAClC;MAAA,CAAE,QAAQ,gBAAiB,EAAE,oBAAoB,KAAK,CAAE,GAC5D,OAAO;CAAA,OAEF;EACN,MAAM,aACL,QAAQ,cAAc,aAAa,iBAClC,OACD,CAAC,CAAC;EACH,IAAK,eAAe,YAAY,eAAe,YAC9C,OAAO;CAET;CAEA,OACC,QAAQ,cAAc,KACtB,QAAQ,eAAe,KACvB,QAAQ,eAAe,CAAC,CAAC,SAAS;AAEpC;;;;;;;;;;AAWA,SAAS,qBAAsB,SAAoC;CAClE,MAAM,MAA6B,QAAQ,QAAS,WAAY;CAChE,IAAK,CAAE,KACN,OAAO;CAGR,MAAM,MAA+B,QAAQ,cAAc,cAC1D,mBAAkB,IAAI,OAAO,KAC9B;CACA,OAAO,CAAC,CAAE,OAAO,CAAE,IAAI,QAAS,SAAU,KAAK,UAAW,GAAI;AAC/D;;;;;;;;;;;;;;;AAgBA,SAAgB,KACf,SACA,EAAE,aAAa,UAAgC,CAAC,GAChC;CAChB,MAAM,WAAsC,QAAQ,iBACnD,cAAe,UAAW,CAC3B;CAEA,OAAO,MAAM,KAAM,QAAS,CAAC,CAAC,QAAU,YAAa;EACpD,MAAM,EAAE,aAAa;EACrB,IAAK,WAAW,UAEf,OAAO,qBAAsB,OAA2B;EAIzD,IAAK,QAAQ,QAAS,SAAU,GAC/B,OAAO;EAGR,OAAO,UAAW,OAAQ;CAC3B,CAAE;AACH"}
|
package/build-module/index.mjs
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
// packages/dom/src/index.ts
|
|
2
1
|
import * as focusable from "./focusable.mjs";
|
|
3
2
|
import * as tabbable from "./tabbable.mjs";
|
|
4
3
|
export * from "./dom/index.mjs";
|
|
5
4
|
export * from "./phrasing-content.mjs";
|
|
6
5
|
export * from "./data-transfer.mjs";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
// packages/dom/src/index.ts
|
|
7
|
+
/**
|
|
8
|
+
* Object grouping `focusable` and `tabbable` utils
|
|
9
|
+
* under the keys with the same name.
|
|
10
|
+
*/
|
|
11
|
+
const focus = {
|
|
12
|
+
focusable,
|
|
13
|
+
tabbable
|
|
10
14
|
};
|
|
11
|
-
|
|
15
|
+
export { focus };
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -1,7 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["import * as focusable from './focusable';\nimport * as tabbable from './tabbable';\n\n/**\n * Object grouping `focusable` and `tabbable` utils\n * under the keys with the same name.\n */\nexport const focus = { focusable, tabbable };\n\nexport * from './dom';\nexport * from './phrasing-content';\nexport * from './data-transfer';\n\n/**\n * Schema of the content allowed inside an element, keyed by tag name.\n */\nexport type { ContentSchema } from './types';\n\n/**\n * The attributes and children allowed for an element in a `ContentSchema`.\n */\nexport type { SemanticElementDefinition } from './types';\n\n/**\n * Schema that `cleanNodeList` and `removeInvalidHTML` clean HTML against,\n * keyed by tag name.\n */\nexport type { Schema } from './dom/types';\n\n/**\n * The rules for a single tag in a `Schema`.\n */\nexport type { SchemaItem } from './dom/types';\n"],
|
|
5
|
-
"mappings": ";AAAA,YAAY,eAAe;AAC3B,YAAY,cAAc;AAQ1B,cAAc;AACd,cAAc;AACd,cAAc;AAJP,IAAM,QAAQ,EAAE,WAAW,SAAS;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import * as focusable from './focusable';\nimport * as tabbable from './tabbable';\n\n/**\n * Object grouping `focusable` and `tabbable` utils\n * under the keys with the same name.\n */\nexport const focus = { focusable, tabbable };\n\nexport * from './dom';\nexport * from './phrasing-content';\nexport * from './data-transfer';\n\n/**\n * Schema of the content allowed inside an element, keyed by tag name.\n */\nexport type { ContentSchema } from './types';\n\n/**\n * The attributes and children allowed for an element in a `ContentSchema`.\n */\nexport type { SemanticElementDefinition } from './types';\n\n/**\n * Schema that `cleanNodeList` and `removeInvalidHTML` clean HTML against,\n * keyed by tag name.\n */\nexport type { Schema } from './dom/types';\n\n/**\n * The rules for a single tag in a `Schema`.\n */\nexport type { SchemaItem } from './dom/types';\n"],"mappings":";;;;;;;;;;AAOA,MAAa,QAAQ;CAAE;CAAW;AAAS"}
|