PluginProbe
Gutenberg / 22.3.0
Gutenberg v22.3.0
23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 7.4.0 All 402 releases
gutenberg / build / scripts / dom / index.js

index.js in Gutenberg 22.3.0, at build/scripts/dom/index.js

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