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

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