PluginProbe
Gutenberg / trunk
Gutenberg vtrunk
24.1.0 24.0.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 All 404 releases
gutenberg / build / scripts / dom / index.js

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

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