PluginProbe
Gutenberg / 23.7.2
Gutenberg v23.7.2
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 23.7.2, at build/scripts/dom/index.js

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