@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.
Files changed (210) hide show
  1. package/README.md +1 -1
  2. package/build/data-transfer.cjs +20 -38
  3. package/build/data-transfer.cjs.map +1 -7
  4. package/build/dom/caret-range-from-point.cjs +31 -38
  5. package/build/dom/caret-range-from-point.cjs.map +1 -7
  6. package/build/dom/clean-node-list.cjs +87 -132
  7. package/build/dom/clean-node-list.cjs.map +1 -7
  8. package/build/dom/compute-caret-rect.cjs +35 -35
  9. package/build/dom/compute-caret-rect.cjs.map +1 -7
  10. package/build/dom/document-has-selection.cjs +35 -30
  11. package/build/dom/document-has-selection.cjs.map +1 -7
  12. package/build/dom/document-has-text-selection.cjs +24 -30
  13. package/build/dom/document-has-text-selection.cjs.map +1 -7
  14. package/build/dom/document-has-uncollapsed-selection.cjs +34 -29
  15. package/build/dom/document-has-uncollapsed-selection.cjs.map +1 -7
  16. package/build/dom/get-computed-style.cjs +14 -30
  17. package/build/dom/get-computed-style.cjs.map +1 -7
  18. package/build/dom/get-offset-parent.cjs +40 -39
  19. package/build/dom/get-offset-parent.cjs.map +1 -7
  20. package/build/dom/get-range-height.cjs +18 -31
  21. package/build/dom/get-range-height.cjs.map +1 -7
  22. package/build/dom/get-rectangle-from-range.cjs +82 -128
  23. package/build/dom/get-rectangle-from-range.cjs.map +1 -7
  24. package/build/dom/get-scroll-container.cjs +46 -50
  25. package/build/dom/get-scroll-container.cjs.map +1 -7
  26. package/build/dom/hidden-caret-range-from-point.cjs +48 -42
  27. package/build/dom/hidden-caret-range-from-point.cjs.map +1 -7
  28. package/build/dom/index.cjs +233 -110
  29. package/build/dom/input-field-has-uncollapsed-selection.cjs +48 -43
  30. package/build/dom/input-field-has-uncollapsed-selection.cjs.map +1 -7
  31. package/build/dom/insert-after.cjs +17 -27
  32. package/build/dom/insert-after.cjs.map +1 -7
  33. package/build/dom/is-edge.cjs +82 -97
  34. package/build/dom/is-edge.cjs.map +1 -7
  35. package/build/dom/is-element.cjs +12 -25
  36. package/build/dom/is-element.cjs.map +1 -7
  37. package/build/dom/is-empty.cjs +23 -37
  38. package/build/dom/is-empty.cjs.map +1 -7
  39. package/build/dom/is-entirely-selected.cjs +70 -67
  40. package/build/dom/is-entirely-selected.cjs.map +1 -7
  41. package/build/dom/is-form-element.cjs +33 -33
  42. package/build/dom/is-form-element.cjs.map +1 -7
  43. package/build/dom/is-horizontal-edge.cjs +31 -28
  44. package/build/dom/is-horizontal-edge.cjs.map +1 -7
  45. package/build/dom/is-html-input-element.cjs +12 -25
  46. package/build/dom/is-html-input-element.cjs.map +1 -7
  47. package/build/dom/is-input-or-text-area.cjs +12 -25
  48. package/build/dom/is-input-or-text-area.cjs.map +1 -7
  49. package/build/dom/is-number-input.cjs +36 -33
  50. package/build/dom/is-number-input.cjs.map +1 -7
  51. package/build/dom/is-rtl.cjs +30 -28
  52. package/build/dom/is-rtl.cjs.map +1 -7
  53. package/build/dom/is-selection-forward.cjs +26 -39
  54. package/build/dom/is-selection-forward.cjs.map +1 -7
  55. package/build/dom/is-text-field.cjs +45 -42
  56. package/build/dom/is-text-field.cjs.map +1 -7
  57. package/build/dom/is-vertical-edge.cjs +31 -28
  58. package/build/dom/is-vertical-edge.cjs.map +1 -7
  59. package/build/dom/place-caret-at-edge.cjs +75 -78
  60. package/build/dom/place-caret-at-edge.cjs.map +1 -7
  61. package/build/dom/place-caret-at-horizontal-edge.cjs +29 -28
  62. package/build/dom/place-caret-at-horizontal-edge.cjs.map +1 -7
  63. package/build/dom/place-caret-at-vertical-edge.cjs +30 -28
  64. package/build/dom/place-caret-at-vertical-edge.cjs.map +1 -7
  65. package/build/dom/remove-invalid-html.cjs +35 -31
  66. package/build/dom/remove-invalid-html.cjs.map +1 -7
  67. package/build/dom/remove.cjs +15 -27
  68. package/build/dom/remove.cjs.map +1 -7
  69. package/build/dom/replace-tag.cjs +21 -32
  70. package/build/dom/replace-tag.cjs.map +1 -7
  71. package/build/dom/replace.cjs +34 -32
  72. package/build/dom/replace.cjs.map +1 -7
  73. package/build/dom/safe-html.cjs +45 -46
  74. package/build/dom/safe-html.cjs.map +1 -7
  75. package/build/dom/scroll-if-no-range.cjs +24 -37
  76. package/build/dom/scroll-if-no-range.cjs.map +1 -7
  77. package/build/dom/strip-html.cjs +33 -31
  78. package/build/dom/strip-html.cjs.map +1 -7
  79. package/build/dom/types.cjs +4 -18
  80. package/build/dom/unwrap.cjs +17 -31
  81. package/build/dom/unwrap.cjs.map +1 -7
  82. package/build/dom/wrap.cjs +17 -28
  83. package/build/dom/wrap.cjs.map +1 -7
  84. package/build/focusable.cjs +99 -76
  85. package/build/focusable.cjs.map +1 -7
  86. package/build/index.cjs +57 -38
  87. package/build/index.cjs.map +1 -7
  88. package/build/phrasing-content.cjs +163 -159
  89. package/build/phrasing-content.cjs.map +1 -7
  90. package/build/tabbable.cjs +123 -78
  91. package/build/tabbable.cjs.map +1 -7
  92. package/build/types.cjs +4 -18
  93. package/build/utils/assert-is-defined.cjs +8 -33
  94. package/build/utils/assert-is-defined.cjs.map +1 -7
  95. package/build-module/data-transfer.mjs +16 -14
  96. package/build-module/data-transfer.mjs.map +1 -7
  97. package/build-module/dom/caret-range-from-point.mjs +27 -18
  98. package/build-module/dom/caret-range-from-point.mjs.map +1 -7
  99. package/build-module/dom/clean-node-list.mjs +60 -105
  100. package/build-module/dom/clean-node-list.mjs.map +1 -7
  101. package/build-module/dom/compute-caret-rect.mjs +16 -12
  102. package/build-module/dom/compute-caret-rect.mjs.map +1 -7
  103. package/build-module/dom/document-has-selection.mjs +13 -6
  104. package/build-module/dom/document-has-selection.mjs.map +1 -7
  105. package/build-module/dom/document-has-text-selection.mjs +20 -10
  106. package/build-module/dom/document-has-text-selection.mjs.map +1 -7
  107. package/build-module/dom/document-has-uncollapsed-selection.mjs +14 -6
  108. package/build-module/dom/document-has-uncollapsed-selection.mjs.map +1 -7
  109. package/build-module/dom/get-computed-style.mjs +10 -10
  110. package/build-module/dom/get-computed-style.mjs.map +1 -7
  111. package/build-module/dom/get-offset-parent.mjs +20 -16
  112. package/build-module/dom/get-offset-parent.mjs.map +1 -7
  113. package/build-module/dom/get-range-height.mjs +14 -11
  114. package/build-module/dom/get-range-height.mjs.map +1 -7
  115. package/build-module/dom/get-rectangle-from-range.mjs +78 -108
  116. package/build-module/dom/get-rectangle-from-range.mjs.map +1 -7
  117. package/build-module/dom/get-scroll-container.mjs +28 -28
  118. package/build-module/dom/get-scroll-container.mjs.map +1 -7
  119. package/build-module/dom/hidden-caret-range-from-point.mjs +28 -19
  120. package/build-module/dom/hidden-caret-range-from-point.mjs.map +1 -7
  121. package/build-module/dom/index.mjs +28 -58
  122. package/build-module/dom/input-field-has-uncollapsed-selection.mjs +28 -20
  123. package/build-module/dom/input-field-has-uncollapsed-selection.mjs.map +1 -7
  124. package/build-module/dom/insert-after.mjs +13 -7
  125. package/build-module/dom/insert-after.mjs.map +1 -7
  126. package/build-module/dom/is-edge.mjs +53 -69
  127. package/build-module/dom/is-edge.mjs.map +1 -7
  128. package/build-module/dom/is-element.mjs +8 -5
  129. package/build-module/dom/is-element.mjs.map +1 -7
  130. package/build-module/dom/is-empty.mjs +19 -17
  131. package/build-module/dom/is-empty.mjs.map +1 -7
  132. package/build-module/dom/is-entirely-selected.mjs +51 -44
  133. package/build-module/dom/is-entirely-selected.mjs.map +1 -7
  134. package/build-module/dom/is-form-element.mjs +15 -11
  135. package/build-module/dom/is-form-element.mjs.map +1 -7
  136. package/build-module/dom/is-horizontal-edge.mjs +13 -6
  137. package/build-module/dom/is-horizontal-edge.mjs.map +1 -7
  138. package/build-module/dom/is-html-input-element.mjs +8 -5
  139. package/build-module/dom/is-html-input-element.mjs.map +1 -7
  140. package/build-module/dom/is-input-or-text-area.mjs +8 -5
  141. package/build-module/dom/is-input-or-text-area.mjs.map +1 -7
  142. package/build-module/dom/is-number-input.mjs +16 -10
  143. package/build-module/dom/is-number-input.mjs.map +1 -7
  144. package/build-module/dom/is-rtl.mjs +12 -6
  145. package/build-module/dom/is-rtl.mjs.map +1 -7
  146. package/build-module/dom/is-selection-forward.mjs +22 -19
  147. package/build-module/dom/is-selection-forward.mjs.map +1 -7
  148. package/build-module/dom/is-text-field.mjs +27 -20
  149. package/build-module/dom/is-text-field.mjs.map +1 -7
  150. package/build-module/dom/is-vertical-edge.mjs +13 -6
  151. package/build-module/dom/is-vertical-edge.mjs.map +1 -7
  152. package/build-module/dom/place-caret-at-edge.mjs +51 -52
  153. package/build-module/dom/place-caret-at-edge.mjs.map +1 -7
  154. package/build-module/dom/place-caret-at-horizontal-edge.mjs +11 -6
  155. package/build-module/dom/place-caret-at-horizontal-edge.mjs.map +1 -7
  156. package/build-module/dom/place-caret-at-vertical-edge.mjs +12 -6
  157. package/build-module/dom/place-caret-at-vertical-edge.mjs.map +1 -7
  158. package/build-module/dom/remove-invalid-html.mjs +17 -9
  159. package/build-module/dom/remove-invalid-html.mjs.map +1 -7
  160. package/build-module/dom/remove.mjs +11 -7
  161. package/build-module/dom/remove.mjs.map +1 -7
  162. package/build-module/dom/replace-tag.mjs +17 -12
  163. package/build-module/dom/replace-tag.mjs.map +1 -7
  164. package/build-module/dom/replace.mjs +13 -8
  165. package/build-module/dom/replace.mjs.map +1 -7
  166. package/build-module/dom/safe-html.mjs +27 -24
  167. package/build-module/dom/safe-html.mjs.map +1 -7
  168. package/build-module/dom/scroll-if-no-range.mjs +20 -13
  169. package/build-module/dom/scroll-if-no-range.mjs.map +1 -7
  170. package/build-module/dom/strip-html.mjs +15 -9
  171. package/build-module/dom/strip-html.mjs.map +1 -7
  172. package/build-module/dom/types.mjs +0 -1
  173. package/build-module/dom/unwrap.mjs +13 -11
  174. package/build-module/dom/unwrap.mjs.map +1 -7
  175. package/build-module/dom/wrap.mjs +13 -8
  176. package/build-module/dom/wrap.mjs.map +1 -7
  177. package/build-module/focusable.mjs +95 -52
  178. package/build-module/focusable.mjs.map +1 -7
  179. package/build-module/index.mjs +11 -5
  180. package/build-module/index.mjs.map +1 -7
  181. package/build-module/phrasing-content.mjs +157 -133
  182. package/build-module/phrasing-content.mjs.map +1 -7
  183. package/build-module/tabbable.mjs +116 -51
  184. package/build-module/tabbable.mjs.map +1 -7
  185. package/build-module/types.mjs +0 -1
  186. package/build-module/utils/assert-is-defined.mjs +4 -9
  187. package/build-module/utils/assert-is-defined.mjs.map +1 -7
  188. package/build-types/dom/clean-node-list.d.ts +2 -2
  189. package/build-types/dom/clean-node-list.d.ts.map +1 -1
  190. package/build-types/dom/is-edge.d.ts.map +1 -1
  191. package/build-types/dom/remove-invalid-html.d.ts +4 -4
  192. package/build-types/dom/remove-invalid-html.d.ts.map +1 -1
  193. package/package.json +4 -4
  194. package/src/dom/clean-node-list.ts +2 -2
  195. package/src/dom/is-edge.ts +35 -43
  196. package/src/dom/remove-invalid-html.ts +4 -4
  197. package/src/dom/test/{get-rectangle-from-range.browser.test.js → get-rectangle-from-range.browser.test.ts} +25 -25
  198. package/src/test/{dom.jsdom.test.js → dom.jsdom.test.ts} +9 -6
  199. package/src/test/{focusable.browser.test.js → focusable.browser.test.ts} +14 -13
  200. package/src/test/{tabbable.browser.test.js → tabbable.browser.test.ts} +3 -2
  201. package/build/dom/index.cjs.map +0 -7
  202. package/build/dom/types.cjs.map +0 -7
  203. package/build/types.cjs.map +0 -7
  204. package/build-module/dom/index.mjs.map +0 -7
  205. package/build-module/dom/types.mjs.map +0 -7
  206. package/build-module/types.mjs.map +0 -7
  207. /package/src/dom/test/{safe-html.jsdom.test.js → safe-html.jsdom.test.ts} +0 -0
  208. /package/src/dom/test/{strip-html.jsdom.test.js → strip-html.jsdom.test.ts} +0 -0
  209. /package/src/test/{focusable-area.jsdom.test.js → focusable-area.jsdom.test.ts} +0 -0
  210. /package/src/test/{utils.js → utils.ts} +0 -0
@@ -1,20 +1,24 @@
1
- // packages/dom/src/dom/get-offset-parent.ts
2
1
  import getComputedStyle from "./get-computed-style.mjs";
3
2
  import isElement from "./is-element.mjs";
3
+ // packages/dom/src/dom/get-offset-parent.ts
4
+ /**
5
+ * Returns the closest positioned element, or null under any of the conditions
6
+ * of the offsetParent specification. Unlike offsetParent, this function is not
7
+ * limited to HTMLElement and accepts any Node (e.g. Node.TEXT_NODE).
8
+ *
9
+ * @see https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetparent
10
+ *
11
+ * @param node Node from which to find offset parent.
12
+ *
13
+ * @return Offset parent.
14
+ */
4
15
  function getOffsetParent(node) {
5
- let closestElement = node.parentNode;
6
- while (closestElement && !isElement(closestElement)) {
7
- closestElement = closestElement.parentNode;
8
- }
9
- if (!closestElement) {
10
- return null;
11
- }
12
- if (getComputedStyle(closestElement).position !== "static") {
13
- return closestElement;
14
- }
15
- return closestElement.offsetParent;
16
+ let closestElement = node.parentNode;
17
+ while (closestElement && !isElement(closestElement)) closestElement = closestElement.parentNode;
18
+ if (!closestElement) return null;
19
+ if (getComputedStyle(closestElement).position !== "static") return closestElement;
20
+ return closestElement.offsetParent;
16
21
  }
17
- export {
18
- getOffsetParent as default
19
- };
20
- //# sourceMappingURL=get-offset-parent.mjs.map
22
+ export { getOffsetParent as default };
23
+
24
+ //# sourceMappingURL=get-offset-parent.mjs.map
@@ -1,7 +1 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/dom/get-offset-parent.ts"],
4
- "sourcesContent": ["import getComputedStyle from './get-computed-style';\nimport isElement from './is-element';\n\n/**\n * Returns the closest positioned element, or null under any of the conditions\n * of the offsetParent specification. Unlike offsetParent, this function is not\n * limited to HTMLElement and accepts any Node (e.g. Node.TEXT_NODE).\n *\n * @see https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetparent\n *\n * @param node Node from which to find offset parent.\n *\n * @return Offset parent.\n */\nexport default function getOffsetParent( node: Node ): Node | null {\n\t// Cannot retrieve computed style or offset parent only anything other than\n\t// an element node, so find the closest element node.\n\tlet closestElement = node.parentNode;\n\twhile ( closestElement && ! isElement( closestElement ) ) {\n\t\tclosestElement = closestElement.parentNode;\n\t}\n\n\tif ( ! closestElement ) {\n\t\treturn null;\n\t}\n\n\t// If the closest element is already positioned, return it, as offsetParent\n\t// does not otherwise consider the node itself.\n\tif ( getComputedStyle( closestElement ).position !== 'static' ) {\n\t\treturn closestElement;\n\t}\n\n\t// offsetParent is undocumented/draft.\n\treturn ( closestElement as HTMLElement ).offsetParent;\n}\n"],
5
- "mappings": ";AAAA,OAAO,sBAAsB;AAC7B,OAAO,eAAe;AAaP,SAAR,gBAAkC,MAA0B;AAGlE,MAAI,iBAAiB,KAAK;AAC1B,SAAQ,kBAAkB,CAAE,UAAW,cAAe,GAAI;AACzD,qBAAiB,eAAe;AAAA,EACjC;AAEA,MAAK,CAAE,gBAAiB;AACvB,WAAO;AAAA,EACR;AAIA,MAAK,iBAAkB,cAAe,EAAE,aAAa,UAAW;AAC/D,WAAO;AAAA,EACR;AAGA,SAAS,eAAgC;AAC1C;",
6
- "names": []
7
- }
1
+ {"version":3,"file":"get-offset-parent.mjs","names":[],"sources":["../../src/dom/get-offset-parent.ts"],"sourcesContent":["import getComputedStyle from './get-computed-style';\nimport isElement from './is-element';\n\n/**\n * Returns the closest positioned element, or null under any of the conditions\n * of the offsetParent specification. Unlike offsetParent, this function is not\n * limited to HTMLElement and accepts any Node (e.g. Node.TEXT_NODE).\n *\n * @see https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetparent\n *\n * @param node Node from which to find offset parent.\n *\n * @return Offset parent.\n */\nexport default function getOffsetParent( node: Node ): Node | null {\n\t// Cannot retrieve computed style or offset parent only anything other than\n\t// an element node, so find the closest element node.\n\tlet closestElement = node.parentNode;\n\twhile ( closestElement && ! isElement( closestElement ) ) {\n\t\tclosestElement = closestElement.parentNode;\n\t}\n\n\tif ( ! closestElement ) {\n\t\treturn null;\n\t}\n\n\t// If the closest element is already positioned, return it, as offsetParent\n\t// does not otherwise consider the node itself.\n\tif ( getComputedStyle( closestElement ).position !== 'static' ) {\n\t\treturn closestElement;\n\t}\n\n\t// offsetParent is undocumented/draft.\n\treturn ( closestElement as HTMLElement ).offsetParent;\n}\n"],"mappings":";;;;;;;;;;;;;;AAcA,SAAwB,gBAAiB,MAA0B;CAGlE,IAAI,iBAAiB,KAAK;CAC1B,OAAQ,kBAAkB,CAAE,UAAW,cAAe,GACrD,iBAAiB,eAAe;CAGjC,IAAK,CAAE,gBACN,OAAO;CAKR,IAAK,iBAAkB,cAAe,CAAC,CAAC,aAAa,UACpD,OAAO;CAIR,OAAS,eAAgC;AAC1C"}
@@ -1,14 +1,17 @@
1
1
  // packages/dom/src/dom/get-range-height.ts
2
+ /**
3
+ * Gets the height of the range without ignoring zero width rectangles, which
4
+ * some browsers ignore when creating a union.
5
+ *
6
+ * @param range The range to check.
7
+ * @return Height of the range or undefined if the range has no client rectangles.
8
+ */
2
9
  function getRangeHeight(range) {
3
- const rects = Array.from(range.getClientRects());
4
- if (!rects.length) {
5
- return;
6
- }
7
- const highestTop = Math.min(...rects.map(({ top }) => top));
8
- const lowestBottom = Math.max(...rects.map(({ bottom }) => bottom));
9
- return lowestBottom - highestTop;
10
+ const rects = Array.from(range.getClientRects());
11
+ if (!rects.length) return;
12
+ const highestTop = Math.min(...rects.map(({ top }) => top));
13
+ return Math.max(...rects.map(({ bottom }) => bottom)) - highestTop;
10
14
  }
11
- export {
12
- getRangeHeight as default
13
- };
14
- //# sourceMappingURL=get-range-height.mjs.map
15
+ export { getRangeHeight as default };
16
+
17
+ //# sourceMappingURL=get-range-height.mjs.map
@@ -1,7 +1 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/dom/get-range-height.ts"],
4
- "sourcesContent": ["/**\n * Gets the height of the range without ignoring zero width rectangles, which\n * some browsers ignore when creating a union.\n *\n * @param range The range to check.\n * @return Height of the range or undefined if the range has no client rectangles.\n */\nexport default function getRangeHeight( range: Range ): number | undefined {\n\tconst rects = Array.from( range.getClientRects() );\n\n\tif ( ! rects.length ) {\n\t\treturn;\n\t}\n\n\tconst highestTop = Math.min( ...rects.map( ( { top } ) => top ) );\n\tconst lowestBottom = Math.max( ...rects.map( ( { bottom } ) => bottom ) );\n\n\treturn lowestBottom - highestTop;\n}\n"],
5
- "mappings": ";AAOe,SAAR,eAAiC,OAAmC;AAC1E,QAAM,QAAQ,MAAM,KAAM,MAAM,eAAe,CAAE;AAEjD,MAAK,CAAE,MAAM,QAAS;AACrB;AAAA,EACD;AAEA,QAAM,aAAa,KAAK,IAAK,GAAG,MAAM,IAAK,CAAE,EAAE,IAAI,MAAO,GAAI,CAAE;AAChE,QAAM,eAAe,KAAK,IAAK,GAAG,MAAM,IAAK,CAAE,EAAE,OAAO,MAAO,MAAO,CAAE;AAExE,SAAO,eAAe;AACvB;",
6
- "names": []
7
- }
1
+ {"version":3,"file":"get-range-height.mjs","names":[],"sources":["../../src/dom/get-range-height.ts"],"sourcesContent":["/**\n * Gets the height of the range without ignoring zero width rectangles, which\n * some browsers ignore when creating a union.\n *\n * @param range The range to check.\n * @return Height of the range or undefined if the range has no client rectangles.\n */\nexport default function getRangeHeight( range: Range ): number | undefined {\n\tconst rects = Array.from( range.getClientRects() );\n\n\tif ( ! rects.length ) {\n\t\treturn;\n\t}\n\n\tconst highestTop = Math.min( ...rects.map( ( { top } ) => top ) );\n\tconst lowestBottom = Math.max( ...rects.map( ( { bottom } ) => bottom ) );\n\n\treturn lowestBottom - highestTop;\n}\n"],"mappings":";;;;;;;;AAOA,SAAwB,eAAgB,OAAmC;CAC1E,MAAM,QAAQ,MAAM,KAAM,MAAM,eAAe,CAAE;CAEjD,IAAK,CAAE,MAAM,QACZ;CAGD,MAAM,aAAa,KAAK,IAAK,GAAG,MAAM,KAAO,EAAE,UAAW,GAAI,CAAE;CAGhE,OAFqB,KAAK,IAAK,GAAG,MAAM,KAAO,EAAE,aAAc,MAAO,CAEpD,IAAI;AACvB"}
@@ -1,111 +1,81 @@
1
- // packages/dom/src/dom/get-rectangle-from-range.ts
2
1
  import { assertIsDefined } from "../utils/assert-is-defined.mjs";
2
+ // packages/dom/src/dom/get-rectangle-from-range.ts
3
+ /**
4
+ * Get the rectangle of a given Range. Returns `null` if no suitable rectangle
5
+ * can be found. Use instead of `Range.getBoundingClientRect()`, which is often
6
+ * broken, especially for collapsed ranges.
7
+ *
8
+ * @param range The range.
9
+ *
10
+ * @return The rectangle.
11
+ */
3
12
  function getRectangleFromRange(range) {
4
- if (!range.collapsed) {
5
- const rects2 = Array.from(range.getClientRects());
6
- if (rects2.length === 1) {
7
- return rects2[0];
8
- }
9
- const filteredRects = rects2.filter(({ width }) => width > 1);
10
- if (filteredRects.length === 0) {
11
- return range.getBoundingClientRect();
12
- }
13
- if (filteredRects.length === 1) {
14
- return filteredRects[0];
15
- }
16
- let {
17
- top: furthestTop,
18
- bottom: furthestBottom,
19
- left: furthestLeft,
20
- right: furthestRight
21
- } = filteredRects[0];
22
- for (const { top, bottom, left, right } of filteredRects) {
23
- if (top < furthestTop) {
24
- furthestTop = top;
25
- }
26
- if (bottom > furthestBottom) {
27
- furthestBottom = bottom;
28
- }
29
- if (left < furthestLeft) {
30
- furthestLeft = left;
31
- }
32
- if (right > furthestRight) {
33
- furthestRight = right;
34
- }
35
- }
36
- return new window.DOMRect(
37
- furthestLeft,
38
- furthestTop,
39
- furthestRight - furthestLeft,
40
- furthestBottom - furthestTop
41
- );
42
- }
43
- const { startContainer, startOffset } = range;
44
- const { ownerDocument } = startContainer;
45
- assertIsDefined(ownerDocument, "ownerDocument");
46
- if (startContainer.nodeType !== startContainer.TEXT_NODE && !startContainer.childNodes.length && startContainer.parentNode) {
47
- range = ownerDocument.createRange();
48
- range.setStartBefore(startContainer);
49
- range.collapse(true);
50
- return getRectangleFromRange(range);
51
- }
52
- if (startContainer.nodeType !== startContainer.TEXT_NODE) {
53
- let before = startContainer.childNodes[startOffset - 1];
54
- while (before?.lastChild) {
55
- before = before.lastChild;
56
- }
57
- let after = startContainer.childNodes[startOffset];
58
- while (after?.firstChild) {
59
- after = after.firstChild;
60
- }
61
- let beforeRange;
62
- if (before && before.nodeType === before.TEXT_NODE) {
63
- beforeRange = ownerDocument.createRange();
64
- beforeRange.setStart(before, before.length);
65
- beforeRange.collapse(true);
66
- }
67
- let afterRange;
68
- if (after && after.nodeType === after.TEXT_NODE) {
69
- afterRange = ownerDocument.createRange();
70
- afterRange.setStart(after, 0);
71
- afterRange.collapse(true);
72
- }
73
- if (beforeRange && afterRange) {
74
- const beforeRect = beforeRange.getClientRects()[0];
75
- const afterRect = afterRange.getClientRects()[0];
76
- if (beforeRect && afterRect && beforeRect.bottom <= afterRect.top) {
77
- return null;
78
- }
79
- }
80
- if (afterRange) {
81
- range = afterRange;
82
- } else if (beforeRange) {
83
- range = beforeRange;
84
- } else {
85
- return null;
86
- }
87
- }
88
- const rects = range.getClientRects();
89
- if (rects.length > 1) {
90
- return null;
91
- }
92
- if (rects.length === 1 && startContainer.nodeType === startContainer.TEXT_NODE && range.startOffset > 0 && range.startOffset < startContainer.length) {
93
- assertIsDefined(ownerDocument, "ownerDocument");
94
- const measure = (start, end) => {
95
- const charRange = ownerDocument.createRange();
96
- charRange.setStart(startContainer, start);
97
- charRange.setEnd(startContainer, end);
98
- return charRange.getBoundingClientRect();
99
- };
100
- const before = measure(range.startOffset - 1, range.startOffset);
101
- const after = measure(range.startOffset, range.startOffset + 1);
102
- if (before.bottom <= after.top) {
103
- return null;
104
- }
105
- }
106
- return rects[0] ?? null;
13
+ if (!range.collapsed) {
14
+ const rects = Array.from(range.getClientRects());
15
+ if (rects.length === 1) return rects[0];
16
+ const filteredRects = rects.filter(({ width }) => width > 1);
17
+ if (filteredRects.length === 0) return range.getBoundingClientRect();
18
+ if (filteredRects.length === 1) return filteredRects[0];
19
+ let { top: furthestTop, bottom: furthestBottom, left: furthestLeft, right: furthestRight } = filteredRects[0];
20
+ for (const { top, bottom, left, right } of filteredRects) {
21
+ if (top < furthestTop) furthestTop = top;
22
+ if (bottom > furthestBottom) furthestBottom = bottom;
23
+ if (left < furthestLeft) furthestLeft = left;
24
+ if (right > furthestRight) furthestRight = right;
25
+ }
26
+ return new window.DOMRect(furthestLeft, furthestTop, furthestRight - furthestLeft, furthestBottom - furthestTop);
27
+ }
28
+ const { startContainer, startOffset } = range;
29
+ const { ownerDocument } = startContainer;
30
+ assertIsDefined(ownerDocument, "ownerDocument");
31
+ if (startContainer.nodeType !== startContainer.TEXT_NODE && !startContainer.childNodes.length && startContainer.parentNode) {
32
+ range = ownerDocument.createRange();
33
+ range.setStartBefore(startContainer);
34
+ range.collapse(true);
35
+ return getRectangleFromRange(range);
36
+ }
37
+ if (startContainer.nodeType !== startContainer.TEXT_NODE) {
38
+ let before = startContainer.childNodes[startOffset - 1];
39
+ while (before?.lastChild) before = before.lastChild;
40
+ let after = startContainer.childNodes[startOffset];
41
+ while (after?.firstChild) after = after.firstChild;
42
+ let beforeRange;
43
+ if (before && before.nodeType === before.TEXT_NODE) {
44
+ beforeRange = ownerDocument.createRange();
45
+ beforeRange.setStart(before, before.length);
46
+ beforeRange.collapse(true);
47
+ }
48
+ let afterRange;
49
+ if (after && after.nodeType === after.TEXT_NODE) {
50
+ afterRange = ownerDocument.createRange();
51
+ afterRange.setStart(after, 0);
52
+ afterRange.collapse(true);
53
+ }
54
+ if (beforeRange && afterRange) {
55
+ const beforeRect = beforeRange.getClientRects()[0];
56
+ const afterRect = afterRange.getClientRects()[0];
57
+ if (beforeRect && afterRect && beforeRect.bottom <= afterRect.top) return null;
58
+ }
59
+ if (afterRange) range = afterRange;
60
+ else if (beforeRange) range = beforeRange;
61
+ else return null;
62
+ }
63
+ const rects = range.getClientRects();
64
+ if (rects.length > 1) return null;
65
+ if (rects.length === 1 && startContainer.nodeType === startContainer.TEXT_NODE && range.startOffset > 0 && range.startOffset < startContainer.length) {
66
+ assertIsDefined(ownerDocument, "ownerDocument");
67
+ const measure = (start, end) => {
68
+ const charRange = ownerDocument.createRange();
69
+ charRange.setStart(startContainer, start);
70
+ charRange.setEnd(startContainer, end);
71
+ return charRange.getBoundingClientRect();
72
+ };
73
+ const before = measure(range.startOffset - 1, range.startOffset);
74
+ const after = measure(range.startOffset, range.startOffset + 1);
75
+ if (before.bottom <= after.top) return null;
76
+ }
77
+ return rects[0] ?? null;
107
78
  }
108
- export {
109
- getRectangleFromRange as default
110
- };
111
- //# sourceMappingURL=get-rectangle-from-range.mjs.map
79
+ export { getRectangleFromRange as default };
80
+
81
+ //# sourceMappingURL=get-rectangle-from-range.mjs.map
@@ -1,7 +1 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/dom/get-rectangle-from-range.ts"],
4
- "sourcesContent": ["import { assertIsDefined } from '../utils/assert-is-defined';\n\n/**\n * Get the rectangle of a given Range. Returns `null` if no suitable rectangle\n * can be found. Use instead of `Range.getBoundingClientRect()`, which is often\n * broken, especially for collapsed ranges.\n *\n * @param range The range.\n *\n * @return The rectangle.\n */\nexport default function getRectangleFromRange( range: Range ): DOMRect | null {\n\t// For uncollapsed ranges, get the rectangle that bounds the contents of the\n\t// range; this a rectangle enclosing the union of the bounding rectangles\n\t// for all the elements in the range.\n\tif ( ! range.collapsed ) {\n\t\tconst rects = Array.from( range.getClientRects() );\n\n\t\t// If there's just a single rect, return it.\n\t\tif ( rects.length === 1 ) {\n\t\t\treturn rects[ 0 ];\n\t\t}\n\n\t\t// Ignore tiny selection at the edge of a range.\n\t\tconst filteredRects = rects.filter( ( { width } ) => width > 1 );\n\n\t\t// If it's full of tiny selections, return browser default.\n\t\tif ( filteredRects.length === 0 ) {\n\t\t\treturn range.getBoundingClientRect();\n\t\t}\n\n\t\tif ( filteredRects.length === 1 ) {\n\t\t\treturn filteredRects[ 0 ];\n\t\t}\n\n\t\tlet {\n\t\t\ttop: furthestTop,\n\t\t\tbottom: furthestBottom,\n\t\t\tleft: furthestLeft,\n\t\t\tright: furthestRight,\n\t\t} = filteredRects[ 0 ];\n\n\t\tfor ( const { top, bottom, left, right } of filteredRects ) {\n\t\t\tif ( top < furthestTop ) {\n\t\t\t\tfurthestTop = top;\n\t\t\t}\n\t\t\tif ( bottom > furthestBottom ) {\n\t\t\t\tfurthestBottom = bottom;\n\t\t\t}\n\t\t\tif ( left < furthestLeft ) {\n\t\t\t\tfurthestLeft = left;\n\t\t\t}\n\t\t\tif ( right > furthestRight ) {\n\t\t\t\tfurthestRight = right;\n\t\t\t}\n\t\t}\n\n\t\treturn new window.DOMRect(\n\t\t\tfurthestLeft,\n\t\t\tfurthestTop,\n\t\t\tfurthestRight - furthestLeft,\n\t\t\tfurthestBottom - furthestTop\n\t\t);\n\t}\n\n\tconst { startContainer, startOffset } = range;\n\tconst { ownerDocument } = startContainer;\n\tassertIsDefined( ownerDocument, 'ownerDocument' );\n\n\t// A range inside an element with no children, like a line break or the\n\t// placeholder, is the same spot as the position before that element.\n\tif (\n\t\tstartContainer.nodeType !== startContainer.TEXT_NODE &&\n\t\t! startContainer.childNodes.length &&\n\t\tstartContainer.parentNode\n\t) {\n\t\trange = ownerDocument.createRange();\n\t\trange.setStartBefore( startContainer );\n\t\trange.collapse( true );\n\t\treturn getRectangleFromRange( range );\n\t}\n\n\t// A collapsed range at an element offset has no rectangle. Translate it\n\t// to the text offset next to it: the end of the text before or the start\n\t// of the text after. When those sit on different lines the caret could\n\t// be on either, so return null.\n\tif ( startContainer.nodeType !== startContainer.TEXT_NODE ) {\n\t\tlet before = startContainer.childNodes[ startOffset - 1 ];\n\t\twhile ( before?.lastChild ) {\n\t\t\tbefore = before.lastChild;\n\t\t}\n\t\tlet after = startContainer.childNodes[ startOffset ];\n\t\twhile ( after?.firstChild ) {\n\t\t\tafter = after.firstChild;\n\t\t}\n\n\t\tlet beforeRange;\n\t\tif ( before && before.nodeType === before.TEXT_NODE ) {\n\t\t\tbeforeRange = ownerDocument.createRange();\n\t\t\tbeforeRange.setStart( before, ( before as Text ).length );\n\t\t\tbeforeRange.collapse( true );\n\t\t}\n\t\tlet afterRange;\n\t\tif ( after && after.nodeType === after.TEXT_NODE ) {\n\t\t\tafterRange = ownerDocument.createRange();\n\t\t\tafterRange.setStart( after, 0 );\n\t\t\tafterRange.collapse( true );\n\t\t}\n\n\t\tif ( beforeRange && afterRange ) {\n\t\t\tconst beforeRect = beforeRange.getClientRects()[ 0 ];\n\t\t\tconst afterRect = afterRange.getClientRects()[ 0 ];\n\t\t\tif (\n\t\t\t\tbeforeRect &&\n\t\t\t\tafterRect &&\n\t\t\t\tbeforeRect.bottom <= afterRect.top\n\t\t\t) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tif ( afterRange ) {\n\t\t\trange = afterRange;\n\t\t} else if ( beforeRange ) {\n\t\t\trange = beforeRange;\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tconst rects = range.getClientRects();\n\n\t// If we have multiple rectangles for a collapsed range, there's no way to\n\t// know which it is, so don't return anything.\n\tif ( rects.length > 1 ) {\n\t\treturn null;\n\t}\n\n\t// A collapsed range at a soft line wrap is equally ambiguous: the same\n\t// position ends one line and starts the next. Some browsers (Gecko)\n\t// return a single rectangle for it, on the upper line, regardless of\n\t// where the caret is. Detect the boundary by measuring the characters\n\t// around the position: when they sit on different lines, there is no\n\t// way to know which line the caret is on, so don't return anything.\n\tif (\n\t\trects.length === 1 &&\n\t\tstartContainer.nodeType === startContainer.TEXT_NODE &&\n\t\trange.startOffset > 0 &&\n\t\trange.startOffset < ( startContainer as Text ).length\n\t) {\n\t\tassertIsDefined( ownerDocument, 'ownerDocument' );\n\t\tconst measure = ( start: number, end: number ) => {\n\t\t\tconst charRange = ownerDocument.createRange();\n\t\t\tcharRange.setStart( startContainer, start );\n\t\t\tcharRange.setEnd( startContainer, end );\n\t\t\treturn charRange.getBoundingClientRect();\n\t\t};\n\t\tconst before = measure( range.startOffset - 1, range.startOffset );\n\t\tconst after = measure( range.startOffset, range.startOffset + 1 );\n\n\t\tif ( before.bottom <= after.top ) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\treturn rects[ 0 ] ?? null;\n}\n"],
5
- "mappings": ";AAAA,SAAS,uBAAuB;AAWjB,SAAR,sBAAwC,OAA+B;AAI7E,MAAK,CAAE,MAAM,WAAY;AACxB,UAAMA,SAAQ,MAAM,KAAM,MAAM,eAAe,CAAE;AAGjD,QAAKA,OAAM,WAAW,GAAI;AACzB,aAAOA,OAAO,CAAE;AAAA,IACjB;AAGA,UAAM,gBAAgBA,OAAM,OAAQ,CAAE,EAAE,MAAM,MAAO,QAAQ,CAAE;AAG/D,QAAK,cAAc,WAAW,GAAI;AACjC,aAAO,MAAM,sBAAsB;AAAA,IACpC;AAEA,QAAK,cAAc,WAAW,GAAI;AACjC,aAAO,cAAe,CAAE;AAAA,IACzB;AAEA,QAAI;AAAA,MACH,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,OAAO;AAAA,IACR,IAAI,cAAe,CAAE;AAErB,eAAY,EAAE,KAAK,QAAQ,MAAM,MAAM,KAAK,eAAgB;AAC3D,UAAK,MAAM,aAAc;AACxB,sBAAc;AAAA,MACf;AACA,UAAK,SAAS,gBAAiB;AAC9B,yBAAiB;AAAA,MAClB;AACA,UAAK,OAAO,cAAe;AAC1B,uBAAe;AAAA,MAChB;AACA,UAAK,QAAQ,eAAgB;AAC5B,wBAAgB;AAAA,MACjB;AAAA,IACD;AAEA,WAAO,IAAI,OAAO;AAAA,MACjB;AAAA,MACA;AAAA,MACA,gBAAgB;AAAA,MAChB,iBAAiB;AAAA,IAClB;AAAA,EACD;AAEA,QAAM,EAAE,gBAAgB,YAAY,IAAI;AACxC,QAAM,EAAE,cAAc,IAAI;AAC1B,kBAAiB,eAAe,eAAgB;AAIhD,MACC,eAAe,aAAa,eAAe,aAC3C,CAAE,eAAe,WAAW,UAC5B,eAAe,YACd;AACD,YAAQ,cAAc,YAAY;AAClC,UAAM,eAAgB,cAAe;AACrC,UAAM,SAAU,IAAK;AACrB,WAAO,sBAAuB,KAAM;AAAA,EACrC;AAMA,MAAK,eAAe,aAAa,eAAe,WAAY;AAC3D,QAAI,SAAS,eAAe,WAAY,cAAc,CAAE;AACxD,WAAQ,QAAQ,WAAY;AAC3B,eAAS,OAAO;AAAA,IACjB;AACA,QAAI,QAAQ,eAAe,WAAY,WAAY;AACnD,WAAQ,OAAO,YAAa;AAC3B,cAAQ,MAAM;AAAA,IACf;AAEA,QAAI;AACJ,QAAK,UAAU,OAAO,aAAa,OAAO,WAAY;AACrD,oBAAc,cAAc,YAAY;AACxC,kBAAY,SAAU,QAAU,OAAiB,MAAO;AACxD,kBAAY,SAAU,IAAK;AAAA,IAC5B;AACA,QAAI;AACJ,QAAK,SAAS,MAAM,aAAa,MAAM,WAAY;AAClD,mBAAa,cAAc,YAAY;AACvC,iBAAW,SAAU,OAAO,CAAE;AAC9B,iBAAW,SAAU,IAAK;AAAA,IAC3B;AAEA,QAAK,eAAe,YAAa;AAChC,YAAM,aAAa,YAAY,eAAe,EAAG,CAAE;AACnD,YAAM,YAAY,WAAW,eAAe,EAAG,CAAE;AACjD,UACC,cACA,aACA,WAAW,UAAU,UAAU,KAC9B;AACD,eAAO;AAAA,MACR;AAAA,IACD;AAEA,QAAK,YAAa;AACjB,cAAQ;AAAA,IACT,WAAY,aAAc;AACzB,cAAQ;AAAA,IACT,OAAO;AACN,aAAO;AAAA,IACR;AAAA,EACD;AAEA,QAAM,QAAQ,MAAM,eAAe;AAInC,MAAK,MAAM,SAAS,GAAI;AACvB,WAAO;AAAA,EACR;AAQA,MACC,MAAM,WAAW,KACjB,eAAe,aAAa,eAAe,aAC3C,MAAM,cAAc,KACpB,MAAM,cAAgB,eAAyB,QAC9C;AACD,oBAAiB,eAAe,eAAgB;AAChD,UAAM,UAAU,CAAE,OAAe,QAAiB;AACjD,YAAM,YAAY,cAAc,YAAY;AAC5C,gBAAU,SAAU,gBAAgB,KAAM;AAC1C,gBAAU,OAAQ,gBAAgB,GAAI;AACtC,aAAO,UAAU,sBAAsB;AAAA,IACxC;AACA,UAAM,SAAS,QAAS,MAAM,cAAc,GAAG,MAAM,WAAY;AACjE,UAAM,QAAQ,QAAS,MAAM,aAAa,MAAM,cAAc,CAAE;AAEhE,QAAK,OAAO,UAAU,MAAM,KAAM;AACjC,aAAO;AAAA,IACR;AAAA,EACD;AAEA,SAAO,MAAO,CAAE,KAAK;AACtB;",
6
- "names": ["rects"]
7
- }
1
+ {"version":3,"file":"get-rectangle-from-range.mjs","names":[],"sources":["../../src/dom/get-rectangle-from-range.ts"],"sourcesContent":["import { assertIsDefined } from '../utils/assert-is-defined';\n\n/**\n * Get the rectangle of a given Range. Returns `null` if no suitable rectangle\n * can be found. Use instead of `Range.getBoundingClientRect()`, which is often\n * broken, especially for collapsed ranges.\n *\n * @param range The range.\n *\n * @return The rectangle.\n */\nexport default function getRectangleFromRange( range: Range ): DOMRect | null {\n\t// For uncollapsed ranges, get the rectangle that bounds the contents of the\n\t// range; this a rectangle enclosing the union of the bounding rectangles\n\t// for all the elements in the range.\n\tif ( ! range.collapsed ) {\n\t\tconst rects = Array.from( range.getClientRects() );\n\n\t\t// If there's just a single rect, return it.\n\t\tif ( rects.length === 1 ) {\n\t\t\treturn rects[ 0 ];\n\t\t}\n\n\t\t// Ignore tiny selection at the edge of a range.\n\t\tconst filteredRects = rects.filter( ( { width } ) => width > 1 );\n\n\t\t// If it's full of tiny selections, return browser default.\n\t\tif ( filteredRects.length === 0 ) {\n\t\t\treturn range.getBoundingClientRect();\n\t\t}\n\n\t\tif ( filteredRects.length === 1 ) {\n\t\t\treturn filteredRects[ 0 ];\n\t\t}\n\n\t\tlet {\n\t\t\ttop: furthestTop,\n\t\t\tbottom: furthestBottom,\n\t\t\tleft: furthestLeft,\n\t\t\tright: furthestRight,\n\t\t} = filteredRects[ 0 ];\n\n\t\tfor ( const { top, bottom, left, right } of filteredRects ) {\n\t\t\tif ( top < furthestTop ) {\n\t\t\t\tfurthestTop = top;\n\t\t\t}\n\t\t\tif ( bottom > furthestBottom ) {\n\t\t\t\tfurthestBottom = bottom;\n\t\t\t}\n\t\t\tif ( left < furthestLeft ) {\n\t\t\t\tfurthestLeft = left;\n\t\t\t}\n\t\t\tif ( right > furthestRight ) {\n\t\t\t\tfurthestRight = right;\n\t\t\t}\n\t\t}\n\n\t\treturn new window.DOMRect(\n\t\t\tfurthestLeft,\n\t\t\tfurthestTop,\n\t\t\tfurthestRight - furthestLeft,\n\t\t\tfurthestBottom - furthestTop\n\t\t);\n\t}\n\n\tconst { startContainer, startOffset } = range;\n\tconst { ownerDocument } = startContainer;\n\tassertIsDefined( ownerDocument, 'ownerDocument' );\n\n\t// A range inside an element with no children, like a line break or the\n\t// placeholder, is the same spot as the position before that element.\n\tif (\n\t\tstartContainer.nodeType !== startContainer.TEXT_NODE &&\n\t\t! startContainer.childNodes.length &&\n\t\tstartContainer.parentNode\n\t) {\n\t\trange = ownerDocument.createRange();\n\t\trange.setStartBefore( startContainer );\n\t\trange.collapse( true );\n\t\treturn getRectangleFromRange( range );\n\t}\n\n\t// A collapsed range at an element offset has no rectangle. Translate it\n\t// to the text offset next to it: the end of the text before or the start\n\t// of the text after. When those sit on different lines the caret could\n\t// be on either, so return null.\n\tif ( startContainer.nodeType !== startContainer.TEXT_NODE ) {\n\t\tlet before = startContainer.childNodes[ startOffset - 1 ];\n\t\twhile ( before?.lastChild ) {\n\t\t\tbefore = before.lastChild;\n\t\t}\n\t\tlet after = startContainer.childNodes[ startOffset ];\n\t\twhile ( after?.firstChild ) {\n\t\t\tafter = after.firstChild;\n\t\t}\n\n\t\tlet beforeRange;\n\t\tif ( before && before.nodeType === before.TEXT_NODE ) {\n\t\t\tbeforeRange = ownerDocument.createRange();\n\t\t\tbeforeRange.setStart( before, ( before as Text ).length );\n\t\t\tbeforeRange.collapse( true );\n\t\t}\n\t\tlet afterRange;\n\t\tif ( after && after.nodeType === after.TEXT_NODE ) {\n\t\t\tafterRange = ownerDocument.createRange();\n\t\t\tafterRange.setStart( after, 0 );\n\t\t\tafterRange.collapse( true );\n\t\t}\n\n\t\tif ( beforeRange && afterRange ) {\n\t\t\tconst beforeRect = beforeRange.getClientRects()[ 0 ];\n\t\t\tconst afterRect = afterRange.getClientRects()[ 0 ];\n\t\t\tif (\n\t\t\t\tbeforeRect &&\n\t\t\t\tafterRect &&\n\t\t\t\tbeforeRect.bottom <= afterRect.top\n\t\t\t) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tif ( afterRange ) {\n\t\t\trange = afterRange;\n\t\t} else if ( beforeRange ) {\n\t\t\trange = beforeRange;\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tconst rects = range.getClientRects();\n\n\t// If we have multiple rectangles for a collapsed range, there's no way to\n\t// know which it is, so don't return anything.\n\tif ( rects.length > 1 ) {\n\t\treturn null;\n\t}\n\n\t// A collapsed range at a soft line wrap is equally ambiguous: the same\n\t// position ends one line and starts the next. Some browsers (Gecko)\n\t// return a single rectangle for it, on the upper line, regardless of\n\t// where the caret is. Detect the boundary by measuring the characters\n\t// around the position: when they sit on different lines, there is no\n\t// way to know which line the caret is on, so don't return anything.\n\tif (\n\t\trects.length === 1 &&\n\t\tstartContainer.nodeType === startContainer.TEXT_NODE &&\n\t\trange.startOffset > 0 &&\n\t\trange.startOffset < ( startContainer as Text ).length\n\t) {\n\t\tassertIsDefined( ownerDocument, 'ownerDocument' );\n\t\tconst measure = ( start: number, end: number ) => {\n\t\t\tconst charRange = ownerDocument.createRange();\n\t\t\tcharRange.setStart( startContainer, start );\n\t\t\tcharRange.setEnd( startContainer, end );\n\t\t\treturn charRange.getBoundingClientRect();\n\t\t};\n\t\tconst before = measure( range.startOffset - 1, range.startOffset );\n\t\tconst after = measure( range.startOffset, range.startOffset + 1 );\n\n\t\tif ( before.bottom <= after.top ) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\treturn rects[ 0 ] ?? null;\n}\n"],"mappings":";;;;;;;;;;;AAWA,SAAwB,sBAAuB,OAA+B;CAI7E,IAAK,CAAE,MAAM,WAAY;EACxB,MAAM,QAAQ,MAAM,KAAM,MAAM,eAAe,CAAE;EAGjD,IAAK,MAAM,WAAW,GACrB,OAAO,MAAO;EAIf,MAAM,gBAAgB,MAAM,QAAU,EAAE,YAAa,QAAQ,CAAE;EAG/D,IAAK,cAAc,WAAW,GAC7B,OAAO,MAAM,sBAAsB;EAGpC,IAAK,cAAc,WAAW,GAC7B,OAAO,cAAe;EAGvB,IAAI,EACH,KAAK,aACL,QAAQ,gBACR,MAAM,cACN,OAAO,kBACJ,cAAe;EAEnB,KAAM,MAAM,EAAE,KAAK,QAAQ,MAAM,WAAW,eAAgB;GAC3D,IAAK,MAAM,aACV,cAAc;GAEf,IAAK,SAAS,gBACb,iBAAiB;GAElB,IAAK,OAAO,cACX,eAAe;GAEhB,IAAK,QAAQ,eACZ,gBAAgB;EAElB;EAEA,OAAO,IAAI,OAAO,QACjB,cACA,aACA,gBAAgB,cAChB,iBAAiB,WAClB;CACD;CAEA,MAAM,EAAE,gBAAgB,gBAAgB;CACxC,MAAM,EAAE,kBAAkB;CAC1B,gBAAiB,eAAe,eAAgB;CAIhD,IACC,eAAe,aAAa,eAAe,aAC3C,CAAE,eAAe,WAAW,UAC5B,eAAe,YACd;EACD,QAAQ,cAAc,YAAY;EAClC,MAAM,eAAgB,cAAe;EACrC,MAAM,SAAU,IAAK;EACrB,OAAO,sBAAuB,KAAM;CACrC;CAMA,IAAK,eAAe,aAAa,eAAe,WAAY;EAC3D,IAAI,SAAS,eAAe,WAAY,cAAc;EACtD,OAAQ,QAAQ,WACf,SAAS,OAAO;EAEjB,IAAI,QAAQ,eAAe,WAAY;EACvC,OAAQ,OAAO,YACd,QAAQ,MAAM;EAGf,IAAI;EACJ,IAAK,UAAU,OAAO,aAAa,OAAO,WAAY;GACrD,cAAc,cAAc,YAAY;GACxC,YAAY,SAAU,QAAU,OAAiB,MAAO;GACxD,YAAY,SAAU,IAAK;EAC5B;EACA,IAAI;EACJ,IAAK,SAAS,MAAM,aAAa,MAAM,WAAY;GAClD,aAAa,cAAc,YAAY;GACvC,WAAW,SAAU,OAAO,CAAE;GAC9B,WAAW,SAAU,IAAK;EAC3B;EAEA,IAAK,eAAe,YAAa;GAChC,MAAM,aAAa,YAAY,eAAe,CAAC,CAAE;GACjD,MAAM,YAAY,WAAW,eAAe,CAAC,CAAE;GAC/C,IACC,cACA,aACA,WAAW,UAAU,UAAU,KAE/B,OAAO;EAET;EAEA,IAAK,YACJ,QAAQ;OACF,IAAK,aACX,QAAQ;OAER,OAAO;CAET;CAEA,MAAM,QAAQ,MAAM,eAAe;CAInC,IAAK,MAAM,SAAS,GACnB,OAAO;CASR,IACC,MAAM,WAAW,KACjB,eAAe,aAAa,eAAe,aAC3C,MAAM,cAAc,KACpB,MAAM,cAAgB,eAAyB,QAC9C;EACD,gBAAiB,eAAe,eAAgB;EAChD,MAAM,WAAY,OAAe,QAAiB;GACjD,MAAM,YAAY,cAAc,YAAY;GAC5C,UAAU,SAAU,gBAAgB,KAAM;GAC1C,UAAU,OAAQ,gBAAgB,GAAI;GACtC,OAAO,UAAU,sBAAsB;EACxC;EACA,MAAM,SAAS,QAAS,MAAM,cAAc,GAAG,MAAM,WAAY;EACjE,MAAM,QAAQ,QAAS,MAAM,aAAa,MAAM,cAAc,CAAE;EAEhE,IAAK,OAAO,UAAU,MAAM,KAC3B,OAAO;CAET;CAEA,OAAO,MAAO,MAAO;AACtB"}
@@ -1,31 +1,31 @@
1
- // packages/dom/src/dom/get-scroll-container.ts
2
1
  import getComputedStyle from "./get-computed-style.mjs";
2
+ // packages/dom/src/dom/get-scroll-container.ts
3
+ /**
4
+ * Given a DOM node, finds the closest scrollable container node or the node
5
+ * itself, if scrollable.
6
+ *
7
+ * @param node Node from which to start.
8
+ * @param direction Direction of scrollable container to search for ('vertical', 'horizontal', 'all').
9
+ * Defaults to 'vertical'.
10
+ * @return Scrollable container node, if found.
11
+ */
3
12
  function getScrollContainer(node, direction = "vertical") {
4
- if (!node) {
5
- return void 0;
6
- }
7
- if (direction === "vertical" || direction === "all") {
8
- if (node.scrollHeight > node.clientHeight) {
9
- const { overflowY } = getComputedStyle(node);
10
- if (/(auto|scroll)/.test(overflowY)) {
11
- return node;
12
- }
13
- }
14
- }
15
- if (direction === "horizontal" || direction === "all") {
16
- if (node.scrollWidth > node.clientWidth) {
17
- const { overflowX } = getComputedStyle(node);
18
- if (/(auto|scroll)/.test(overflowX)) {
19
- return node;
20
- }
21
- }
22
- }
23
- if (node.ownerDocument === node.parentNode) {
24
- return node;
25
- }
26
- return getScrollContainer(node.parentNode, direction);
13
+ if (!node) return;
14
+ if (direction === "vertical" || direction === "all") {
15
+ if (node.scrollHeight > node.clientHeight) {
16
+ const { overflowY } = getComputedStyle(node);
17
+ if (/(auto|scroll)/.test(overflowY)) return node;
18
+ }
19
+ }
20
+ if (direction === "horizontal" || direction === "all") {
21
+ if (node.scrollWidth > node.clientWidth) {
22
+ const { overflowX } = getComputedStyle(node);
23
+ if (/(auto|scroll)/.test(overflowX)) return node;
24
+ }
25
+ }
26
+ if (node.ownerDocument === node.parentNode) return node;
27
+ return getScrollContainer(node.parentNode, direction);
27
28
  }
28
- export {
29
- getScrollContainer as default
30
- };
31
- //# sourceMappingURL=get-scroll-container.mjs.map
29
+ export { getScrollContainer as default };
30
+
31
+ //# sourceMappingURL=get-scroll-container.mjs.map
@@ -1,7 +1 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/dom/get-scroll-container.ts"],
4
- "sourcesContent": ["import getComputedStyle from './get-computed-style';\n\n/**\n * Given a DOM node, finds the closest scrollable container node or the node\n * itself, if scrollable.\n *\n * @param node Node from which to start.\n * @param direction Direction of scrollable container to search for ('vertical', 'horizontal', 'all').\n * Defaults to 'vertical'.\n * @return Scrollable container node, if found.\n */\nexport default function getScrollContainer(\n\tnode: Element | null,\n\tdirection: 'vertical' | 'horizontal' | 'all' = 'vertical'\n): Element | undefined {\n\tif ( ! node ) {\n\t\treturn undefined;\n\t}\n\n\tif ( direction === 'vertical' || direction === 'all' ) {\n\t\t// Scrollable if scrollable height exceeds displayed...\n\t\tif ( node.scrollHeight > node.clientHeight ) {\n\t\t\t// ...except when overflow is defined to be hidden or visible\n\t\t\tconst { overflowY } = getComputedStyle( node );\n\n\t\t\tif ( /(auto|scroll)/.test( overflowY ) ) {\n\t\t\t\treturn node;\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( direction === 'horizontal' || direction === 'all' ) {\n\t\t// Scrollable if scrollable width exceeds displayed...\n\t\tif ( node.scrollWidth > node.clientWidth ) {\n\t\t\t// ...except when overflow is defined to be hidden or visible\n\t\t\tconst { overflowX } = getComputedStyle( node );\n\n\t\t\tif ( /(auto|scroll)/.test( overflowX ) ) {\n\t\t\t\treturn node;\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( node.ownerDocument === node.parentNode ) {\n\t\treturn node;\n\t}\n\n\t// Continue traversing.\n\treturn getScrollContainer( node.parentNode as Element, direction );\n}\n"],
5
- "mappings": ";AAAA,OAAO,sBAAsB;AAWd,SAAR,mBACN,MACA,YAA+C,YACzB;AACtB,MAAK,CAAE,MAAO;AACb,WAAO;AAAA,EACR;AAEA,MAAK,cAAc,cAAc,cAAc,OAAQ;AAEtD,QAAK,KAAK,eAAe,KAAK,cAAe;AAE5C,YAAM,EAAE,UAAU,IAAI,iBAAkB,IAAK;AAE7C,UAAK,gBAAgB,KAAM,SAAU,GAAI;AACxC,eAAO;AAAA,MACR;AAAA,IACD;AAAA,EACD;AAEA,MAAK,cAAc,gBAAgB,cAAc,OAAQ;AAExD,QAAK,KAAK,cAAc,KAAK,aAAc;AAE1C,YAAM,EAAE,UAAU,IAAI,iBAAkB,IAAK;AAE7C,UAAK,gBAAgB,KAAM,SAAU,GAAI;AACxC,eAAO;AAAA,MACR;AAAA,IACD;AAAA,EACD;AAEA,MAAK,KAAK,kBAAkB,KAAK,YAAa;AAC7C,WAAO;AAAA,EACR;AAGA,SAAO,mBAAoB,KAAK,YAAuB,SAAU;AAClE;",
6
- "names": []
7
- }
1
+ {"version":3,"file":"get-scroll-container.mjs","names":[],"sources":["../../src/dom/get-scroll-container.ts"],"sourcesContent":["import getComputedStyle from './get-computed-style';\n\n/**\n * Given a DOM node, finds the closest scrollable container node or the node\n * itself, if scrollable.\n *\n * @param node Node from which to start.\n * @param direction Direction of scrollable container to search for ('vertical', 'horizontal', 'all').\n * Defaults to 'vertical'.\n * @return Scrollable container node, if found.\n */\nexport default function getScrollContainer(\n\tnode: Element | null,\n\tdirection: 'vertical' | 'horizontal' | 'all' = 'vertical'\n): Element | undefined {\n\tif ( ! node ) {\n\t\treturn undefined;\n\t}\n\n\tif ( direction === 'vertical' || direction === 'all' ) {\n\t\t// Scrollable if scrollable height exceeds displayed...\n\t\tif ( node.scrollHeight > node.clientHeight ) {\n\t\t\t// ...except when overflow is defined to be hidden or visible\n\t\t\tconst { overflowY } = getComputedStyle( node );\n\n\t\t\tif ( /(auto|scroll)/.test( overflowY ) ) {\n\t\t\t\treturn node;\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( direction === 'horizontal' || direction === 'all' ) {\n\t\t// Scrollable if scrollable width exceeds displayed...\n\t\tif ( node.scrollWidth > node.clientWidth ) {\n\t\t\t// ...except when overflow is defined to be hidden or visible\n\t\t\tconst { overflowX } = getComputedStyle( node );\n\n\t\t\tif ( /(auto|scroll)/.test( overflowX ) ) {\n\t\t\t\treturn node;\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( node.ownerDocument === node.parentNode ) {\n\t\treturn node;\n\t}\n\n\t// Continue traversing.\n\treturn getScrollContainer( node.parentNode as Element, direction );\n}\n"],"mappings":";;;;;;;;;;;AAWA,SAAwB,mBACvB,MACA,YAA+C,YACzB;CACtB,IAAK,CAAE,MACN;CAGD,IAAK,cAAc,cAAc,cAAc,OAEzC;MAAA,KAAK,eAAe,KAAK,cAAe;GAE5C,MAAM,EAAE,cAAc,iBAAkB,IAAK;GAE7C,IAAK,gBAAgB,KAAM,SAAU,GACpC,OAAO;EAET;;CAGD,IAAK,cAAc,gBAAgB,cAAc,OAE3C;MAAA,KAAK,cAAc,KAAK,aAAc;GAE1C,MAAM,EAAE,cAAc,iBAAkB,IAAK;GAE7C,IAAK,gBAAgB,KAAM,SAAU,GACpC,OAAO;EAET;;CAGD,IAAK,KAAK,kBAAkB,KAAK,YAChC,OAAO;CAIR,OAAO,mBAAoB,KAAK,YAAuB,SAAU;AAClE"}
@@ -1,23 +1,32 @@
1
- // packages/dom/src/dom/hidden-caret-range-from-point.ts
2
1
  import caretRangeFromPoint from "./caret-range-from-point.mjs";
3
2
  import getComputedStyle from "./get-computed-style.mjs";
3
+ // packages/dom/src/dom/hidden-caret-range-from-point.ts
4
+ /**
5
+ * Get a collapsed range for a given point.
6
+ * Gives the container a temporary high z-index (above any UI).
7
+ * This is preferred over getting the UI nodes and set styles there.
8
+ *
9
+ * @param doc The document of the range.
10
+ * @param x Horizontal position within the current viewport.
11
+ * @param y Vertical position within the current viewport.
12
+ * @param container Container in which the range is expected to be found.
13
+ *
14
+ * @return The best range for the given point.
15
+ */
4
16
  function hiddenCaretRangeFromPoint(doc, x, y, container) {
5
- const originalZIndex = container.style.zIndex;
6
- const originalPosition = container.style.position;
7
- const originalBorderRadius = container.style.borderRadius;
8
- const { position = "static" } = getComputedStyle(container);
9
- if (position === "static") {
10
- container.style.position = "relative";
11
- }
12
- container.style.zIndex = "10000";
13
- container.style.borderRadius = "0";
14
- const range = caretRangeFromPoint(doc, x, y);
15
- container.style.zIndex = originalZIndex;
16
- container.style.position = originalPosition;
17
- container.style.borderRadius = originalBorderRadius;
18
- return range;
17
+ const originalZIndex = container.style.zIndex;
18
+ const originalPosition = container.style.position;
19
+ const originalBorderRadius = container.style.borderRadius;
20
+ const { position = "static" } = getComputedStyle(container);
21
+ if (position === "static") container.style.position = "relative";
22
+ container.style.zIndex = "10000";
23
+ container.style.borderRadius = "0";
24
+ const range = caretRangeFromPoint(doc, x, y);
25
+ container.style.zIndex = originalZIndex;
26
+ container.style.position = originalPosition;
27
+ container.style.borderRadius = originalBorderRadius;
28
+ return range;
19
29
  }
20
- export {
21
- hiddenCaretRangeFromPoint as default
22
- };
23
- //# sourceMappingURL=hidden-caret-range-from-point.mjs.map
30
+ export { hiddenCaretRangeFromPoint as default };
31
+
32
+ //# sourceMappingURL=hidden-caret-range-from-point.mjs.map
@@ -1,7 +1 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/dom/hidden-caret-range-from-point.ts"],
4
- "sourcesContent": ["import caretRangeFromPoint from './caret-range-from-point';\nimport getComputedStyle from './get-computed-style';\n\n/**\n * Get a collapsed range for a given point.\n * Gives the container a temporary high z-index (above any UI).\n * This is preferred over getting the UI nodes and set styles there.\n *\n * @param doc The document of the range.\n * @param x Horizontal position within the current viewport.\n * @param y Vertical position within the current viewport.\n * @param container Container in which the range is expected to be found.\n *\n * @return The best range for the given point.\n */\nexport default function hiddenCaretRangeFromPoint(\n\tdoc: Document,\n\tx: number,\n\ty: number,\n\tcontainer: HTMLElement\n): Range | null {\n\tconst originalZIndex = container.style.zIndex;\n\tconst originalPosition = container.style.position;\n\tconst originalBorderRadius = container.style.borderRadius;\n\n\tconst { position = 'static' } = getComputedStyle( container );\n\n\t// A z-index only works if the element position is not static.\n\tif ( position === 'static' ) {\n\t\tcontainer.style.position = 'relative';\n\t}\n\n\tcontainer.style.zIndex = '10000';\n\n\t// When an element has border radius, the x/y coordinates can incorrectly fall\n\t// outside the element because of the radius. Temporarily reset the value\n\t// to ensure the coordinates are tested against a rectangle and not a pill-shaped\n\t// element. See https://github.com/WordPress/gutenberg/issues/72053 for more info.\n\tcontainer.style.borderRadius = '0';\n\n\tconst range = caretRangeFromPoint( doc, x, y );\n\n\tcontainer.style.zIndex = originalZIndex;\n\tcontainer.style.position = originalPosition;\n\tcontainer.style.borderRadius = originalBorderRadius;\n\n\treturn range;\n}\n"],
5
- "mappings": ";AAAA,OAAO,yBAAyB;AAChC,OAAO,sBAAsB;AAcd,SAAR,0BACN,KACA,GACA,GACA,WACe;AACf,QAAM,iBAAiB,UAAU,MAAM;AACvC,QAAM,mBAAmB,UAAU,MAAM;AACzC,QAAM,uBAAuB,UAAU,MAAM;AAE7C,QAAM,EAAE,WAAW,SAAS,IAAI,iBAAkB,SAAU;AAG5D,MAAK,aAAa,UAAW;AAC5B,cAAU,MAAM,WAAW;AAAA,EAC5B;AAEA,YAAU,MAAM,SAAS;AAMzB,YAAU,MAAM,eAAe;AAE/B,QAAM,QAAQ,oBAAqB,KAAK,GAAG,CAAE;AAE7C,YAAU,MAAM,SAAS;AACzB,YAAU,MAAM,WAAW;AAC3B,YAAU,MAAM,eAAe;AAE/B,SAAO;AACR;",
6
- "names": []
7
- }
1
+ {"version":3,"file":"hidden-caret-range-from-point.mjs","names":[],"sources":["../../src/dom/hidden-caret-range-from-point.ts"],"sourcesContent":["import caretRangeFromPoint from './caret-range-from-point';\nimport getComputedStyle from './get-computed-style';\n\n/**\n * Get a collapsed range for a given point.\n * Gives the container a temporary high z-index (above any UI).\n * This is preferred over getting the UI nodes and set styles there.\n *\n * @param doc The document of the range.\n * @param x Horizontal position within the current viewport.\n * @param y Vertical position within the current viewport.\n * @param container Container in which the range is expected to be found.\n *\n * @return The best range for the given point.\n */\nexport default function hiddenCaretRangeFromPoint(\n\tdoc: Document,\n\tx: number,\n\ty: number,\n\tcontainer: HTMLElement\n): Range | null {\n\tconst originalZIndex = container.style.zIndex;\n\tconst originalPosition = container.style.position;\n\tconst originalBorderRadius = container.style.borderRadius;\n\n\tconst { position = 'static' } = getComputedStyle( container );\n\n\t// A z-index only works if the element position is not static.\n\tif ( position === 'static' ) {\n\t\tcontainer.style.position = 'relative';\n\t}\n\n\tcontainer.style.zIndex = '10000';\n\n\t// When an element has border radius, the x/y coordinates can incorrectly fall\n\t// outside the element because of the radius. Temporarily reset the value\n\t// to ensure the coordinates are tested against a rectangle and not a pill-shaped\n\t// element. See https://github.com/WordPress/gutenberg/issues/72053 for more info.\n\tcontainer.style.borderRadius = '0';\n\n\tconst range = caretRangeFromPoint( doc, x, y );\n\n\tcontainer.style.zIndex = originalZIndex;\n\tcontainer.style.position = originalPosition;\n\tcontainer.style.borderRadius = originalBorderRadius;\n\n\treturn range;\n}\n"],"mappings":";;;;;;;;;;;;;;;AAeA,SAAwB,0BACvB,KACA,GACA,GACA,WACe;CACf,MAAM,iBAAiB,UAAU,MAAM;CACvC,MAAM,mBAAmB,UAAU,MAAM;CACzC,MAAM,uBAAuB,UAAU,MAAM;CAE7C,MAAM,EAAE,WAAW,aAAa,iBAAkB,SAAU;CAG5D,IAAK,aAAa,UACjB,UAAU,MAAM,WAAW;CAG5B,UAAU,MAAM,SAAS;CAMzB,UAAU,MAAM,eAAe;CAE/B,MAAM,QAAQ,oBAAqB,KAAK,GAAG,CAAE;CAE7C,UAAU,MAAM,SAAS;CACzB,UAAU,MAAM,WAAW;CAC3B,UAAU,MAAM,eAAe;CAE/B,OAAO;AACR"}
@@ -1,58 +1,28 @@
1
- // packages/dom/src/dom/index.ts
2
- import { default as default2 } from "./compute-caret-rect.mjs";
3
- import { default as default3 } from "./document-has-text-selection.mjs";
4
- import { default as default4 } from "./document-has-uncollapsed-selection.mjs";
5
- import { default as default5 } from "./document-has-selection.mjs";
6
- import { default as default6 } from "./get-rectangle-from-range.mjs";
7
- import { default as default7 } from "./get-scroll-container.mjs";
8
- import { default as default8 } from "./get-offset-parent.mjs";
9
- import { default as default9 } from "./is-entirely-selected.mjs";
10
- import { default as default10 } from "./is-form-element.mjs";
11
- import { default as default11 } from "./is-horizontal-edge.mjs";
12
- import { default as default12 } from "./is-number-input.mjs";
13
- import { default as default13 } from "./is-text-field.mjs";
14
- import { default as default14 } from "./is-vertical-edge.mjs";
15
- import { default as default15 } from "./place-caret-at-horizontal-edge.mjs";
16
- import { default as default16 } from "./place-caret-at-vertical-edge.mjs";
17
- import { default as default17 } from "./replace.mjs";
18
- import { default as default18 } from "./remove.mjs";
19
- import { default as default19 } from "./insert-after.mjs";
20
- import { default as default20 } from "./unwrap.mjs";
21
- import { default as default21 } from "./replace-tag.mjs";
22
- import { default as default22 } from "./wrap.mjs";
23
- import { default as default23 } from "./strip-html.mjs";
24
- import { default as default24 } from "./is-empty.mjs";
25
- import { default as default25 } from "./remove-invalid-html.mjs";
26
- import { default as default26 } from "./is-rtl.mjs";
27
- import { default as default27 } from "./safe-html.mjs";
28
- import { default as default28 } from "./is-selection-forward.mjs";
29
- export {
30
- default23 as __unstableStripHTML,
31
- default2 as computeCaretRect,
32
- default5 as documentHasSelection,
33
- default3 as documentHasTextSelection,
34
- default4 as documentHasUncollapsedSelection,
35
- default8 as getOffsetParent,
36
- default6 as getRectangleFromRange,
37
- default7 as getScrollContainer,
38
- default19 as insertAfter,
39
- default24 as isEmpty,
40
- default9 as isEntirelySelected,
41
- default10 as isFormElement,
42
- default11 as isHorizontalEdge,
43
- default12 as isNumberInput,
44
- default26 as isRTL,
45
- default28 as isSelectionForward,
46
- default13 as isTextField,
47
- default14 as isVerticalEdge,
48
- default15 as placeCaretAtHorizontalEdge,
49
- default16 as placeCaretAtVerticalEdge,
50
- default18 as remove,
51
- default25 as removeInvalidHTML,
52
- default17 as replace,
53
- default21 as replaceTag,
54
- default27 as safeHTML,
55
- default20 as unwrap,
56
- default22 as wrap
57
- };
58
- //# sourceMappingURL=index.mjs.map
1
+ import computeCaretRect from "./compute-caret-rect.mjs";
2
+ import documentHasTextSelection from "./document-has-text-selection.mjs";
3
+ import documentHasUncollapsedSelection from "./document-has-uncollapsed-selection.mjs";
4
+ import documentHasSelection from "./document-has-selection.mjs";
5
+ import getRectangleFromRange from "./get-rectangle-from-range.mjs";
6
+ import getScrollContainer from "./get-scroll-container.mjs";
7
+ import getOffsetParent from "./get-offset-parent.mjs";
8
+ import isEntirelySelected from "./is-entirely-selected.mjs";
9
+ import isFormElement from "./is-form-element.mjs";
10
+ import isHorizontalEdge from "./is-horizontal-edge.mjs";
11
+ import isNumberInput from "./is-number-input.mjs";
12
+ import isTextField from "./is-text-field.mjs";
13
+ import isVerticalEdge from "./is-vertical-edge.mjs";
14
+ import placeCaretAtHorizontalEdge from "./place-caret-at-horizontal-edge.mjs";
15
+ import placeCaretAtVerticalEdge from "./place-caret-at-vertical-edge.mjs";
16
+ import replace from "./replace.mjs";
17
+ import remove from "./remove.mjs";
18
+ import insertAfter from "./insert-after.mjs";
19
+ import unwrap from "./unwrap.mjs";
20
+ import replaceTag from "./replace-tag.mjs";
21
+ import wrap from "./wrap.mjs";
22
+ import __unstableStripHTML from "./strip-html.mjs";
23
+ import isEmpty from "./is-empty.mjs";
24
+ import removeInvalidHTML from "./remove-invalid-html.mjs";
25
+ import isRTL from "./is-rtl.mjs";
26
+ import safeHTML from "./safe-html.mjs";
27
+ import isSelectionForward from "./is-selection-forward.mjs";
28
+ export { __unstableStripHTML, computeCaretRect, documentHasSelection, documentHasTextSelection, documentHasUncollapsedSelection, getOffsetParent, getRectangleFromRange, getScrollContainer, insertAfter, isEmpty, isEntirelySelected, isFormElement, isHorizontalEdge, isNumberInput, isRTL, isSelectionForward, isTextField, isVerticalEdge, placeCaretAtHorizontalEdge, placeCaretAtVerticalEdge, remove, removeInvalidHTML, replace, replaceTag, safeHTML, unwrap, wrap };
@@ -1,24 +1,32 @@
1
- // packages/dom/src/dom/input-field-has-uncollapsed-selection.ts
2
1
  import isTextField from "./is-text-field.mjs";
3
2
  import isHTMLInputElement from "./is-html-input-element.mjs";
3
+ // packages/dom/src/dom/input-field-has-uncollapsed-selection.ts
4
+ /**
5
+ * Check whether the given input field or textarea contains a (uncollapsed)
6
+ * selection of text.
7
+ *
8
+ * CAVEAT: Only specific text-based HTML inputs support the selection APIs
9
+ * needed to determine whether they have a collapsed or uncollapsed selection.
10
+ * This function defaults to returning `true` when the selection cannot be
11
+ * inspected, such as with `<input type="time">`. The rationale is that this
12
+ * should cause the block editor to defer to the browser's native selection
13
+ * handling (e.g. copying and pasting), thereby reducing friction for the user.
14
+ *
15
+ * See: https://html.spec.whatwg.org/multipage/input.html#do-not-apply
16
+ *
17
+ * @param element The HTML element.
18
+ *
19
+ * @return Whether the input/textarea element has some "selection".
20
+ */
4
21
  function inputFieldHasUncollapsedSelection(element) {
5
- if (!isHTMLInputElement(element) && !isTextField(element)) {
6
- return false;
7
- }
8
- try {
9
- const { selectionStart, selectionEnd } = element;
10
- return (
11
- // `null` means the input type doesn't implement selection, thus we
12
- // cannot determine whether the selection is collapsed, so we
13
- // default to true.
14
- selectionStart === null || // when not null, compare the two points
15
- selectionStart !== selectionEnd
16
- );
17
- } catch {
18
- return true;
19
- }
22
+ if (!isHTMLInputElement(element) && !isTextField(element)) return false;
23
+ try {
24
+ const { selectionStart, selectionEnd } = element;
25
+ return selectionStart === null || selectionStart !== selectionEnd;
26
+ } catch {
27
+ return true;
28
+ }
20
29
  }
21
- export {
22
- inputFieldHasUncollapsedSelection as default
23
- };
24
- //# sourceMappingURL=input-field-has-uncollapsed-selection.mjs.map
30
+ export { inputFieldHasUncollapsedSelection as default };
31
+
32
+ //# sourceMappingURL=input-field-has-uncollapsed-selection.mjs.map