[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 /******/ (() => { // webpackBootstrap 2 /******/ "use strict"; 3 /******/ // The require scope 4 /******/ var __webpack_require__ = {}; 5 /******/ 6 /************************************************************************/ 7 /******/ /* webpack/runtime/compat get default export */ 8 /******/ (() => { 9 /******/ // getDefaultExport function for compatibility with non-harmony modules 10 /******/ __webpack_require__.n = (module) => { 11 /******/ var getter = module && module.__esModule ? 12 /******/ () => (module['default']) : 13 /******/ () => (module); 14 /******/ __webpack_require__.d(getter, { a: getter }); 15 /******/ return getter; 16 /******/ }; 17 /******/ })(); 18 /******/ 19 /******/ /* webpack/runtime/define property getters */ 20 /******/ (() => { 21 /******/ // define getter functions for harmony exports 22 /******/ __webpack_require__.d = (exports, definition) => { 23 /******/ for(var key in definition) { 24 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { 25 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); 26 /******/ } 27 /******/ } 28 /******/ }; 29 /******/ })(); 30 /******/ 31 /******/ /* webpack/runtime/hasOwnProperty shorthand */ 32 /******/ (() => { 33 /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) 34 /******/ })(); 35 /******/ 36 /******/ /* webpack/runtime/make namespace object */ 37 /******/ (() => { 38 /******/ // define __esModule on exports 39 /******/ __webpack_require__.r = (exports) => { 40 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 41 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 42 /******/ } 43 /******/ Object.defineProperty(exports, '__esModule', { value: true }); 44 /******/ }; 45 /******/ })(); 46 /******/ 47 /************************************************************************/ 48 var __webpack_exports__ = {}; 49 // ESM COMPAT FLAG 50 __webpack_require__.r(__webpack_exports__); 51 52 // EXPORTS 53 __webpack_require__.d(__webpack_exports__, { 54 __unstableStripHTML: () => (/* reexport */ stripHTML), 55 computeCaretRect: () => (/* reexport */ computeCaretRect), 56 documentHasSelection: () => (/* reexport */ documentHasSelection), 57 documentHasTextSelection: () => (/* reexport */ documentHasTextSelection), 58 documentHasUncollapsedSelection: () => (/* reexport */ documentHasUncollapsedSelection), 59 focus: () => (/* binding */ build_module_focus), 60 getFilesFromDataTransfer: () => (/* reexport */ getFilesFromDataTransfer), 61 getOffsetParent: () => (/* reexport */ getOffsetParent), 62 getPhrasingContentSchema: () => (/* reexport */ getPhrasingContentSchema), 63 getRectangleFromRange: () => (/* reexport */ getRectangleFromRange), 64 getScrollContainer: () => (/* reexport */ getScrollContainer), 65 insertAfter: () => (/* reexport */ insertAfter), 66 isEmpty: () => (/* reexport */ isEmpty), 67 isEntirelySelected: () => (/* reexport */ isEntirelySelected), 68 isFormElement: () => (/* reexport */ isFormElement), 69 isHorizontalEdge: () => (/* reexport */ isHorizontalEdge), 70 isNumberInput: () => (/* reexport */ isNumberInput), 71 isPhrasingContent: () => (/* reexport */ isPhrasingContent), 72 isRTL: () => (/* reexport */ isRTL), 73 isSelectionForward: () => (/* reexport */ isSelectionForward), 74 isTextContent: () => (/* reexport */ isTextContent), 75 isTextField: () => (/* reexport */ isTextField), 76 isVerticalEdge: () => (/* reexport */ isVerticalEdge), 77 placeCaretAtHorizontalEdge: () => (/* reexport */ placeCaretAtHorizontalEdge), 78 placeCaretAtVerticalEdge: () => (/* reexport */ placeCaretAtVerticalEdge), 79 remove: () => (/* reexport */ remove), 80 removeInvalidHTML: () => (/* reexport */ removeInvalidHTML), 81 replace: () => (/* reexport */ replace), 82 replaceTag: () => (/* reexport */ replaceTag), 83 safeHTML: () => (/* reexport */ safeHTML), 84 unwrap: () => (/* reexport */ unwrap), 85 wrap: () => (/* reexport */ wrap) 86 }); 87 88 // NAMESPACE OBJECT: ./node_modules/@wordpress/dom/build-module/focusable.js 89 var focusable_namespaceObject = {}; 90 __webpack_require__.r(focusable_namespaceObject); 91 __webpack_require__.d(focusable_namespaceObject, { 92 find: () => (find) 93 }); 94 95 // NAMESPACE OBJECT: ./node_modules/@wordpress/dom/build-module/tabbable.js 96 var tabbable_namespaceObject = {}; 97 __webpack_require__.r(tabbable_namespaceObject); 98 __webpack_require__.d(tabbable_namespaceObject, { 99 find: () => (tabbable_find), 100 findNext: () => (findNext), 101 findPrevious: () => (findPrevious), 102 isTabbableIndex: () => (isTabbableIndex) 103 }); 104 105 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/focusable.js 106 /** 107 * References: 108 * 109 * Focusable: 110 * - https://www.w3.org/TR/html5/editing.html#focus-management 111 * 112 * Sequential focus navigation: 113 * - https://www.w3.org/TR/html5/editing.html#sequential-focus-navigation-and-the-tabindex-attribute 114 * 115 * Disabled elements: 116 * - https://www.w3.org/TR/html5/disabled-elements.html#disabled-elements 117 * 118 * getClientRects algorithm (requiring layout box): 119 * - https://www.w3.org/TR/cssom-view-1/#extension-to-the-element-interface 120 * 121 * AREA elements associated with an IMG: 122 * - https://w3c.github.io/html/editing.html#data-model 123 */ 124 125 /** 126 * Returns a CSS selector used to query for focusable elements. 127 * 128 * @param {boolean} sequential If set, only query elements that are sequentially 129 * focusable. Non-interactive elements with a 130 * negative `tabindex` are focusable but not 131 * sequentially focusable. 132 * https://html.spec.whatwg.org/multipage/interaction.html#the-tabindex-attribute 133 * 134 * @return {string} CSS selector. 135 */ 136 function buildSelector(sequential) { 137 return [sequential ? '[tabindex]:not([tabindex^="-"])' : '[tabindex]', 'a[href]', 'button:not([disabled])', 'input:not([type="hidden"]):not([disabled])', 'select:not([disabled])', 'textarea:not([disabled])', 'iframe:not([tabindex^="-"])', 'object', 'embed', 'area[href]', '[contenteditable]:not([contenteditable=false])'].join(','); 138 } 139 140 /** 141 * Returns true if the specified element is visible (i.e. neither display: none 142 * nor visibility: hidden). 143 * 144 * @param {HTMLElement} element DOM element to test. 145 * 146 * @return {boolean} Whether element is visible. 147 */ 148 function isVisible(element) { 149 return element.offsetWidth > 0 || element.offsetHeight > 0 || element.getClientRects().length > 0; 150 } 151 152 /** 153 * Returns true if the specified area element is a valid focusable element, or 154 * false otherwise. Area is only focusable if within a map where a named map 155 * referenced by an image somewhere in the document. 156 * 157 * @param {HTMLAreaElement} element DOM area element to test. 158 * 159 * @return {boolean} Whether area element is valid for focus. 160 */ 161 function isValidFocusableArea(element) { 162 /** @type {HTMLMapElement | null} */ 163 const map = element.closest('map[name]'); 164 if (!map) { 165 return false; 166 } 167 168 /** @type {HTMLImageElement | null} */ 169 const img = element.ownerDocument.querySelector('img[usemap="#' + map.name + '"]'); 170 return !!img && isVisible(img); 171 } 172 173 /** 174 * Returns all focusable elements within a given context. 175 * 176 * @param {Element} context Element in which to search. 177 * @param {Object} options 178 * @param {boolean} [options.sequential] If set, only return elements that are 179 * sequentially focusable. 180 * Non-interactive elements with a 181 * negative `tabindex` are focusable but 182 * not sequentially focusable. 183 * https://html.spec.whatwg.org/multipage/interaction.html#the-tabindex-attribute 184 * 185 * @return {HTMLElement[]} Focusable elements. 186 */ 187 function find(context, { 188 sequential = false 189 } = {}) { 190 /** @type {NodeListOf<HTMLElement>} */ 191 const elements = context.querySelectorAll(buildSelector(sequential)); 192 return Array.from(elements).filter(element => { 193 if (!isVisible(element)) { 194 return false; 195 } 196 const { 197 nodeName 198 } = element; 199 if ('AREA' === nodeName) { 200 return isValidFocusableArea( /** @type {HTMLAreaElement} */element); 201 } 202 return true; 203 }); 204 } 205 206 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/tabbable.js 207 /** 208 * Internal dependencies 209 */ 210 211 212 /** 213 * Returns the tab index of the given element. In contrast with the tabIndex 214 * property, this normalizes the default (0) to avoid browser inconsistencies, 215 * operating under the assumption that this function is only ever called with a 216 * focusable node. 217 * 218 * @see https://bugzilla.mozilla.org/show_bug.cgi?id=1190261 219 * 220 * @param {Element} element Element from which to retrieve. 221 * 222 * @return {number} Tab index of element (default 0). 223 */ 224 function getTabIndex(element) { 225 const tabIndex = element.getAttribute('tabindex'); 226 return tabIndex === null ? 0 : parseInt(tabIndex, 10); 227 } 228 229 /** 230 * Returns true if the specified element is tabbable, or false otherwise. 231 * 232 * @param {Element} element Element to test. 233 * 234 * @return {boolean} Whether element is tabbable. 235 */ 236 function isTabbableIndex(element) { 237 return getTabIndex(element) !== -1; 238 } 239 240 /** @typedef {HTMLElement & { type?: string, checked?: boolean, name?: string }} MaybeHTMLInputElement */ 241 242 /** 243 * Returns a stateful reducer function which constructs a filtered array of 244 * tabbable elements, where at most one radio input is selected for a given 245 * name, giving priority to checked input, falling back to the first 246 * encountered. 247 * 248 * @return {(acc: MaybeHTMLInputElement[], el: MaybeHTMLInputElement) => MaybeHTMLInputElement[]} Radio group collapse reducer. 249 */ 250 function createStatefulCollapseRadioGroup() { 251 /** @type {Record<string, MaybeHTMLInputElement>} */ 252 const CHOSEN_RADIO_BY_NAME = {}; 253 return function collapseRadioGroup( /** @type {MaybeHTMLInputElement[]} */result, /** @type {MaybeHTMLInputElement} */element) { 254 const { 255 nodeName, 256 type, 257 checked, 258 name 259 } = element; 260 261 // For all non-radio tabbables, construct to array by concatenating. 262 if (nodeName !== 'INPUT' || type !== 'radio' || !name) { 263 return result.concat(element); 264 } 265 const hasChosen = CHOSEN_RADIO_BY_NAME.hasOwnProperty(name); 266 267 // Omit by skipping concatenation if the radio element is not chosen. 268 const isChosen = checked || !hasChosen; 269 if (!isChosen) { 270 return result; 271 } 272 273 // At this point, if there had been a chosen element, the current 274 // element is checked and should take priority. Retroactively remove 275 // the element which had previously been considered the chosen one. 276 if (hasChosen) { 277 const hadChosenElement = CHOSEN_RADIO_BY_NAME[name]; 278 result = result.filter(e => e !== hadChosenElement); 279 } 280 CHOSEN_RADIO_BY_NAME[name] = element; 281 return result.concat(element); 282 }; 283 } 284 285 /** 286 * An array map callback, returning an object with the element value and its 287 * array index location as properties. This is used to emulate a proper stable 288 * sort where equal tabIndex should be left in order of their occurrence in the 289 * document. 290 * 291 * @param {HTMLElement} element Element. 292 * @param {number} index Array index of element. 293 * 294 * @return {{ element: HTMLElement, index: number }} Mapped object with element, index. 295 */ 296 function mapElementToObjectTabbable(element, index) { 297 return { 298 element, 299 index 300 }; 301 } 302 303 /** 304 * An array map callback, returning an element of the given mapped object's 305 * element value. 306 * 307 * @param {{ element: HTMLElement }} object Mapped object with element. 308 * 309 * @return {HTMLElement} Mapped object element. 310 */ 311 function mapObjectTabbableToElement(object) { 312 return object.element; 313 } 314 315 /** 316 * A sort comparator function used in comparing two objects of mapped elements. 317 * 318 * @see mapElementToObjectTabbable 319 * 320 * @param {{ element: HTMLElement, index: number }} a First object to compare. 321 * @param {{ element: HTMLElement, index: number }} b Second object to compare. 322 * 323 * @return {number} Comparator result. 324 */ 325 function compareObjectTabbables(a, b) { 326 const aTabIndex = getTabIndex(a.element); 327 const bTabIndex = getTabIndex(b.element); 328 if (aTabIndex === bTabIndex) { 329 return a.index - b.index; 330 } 331 return aTabIndex - bTabIndex; 332 } 333 334 /** 335 * Givin focusable elements, filters out tabbable element. 336 * 337 * @param {HTMLElement[]} focusables Focusable elements to filter. 338 * 339 * @return {HTMLElement[]} Tabbable elements. 340 */ 341 function filterTabbable(focusables) { 342 return focusables.filter(isTabbableIndex).map(mapElementToObjectTabbable).sort(compareObjectTabbables).map(mapObjectTabbableToElement).reduce(createStatefulCollapseRadioGroup(), []); 343 } 344 345 /** 346 * @param {Element} context 347 * @return {HTMLElement[]} Tabbable elements within the context. 348 */ 349 function tabbable_find(context) { 350 return filterTabbable(find(context)); 351 } 352 353 /** 354 * Given a focusable element, find the preceding tabbable element. 355 * 356 * @param {Element} element The focusable element before which to look. Defaults 357 * to the active element. 358 * 359 * @return {HTMLElement|undefined} Preceding tabbable element. 360 */ 361 function findPrevious(element) { 362 return filterTabbable(find(element.ownerDocument.body)).reverse().find(focusable => 363 // eslint-disable-next-line no-bitwise 364 element.compareDocumentPosition(focusable) & element.DOCUMENT_POSITION_PRECEDING); 365 } 366 367 /** 368 * Given a focusable element, find the next tabbable element. 369 * 370 * @param {Element} element The focusable element after which to look. Defaults 371 * to the active element. 372 * 373 * @return {HTMLElement|undefined} Next tabbable element. 374 */ 375 function findNext(element) { 376 return filterTabbable(find(element.ownerDocument.body)).find(focusable => 377 // eslint-disable-next-line no-bitwise 378 element.compareDocumentPosition(focusable) & element.DOCUMENT_POSITION_FOLLOWING); 379 } 380 381 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/utils/assert-is-defined.js 382 function assertIsDefined(val, name) { 383 if (false) {} 384 } 385 386 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/get-rectangle-from-range.js 387 /** 388 * Internal dependencies 389 */ 390 391 392 /** 393 * Get the rectangle of a given Range. Returns `null` if no suitable rectangle 394 * can be found. 395 * 396 * @param {Range} range The range. 397 * 398 * @return {DOMRect?} The rectangle. 399 */ 400 function getRectangleFromRange(range) { 401 // For uncollapsed ranges, get the rectangle that bounds the contents of the 402 // range; this a rectangle enclosing the union of the bounding rectangles 403 // for all the elements in the range. 404 if (!range.collapsed) { 405 const rects = Array.from(range.getClientRects()); 406 407 // If there's just a single rect, return it. 408 if (rects.length === 1) { 409 return rects[0]; 410 } 411 412 // Ignore tiny selection at the edge of a range. 413 const filteredRects = rects.filter(({ 414 width 415 }) => width > 1); 416 417 // If it's full of tiny selections, return browser default. 418 if (filteredRects.length === 0) { 419 return range.getBoundingClientRect(); 420 } 421 if (filteredRects.length === 1) { 422 return filteredRects[0]; 423 } 424 let { 425 top: furthestTop, 426 bottom: furthestBottom, 427 left: furthestLeft, 428 right: furthestRight 429 } = filteredRects[0]; 430 for (const { 431 top, 432 bottom, 433 left, 434 right 435 } of filteredRects) { 436 if (top < furthestTop) { 437 furthestTop = top; 438 } 439 if (bottom > furthestBottom) { 440 furthestBottom = bottom; 441 } 442 if (left < furthestLeft) { 443 furthestLeft = left; 444 } 445 if (right > furthestRight) { 446 furthestRight = right; 447 } 448 } 449 return new window.DOMRect(furthestLeft, furthestTop, furthestRight - furthestLeft, furthestBottom - furthestTop); 450 } 451 const { 452 startContainer 453 } = range; 454 const { 455 ownerDocument 456 } = startContainer; 457 458 // Correct invalid "BR" ranges. The cannot contain any children. 459 if (startContainer.nodeName === 'BR') { 460 const { 461 parentNode 462 } = startContainer; 463 assertIsDefined(parentNode, 'parentNode'); 464 const index = /** @type {Node[]} */Array.from(parentNode.childNodes).indexOf(startContainer); 465 assertIsDefined(ownerDocument, 'ownerDocument'); 466 range = ownerDocument.createRange(); 467 range.setStart(parentNode, index); 468 range.setEnd(parentNode, index); 469 } 470 const rects = range.getClientRects(); 471 472 // If we have multiple rectangles for a collapsed range, there's no way to 473 // know which it is, so don't return anything. 474 if (rects.length > 1) { 475 return null; 476 } 477 let rect = rects[0]; 478 479 // If the collapsed range starts (and therefore ends) at an element node, 480 // `getClientRects` can be empty in some browsers. This can be resolved 481 // by adding a temporary text node with zero-width space to the range. 482 // 483 // See: https://stackoverflow.com/a/6847328/995445 484 if (!rect || rect.height === 0) { 485 assertIsDefined(ownerDocument, 'ownerDocument'); 486 const padNode = ownerDocument.createTextNode('\u200b'); 487 // Do not modify the live range. 488 range = range.cloneRange(); 489 range.insertNode(padNode); 490 rect = range.getClientRects()[0]; 491 assertIsDefined(padNode.parentNode, 'padNode.parentNode'); 492 padNode.parentNode.removeChild(padNode); 493 } 494 return rect; 495 } 496 497 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/compute-caret-rect.js 498 /** 499 * Internal dependencies 500 */ 501 502 503 504 /** 505 * Get the rectangle for the selection in a container. 506 * 507 * @param {Window} win The window of the selection. 508 * 509 * @return {DOMRect | null} The rectangle. 510 */ 511 function computeCaretRect(win) { 512 const selection = win.getSelection(); 513 assertIsDefined(selection, 'selection'); 514 const range = selection.rangeCount ? selection.getRangeAt(0) : null; 515 if (!range) { 516 return null; 517 } 518 return getRectangleFromRange(range); 519 } 520 521 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/document-has-text-selection.js 522 /** 523 * Internal dependencies 524 */ 525 526 527 /** 528 * Check whether the current document has selected text. This applies to ranges 529 * of text in the document, and not selection inside `<input>` and `<textarea>` 530 * elements. 531 * 532 * See: https://developer.mozilla.org/en-US/docs/Web/API/Window/getSelection#Related_objects. 533 * 534 * @param {Document} doc The document to check. 535 * 536 * @return {boolean} True if there is selection, false if not. 537 */ 538 function documentHasTextSelection(doc) { 539 assertIsDefined(doc.defaultView, 'doc.defaultView'); 540 const selection = doc.defaultView.getSelection(); 541 assertIsDefined(selection, 'selection'); 542 const range = selection.rangeCount ? selection.getRangeAt(0) : null; 543 return !!range && !range.collapsed; 544 } 545 546 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/is-html-input-element.js 547 /* eslint-disable jsdoc/valid-types */ 548 /** 549 * @param {Node} node 550 * @return {node is HTMLInputElement} Whether the node is an HTMLInputElement. 551 */ 552 function isHTMLInputElement(node) { 553 /* eslint-enable jsdoc/valid-types */ 554 return node?.nodeName === 'INPUT'; 555 } 556 557 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/is-text-field.js 558 /** 559 * Internal dependencies 560 */ 561 562 563 /* eslint-disable jsdoc/valid-types */ 564 /** 565 * Check whether the given element is a text field, where text field is defined 566 * by the ability to select within the input, or that it is contenteditable. 567 * 568 * See: https://html.spec.whatwg.org/#textFieldSelection 569 * 570 * @param {Node} node The HTML element. 571 * @return {node is HTMLElement} True if the element is an text field, false if not. 572 */ 573 function isTextField(node) { 574 /* eslint-enable jsdoc/valid-types */ 575 const nonTextInputs = ['button', 'checkbox', 'hidden', 'file', 'radio', 'image', 'range', 'reset', 'submit', 'number', 'email', 'time']; 576 return isHTMLInputElement(node) && node.type && !nonTextInputs.includes(node.type) || node.nodeName === 'TEXTAREA' || /** @type {HTMLElement} */node.contentEditable === 'true'; 577 } 578 579 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/input-field-has-uncollapsed-selection.js 580 /** 581 * Internal dependencies 582 */ 583 584 585 586 /** 587 * Check whether the given input field or textarea contains a (uncollapsed) 588 * selection of text. 589 * 590 * CAVEAT: Only specific text-based HTML inputs support the selection APIs 591 * needed to determine whether they have a collapsed or uncollapsed selection. 592 * This function defaults to returning `true` when the selection cannot be 593 * inspected, such as with `<input type="time">`. The rationale is that this 594 * should cause the block editor to defer to the browser's native selection 595 * handling (e.g. copying and pasting), thereby reducing friction for the user. 596 * 597 * See: https://html.spec.whatwg.org/multipage/input.html#do-not-apply 598 * 599 * @param {Element} element The HTML element. 600 * 601 * @return {boolean} Whether the input/textareaa element has some "selection". 602 */ 603 function inputFieldHasUncollapsedSelection(element) { 604 if (!isHTMLInputElement(element) && !isTextField(element)) { 605 return false; 606 } 607 608 // Safari throws a type error when trying to get `selectionStart` and 609 // `selectionEnd` on non-text <input> elements, so a try/catch construct is 610 // necessary. 611 try { 612 const { 613 selectionStart, 614 selectionEnd 615 } = /** @type {HTMLInputElement | HTMLTextAreaElement} */element; 616 return ( 617 // `null` means the input type doesn't implement selection, thus we 618 // cannot determine whether the selection is collapsed, so we 619 // default to true. 620 selectionStart === null || 621 // when not null, compare the two points 622 selectionStart !== selectionEnd 623 ); 624 } catch (error) { 625 // This is Safari's way of saying that the input type doesn't implement 626 // selection, so we default to true. 627 return true; 628 } 629 } 630 631 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/document-has-uncollapsed-selection.js 632 /** 633 * Internal dependencies 634 */ 635 636 637 638 /** 639 * Check whether the current document has any sort of (uncollapsed) selection. 640 * This includes ranges of text across elements and any selection inside 641 * textual `<input>` and `<textarea>` elements. 642 * 643 * @param {Document} doc The document to check. 644 * 645 * @return {boolean} Whether there is any recognizable text selection in the document. 646 */ 647 function documentHasUncollapsedSelection(doc) { 648 return documentHasTextSelection(doc) || !!doc.activeElement && inputFieldHasUncollapsedSelection(doc.activeElement); 649 } 650 651 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/document-has-selection.js 652 /** 653 * Internal dependencies 654 */ 655 656 657 658 659 /** 660 * Check whether the current document has a selection. This includes focus in 661 * input fields, textareas, and general rich-text selection. 662 * 663 * @param {Document} doc The document to check. 664 * 665 * @return {boolean} True if there is selection, false if not. 666 */ 667 function documentHasSelection(doc) { 668 return !!doc.activeElement && (isHTMLInputElement(doc.activeElement) || isTextField(doc.activeElement) || documentHasTextSelection(doc)); 669 } 670 671 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/get-computed-style.js 672 /** 673 * Internal dependencies 674 */ 675 676 677 /* eslint-disable jsdoc/valid-types */ 678 /** 679 * @param {Element} element 680 * @return {ReturnType<Window['getComputedStyle']>} The computed style for the element. 681 */ 682 function getComputedStyle(element) { 683 /* eslint-enable jsdoc/valid-types */ 684 assertIsDefined(element.ownerDocument.defaultView, 'element.ownerDocument.defaultView'); 685 return element.ownerDocument.defaultView.getComputedStyle(element); 686 } 687 688 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/get-scroll-container.js 689 /** 690 * Internal dependencies 691 */ 692 693 694 /** 695 * Given a DOM node, finds the closest scrollable container node or the node 696 * itself, if scrollable. 697 * 698 * @param {Element | null} node Node from which to start. 699 * @param {?string} direction Direction of scrollable container to search for ('vertical', 'horizontal', 'all'). 700 * Defaults to 'vertical'. 701 * @return {Element | undefined} Scrollable container node, if found. 702 */ 703 function getScrollContainer(node, direction = 'vertical') { 704 if (!node) { 705 return undefined; 706 } 707 if (direction === 'vertical' || direction === 'all') { 708 // Scrollable if scrollable height exceeds displayed... 709 if (node.scrollHeight > node.clientHeight) { 710 // ...except when overflow is defined to be hidden or visible 711 const { 712 overflowY 713 } = getComputedStyle(node); 714 if (/(auto|scroll)/.test(overflowY)) { 715 return node; 716 } 717 } 718 } 719 if (direction === 'horizontal' || direction === 'all') { 720 // Scrollable if scrollable width exceeds displayed... 721 if (node.scrollWidth > node.clientWidth) { 722 // ...except when overflow is defined to be hidden or visible 723 const { 724 overflowX 725 } = getComputedStyle(node); 726 if (/(auto|scroll)/.test(overflowX)) { 727 return node; 728 } 729 } 730 } 731 if (node.ownerDocument === node.parentNode) { 732 return node; 733 } 734 735 // Continue traversing. 736 return getScrollContainer( /** @type {Element} */node.parentNode, direction); 737 } 738 739 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/get-offset-parent.js 740 /** 741 * Internal dependencies 742 */ 743 744 745 /** 746 * Returns the closest positioned element, or null under any of the conditions 747 * of the offsetParent specification. Unlike offsetParent, this function is not 748 * limited to HTMLElement and accepts any Node (e.g. Node.TEXT_NODE). 749 * 750 * @see https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetparent 751 * 752 * @param {Node} node Node from which to find offset parent. 753 * 754 * @return {Node | null} Offset parent. 755 */ 756 function getOffsetParent(node) { 757 // Cannot retrieve computed style or offset parent only anything other than 758 // an element node, so find the closest element node. 759 let closestElement; 760 while (closestElement = /** @type {Node} */node.parentNode) { 761 if (closestElement.nodeType === closestElement.ELEMENT_NODE) { 762 break; 763 } 764 } 765 if (!closestElement) { 766 return null; 767 } 768 769 // If the closest element is already positioned, return it, as offsetParent 770 // does not otherwise consider the node itself. 771 if (getComputedStyle( /** @type {Element} */closestElement).position !== 'static') { 772 return closestElement; 773 } 774 775 // offsetParent is undocumented/draft. 776 return /** @type {Node & { offsetParent: Node }} */closestElement.offsetParent; 777 } 778 779 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/is-input-or-text-area.js 780 /* eslint-disable jsdoc/valid-types */ 781 /** 782 * @param {Element} element 783 * @return {element is HTMLInputElement | HTMLTextAreaElement} Whether the element is an input or textarea 784 */ 785 function isInputOrTextArea(element) { 786 /* eslint-enable jsdoc/valid-types */ 787 return element.tagName === 'INPUT' || element.tagName === 'TEXTAREA'; 788 } 789 790 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/is-entirely-selected.js 791 /** 792 * Internal dependencies 793 */ 794 795 796 797 /** 798 * Check whether the contents of the element have been entirely selected. 799 * Returns true if there is no possibility of selection. 800 * 801 * @param {HTMLElement} element The element to check. 802 * 803 * @return {boolean} True if entirely selected, false if not. 804 */ 805 function isEntirelySelected(element) { 806 if (isInputOrTextArea(element)) { 807 return element.selectionStart === 0 && element.value.length === element.selectionEnd; 808 } 809 if (!element.isContentEditable) { 810 return true; 811 } 812 const { 813 ownerDocument 814 } = element; 815 const { 816 defaultView 817 } = ownerDocument; 818 assertIsDefined(defaultView, 'defaultView'); 819 const selection = defaultView.getSelection(); 820 assertIsDefined(selection, 'selection'); 821 const range = selection.rangeCount ? selection.getRangeAt(0) : null; 822 if (!range) { 823 return true; 824 } 825 const { 826 startContainer, 827 endContainer, 828 startOffset, 829 endOffset 830 } = range; 831 if (startContainer === element && endContainer === element && startOffset === 0 && endOffset === element.childNodes.length) { 832 return true; 833 } 834 const lastChild = element.lastChild; 835 assertIsDefined(lastChild, 'lastChild'); 836 const endContainerContentLength = endContainer.nodeType === endContainer.TEXT_NODE ? /** @type {Text} */endContainer.data.length : endContainer.childNodes.length; 837 return isDeepChild(startContainer, element, 'firstChild') && isDeepChild(endContainer, element, 'lastChild') && startOffset === 0 && endOffset === endContainerContentLength; 838 } 839 840 /** 841 * Check whether the contents of the element have been entirely selected. 842 * Returns true if there is no possibility of selection. 843 * 844 * @param {HTMLElement|Node} query The element to check. 845 * @param {HTMLElement} container The container that we suspect "query" may be a first or last child of. 846 * @param {"firstChild"|"lastChild"} propName "firstChild" or "lastChild" 847 * 848 * @return {boolean} True if query is a deep first/last child of container, false otherwise. 849 */ 850 function isDeepChild(query, container, propName) { 851 /** @type {HTMLElement | ChildNode | null} */ 852 let candidate = container; 853 do { 854 if (query === candidate) { 855 return true; 856 } 857 candidate = candidate[propName]; 858 } while (candidate); 859 return false; 860 } 861 862 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/is-form-element.js 863 /** 864 * Internal dependencies 865 */ 866 867 868 /** 869 * 870 * Detects if element is a form element. 871 * 872 * @param {Element} element The element to check. 873 * 874 * @return {boolean} True if form element and false otherwise. 875 */ 876 function isFormElement(element) { 877 if (!element) { 878 return false; 879 } 880 const { 881 tagName 882 } = element; 883 const checkForInputTextarea = isInputOrTextArea(element); 884 return checkForInputTextarea || tagName === 'BUTTON' || tagName === 'SELECT'; 885 } 886 887 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/is-rtl.js 888 /** 889 * Internal dependencies 890 */ 891 892 893 /** 894 * Whether the element's text direction is right-to-left. 895 * 896 * @param {Element} element The element to check. 897 * 898 * @return {boolean} True if rtl, false if ltr. 899 */ 900 function isRTL(element) { 901 return getComputedStyle(element).direction === 'rtl'; 902 } 903 904 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/get-range-height.js 905 /** 906 * Gets the height of the range without ignoring zero width rectangles, which 907 * some browsers ignore when creating a union. 908 * 909 * @param {Range} range The range to check. 910 * @return {number | undefined} Height of the range or undefined if the range has no client rectangles. 911 */ 912 function getRangeHeight(range) { 913 const rects = Array.from(range.getClientRects()); 914 if (!rects.length) { 915 return; 916 } 917 const highestTop = Math.min(...rects.map(({ 918 top 919 }) => top)); 920 const lowestBottom = Math.max(...rects.map(({ 921 bottom 922 }) => bottom)); 923 return lowestBottom - highestTop; 924 } 925 926 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/is-selection-forward.js 927 /** 928 * Internal dependencies 929 */ 930 931 932 /** 933 * Returns true if the given selection object is in the forward direction, or 934 * false otherwise. 935 * 936 * @see https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition 937 * 938 * @param {Selection} selection Selection object to check. 939 * 940 * @return {boolean} Whether the selection is forward. 941 */ 942 function isSelectionForward(selection) { 943 const { 944 anchorNode, 945 focusNode, 946 anchorOffset, 947 focusOffset 948 } = selection; 949 assertIsDefined(anchorNode, 'anchorNode'); 950 assertIsDefined(focusNode, 'focusNode'); 951 const position = anchorNode.compareDocumentPosition(focusNode); 952 953 // Disable reason: `Node#compareDocumentPosition` returns a bitmask value, 954 // so bitwise operators are intended. 955 /* eslint-disable no-bitwise */ 956 // Compare whether anchor node precedes focus node. If focus node (where 957 // end of selection occurs) is after the anchor node, it is forward. 958 if (position & anchorNode.DOCUMENT_POSITION_PRECEDING) { 959 return false; 960 } 961 if (position & anchorNode.DOCUMENT_POSITION_FOLLOWING) { 962 return true; 963 } 964 /* eslint-enable no-bitwise */ 965 966 // `compareDocumentPosition` returns 0 when passed the same node, in which 967 // case compare offsets. 968 if (position === 0) { 969 return anchorOffset <= focusOffset; 970 } 971 972 // This should never be reached, but return true as default case. 973 return true; 974 } 975 976 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/caret-range-from-point.js 977 /** 978 * Polyfill. 979 * Get a collapsed range for a given point. 980 * 981 * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/caretRangeFromPoint 982 * 983 * @param {DocumentMaybeWithCaretPositionFromPoint} doc The document of the range. 984 * @param {number} x Horizontal position within the current viewport. 985 * @param {number} y Vertical position within the current viewport. 986 * 987 * @return {Range | null} The best range for the given point. 988 */ 989 function caretRangeFromPoint(doc, x, y) { 990 if (doc.caretRangeFromPoint) { 991 return doc.caretRangeFromPoint(x, y); 992 } 993 if (!doc.caretPositionFromPoint) { 994 return null; 995 } 996 const point = doc.caretPositionFromPoint(x, y); 997 998 // If x or y are negative, outside viewport, or there is no text entry node. 999 // https://developer.mozilla.org/en-US/docs/Web/API/Document/caretRangeFromPoint 1000 if (!point) { 1001 return null; 1002 } 1003 const range = doc.createRange(); 1004 range.setStart(point.offsetNode, point.offset); 1005 range.collapse(true); 1006 return range; 1007 } 1008 1009 /** 1010 * @typedef {{caretPositionFromPoint?: (x: number, y: number)=> CaretPosition | null} & Document } DocumentMaybeWithCaretPositionFromPoint 1011 * @typedef {{ readonly offset: number; readonly offsetNode: Node; getClientRect(): DOMRect | null; }} CaretPosition 1012 */ 1013 1014 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/hidden-caret-range-from-point.js 1015 /** 1016 * Internal dependencies 1017 */ 1018 1019 1020 1021 /** 1022 * Get a collapsed range for a given point. 1023 * Gives the container a temporary high z-index (above any UI). 1024 * This is preferred over getting the UI nodes and set styles there. 1025 * 1026 * @param {Document} doc The document of the range. 1027 * @param {number} x Horizontal position within the current viewport. 1028 * @param {number} y Vertical position within the current viewport. 1029 * @param {HTMLElement} container Container in which the range is expected to be found. 1030 * 1031 * @return {?Range} The best range for the given point. 1032 */ 1033 function hiddenCaretRangeFromPoint(doc, x, y, container) { 1034 const originalZIndex = container.style.zIndex; 1035 const originalPosition = container.style.position; 1036 const { 1037 position = 'static' 1038 } = getComputedStyle(container); 1039 1040 // A z-index only works if the element position is not static. 1041 if (position === 'static') { 1042 container.style.position = 'relative'; 1043 } 1044 container.style.zIndex = '10000'; 1045 const range = caretRangeFromPoint(doc, x, y); 1046 container.style.zIndex = originalZIndex; 1047 container.style.position = originalPosition; 1048 return range; 1049 } 1050 1051 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/scroll-if-no-range.js 1052 /** 1053 * If no range range can be created or it is outside the container, the element 1054 * may be out of view, so scroll it into view and try again. 1055 * 1056 * @param {HTMLElement} container The container to scroll. 1057 * @param {boolean} alignToTop True to align to top, false to bottom. 1058 * @param {Function} callback The callback to create the range. 1059 * 1060 * @return {?Range} The range returned by the callback. 1061 */ 1062 function scrollIfNoRange(container, alignToTop, callback) { 1063 let range = callback(); 1064 1065 // If no range range can be created or it is outside the container, the 1066 // element may be out of view. 1067 if (!range || !range.startContainer || !container.contains(range.startContainer)) { 1068 container.scrollIntoView(alignToTop); 1069 range = callback(); 1070 if (!range || !range.startContainer || !container.contains(range.startContainer)) { 1071 return null; 1072 } 1073 } 1074 return range; 1075 } 1076 1077 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/is-edge.js 1078 /** 1079 * Internal dependencies 1080 */ 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 /** 1091 * Check whether the selection is at the edge of the container. Checks for 1092 * horizontal position by default. Set `onlyVertical` to true to check only 1093 * vertically. 1094 * 1095 * @param {HTMLElement} container Focusable element. 1096 * @param {boolean} isReverse Set to true to check left, false to check right. 1097 * @param {boolean} [onlyVertical=false] Set to true to check only vertical position. 1098 * 1099 * @return {boolean} True if at the edge, false if not. 1100 */ 1101 function isEdge(container, isReverse, onlyVertical = false) { 1102 if (isInputOrTextArea(container) && typeof container.selectionStart === 'number') { 1103 if (container.selectionStart !== container.selectionEnd) { 1104 return false; 1105 } 1106 if (isReverse) { 1107 return container.selectionStart === 0; 1108 } 1109 return container.value.length === container.selectionStart; 1110 } 1111 if (!container.isContentEditable) { 1112 return true; 1113 } 1114 const { 1115 ownerDocument 1116 } = container; 1117 const { 1118 defaultView 1119 } = ownerDocument; 1120 assertIsDefined(defaultView, 'defaultView'); 1121 const selection = defaultView.getSelection(); 1122 if (!selection || !selection.rangeCount) { 1123 return false; 1124 } 1125 const range = selection.getRangeAt(0); 1126 const collapsedRange = range.cloneRange(); 1127 const isForward = isSelectionForward(selection); 1128 const isCollapsed = selection.isCollapsed; 1129 1130 // Collapse in direction of selection. 1131 if (!isCollapsed) { 1132 collapsedRange.collapse(!isForward); 1133 } 1134 const collapsedRangeRect = getRectangleFromRange(collapsedRange); 1135 const rangeRect = getRectangleFromRange(range); 1136 if (!collapsedRangeRect || !rangeRect) { 1137 return false; 1138 } 1139 1140 // Only consider the multiline selection at the edge if the direction is 1141 // towards the edge. The selection is multiline if it is taller than the 1142 // collapsed selection. 1143 const rangeHeight = getRangeHeight(range); 1144 if (!isCollapsed && rangeHeight && rangeHeight > collapsedRangeRect.height && isForward === isReverse) { 1145 return false; 1146 } 1147 1148 // In the case of RTL scripts, the horizontal edge is at the opposite side. 1149 const isReverseDir = isRTL(container) ? !isReverse : isReverse; 1150 const containerRect = container.getBoundingClientRect(); 1151 1152 // To check if a selection is at the edge, we insert a test selection at the 1153 // edge of the container and check if the selections have the same vertical 1154 // or horizontal position. If they do, the selection is at the edge. 1155 // This method proves to be better than a DOM-based calculation for the 1156 // horizontal edge, since it ignores empty textnodes and a trailing line 1157 // break element. In other words, we need to check visual positioning, not 1158 // DOM positioning. 1159 // It also proves better than using the computed style for the vertical 1160 // edge, because we cannot know the padding and line height reliably in 1161 // pixels. `getComputedStyle` may return a value with different units. 1162 const x = isReverseDir ? containerRect.left + 1 : containerRect.right - 1; 1163 const y = isReverse ? containerRect.top + 1 : containerRect.bottom - 1; 1164 const testRange = scrollIfNoRange(container, isReverse, () => hiddenCaretRangeFromPoint(ownerDocument, x, y, container)); 1165 if (!testRange) { 1166 return false; 1167 } 1168 const testRect = getRectangleFromRange(testRange); 1169 if (!testRect) { 1170 return false; 1171 } 1172 const verticalSide = isReverse ? 'top' : 'bottom'; 1173 const horizontalSide = isReverseDir ? 'left' : 'right'; 1174 const verticalDiff = testRect[verticalSide] - rangeRect[verticalSide]; 1175 const horizontalDiff = testRect[horizontalSide] - collapsedRangeRect[horizontalSide]; 1176 1177 // Allow the position to be 1px off. 1178 const hasVerticalDiff = Math.abs(verticalDiff) <= 1; 1179 const hasHorizontalDiff = Math.abs(horizontalDiff) <= 1; 1180 return onlyVertical ? hasVerticalDiff : hasVerticalDiff && hasHorizontalDiff; 1181 } 1182 1183 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/is-horizontal-edge.js 1184 /** 1185 * Internal dependencies 1186 */ 1187 1188 1189 /** 1190 * Check whether the selection is horizontally at the edge of the container. 1191 * 1192 * @param {HTMLElement} container Focusable element. 1193 * @param {boolean} isReverse Set to true to check left, false for right. 1194 * 1195 * @return {boolean} True if at the horizontal edge, false if not. 1196 */ 1197 function isHorizontalEdge(container, isReverse) { 1198 return isEdge(container, isReverse); 1199 } 1200 1201 ;// CONCATENATED MODULE: external ["wp","deprecated"] 1202 const external_wp_deprecated_namespaceObject = window["wp"]["deprecated"]; 1203 var external_wp_deprecated_default = /*#__PURE__*/__webpack_require__.n(external_wp_deprecated_namespaceObject); 1204 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/is-number-input.js 1205 /** 1206 * WordPress dependencies 1207 */ 1208 1209 1210 /** 1211 * Internal dependencies 1212 */ 1213 1214 1215 /* eslint-disable jsdoc/valid-types */ 1216 /** 1217 * Check whether the given element is an input field of type number. 1218 * 1219 * @param {Node} node The HTML node. 1220 * 1221 * @return {node is HTMLInputElement} True if the node is number input. 1222 */ 1223 function isNumberInput(node) { 1224 external_wp_deprecated_default()('wp.dom.isNumberInput', { 1225 since: '6.1', 1226 version: '6.5' 1227 }); 1228 /* eslint-enable jsdoc/valid-types */ 1229 return isHTMLInputElement(node) && node.type === 'number' && !isNaN(node.valueAsNumber); 1230 } 1231 1232 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/is-vertical-edge.js 1233 /** 1234 * Internal dependencies 1235 */ 1236 1237 1238 /** 1239 * Check whether the selection is vertically at the edge of the container. 1240 * 1241 * @param {HTMLElement} container Focusable element. 1242 * @param {boolean} isReverse Set to true to check top, false for bottom. 1243 * 1244 * @return {boolean} True if at the vertical edge, false if not. 1245 */ 1246 function isVerticalEdge(container, isReverse) { 1247 return isEdge(container, isReverse, true); 1248 } 1249 1250 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/place-caret-at-edge.js 1251 /** 1252 * Internal dependencies 1253 */ 1254 1255 1256 1257 1258 1259 1260 /** 1261 * Gets the range to place. 1262 * 1263 * @param {HTMLElement} container Focusable element. 1264 * @param {boolean} isReverse True for end, false for start. 1265 * @param {number|undefined} x X coordinate to vertically position. 1266 * 1267 * @return {Range|null} The range to place. 1268 */ 1269 function getRange(container, isReverse, x) { 1270 const { 1271 ownerDocument 1272 } = container; 1273 // In the case of RTL scripts, the horizontal edge is at the opposite side. 1274 const isReverseDir = isRTL(container) ? !isReverse : isReverse; 1275 const containerRect = container.getBoundingClientRect(); 1276 // When placing at the end (isReverse), find the closest range to the bottom 1277 // right corner. When placing at the start, to the top left corner. 1278 // Ensure x is defined and within the container's boundaries. When it's 1279 // exactly at the boundary, it's not considered within the boundaries. 1280 if (x === undefined) { 1281 x = isReverse ? containerRect.right - 1 : containerRect.left + 1; 1282 } else if (x <= containerRect.left) { 1283 x = containerRect.left + 1; 1284 } else if (x >= containerRect.right) { 1285 x = containerRect.right - 1; 1286 } 1287 const y = isReverseDir ? containerRect.bottom - 1 : containerRect.top + 1; 1288 return hiddenCaretRangeFromPoint(ownerDocument, x, y, container); 1289 } 1290 1291 /** 1292 * Places the caret at start or end of a given element. 1293 * 1294 * @param {HTMLElement} container Focusable element. 1295 * @param {boolean} isReverse True for end, false for start. 1296 * @param {number|undefined} x X coordinate to vertically position. 1297 */ 1298 function placeCaretAtEdge(container, isReverse, x) { 1299 if (!container) { 1300 return; 1301 } 1302 container.focus(); 1303 if (isInputOrTextArea(container)) { 1304 // The element may not support selection setting. 1305 if (typeof container.selectionStart !== 'number') { 1306 return; 1307 } 1308 if (isReverse) { 1309 container.selectionStart = container.value.length; 1310 container.selectionEnd = container.value.length; 1311 } else { 1312 container.selectionStart = 0; 1313 container.selectionEnd = 0; 1314 } 1315 return; 1316 } 1317 if (!container.isContentEditable) { 1318 return; 1319 } 1320 const range = scrollIfNoRange(container, isReverse, () => getRange(container, isReverse, x)); 1321 if (!range) { 1322 return; 1323 } 1324 const { 1325 ownerDocument 1326 } = container; 1327 const { 1328 defaultView 1329 } = ownerDocument; 1330 assertIsDefined(defaultView, 'defaultView'); 1331 const selection = defaultView.getSelection(); 1332 assertIsDefined(selection, 'selection'); 1333 selection.removeAllRanges(); 1334 selection.addRange(range); 1335 } 1336 1337 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/place-caret-at-horizontal-edge.js 1338 /** 1339 * Internal dependencies 1340 */ 1341 1342 1343 /** 1344 * Places the caret at start or end of a given element. 1345 * 1346 * @param {HTMLElement} container Focusable element. 1347 * @param {boolean} isReverse True for end, false for start. 1348 */ 1349 function placeCaretAtHorizontalEdge(container, isReverse) { 1350 return placeCaretAtEdge(container, isReverse, undefined); 1351 } 1352 1353 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/place-caret-at-vertical-edge.js 1354 /** 1355 * Internal dependencies 1356 */ 1357 1358 1359 /** 1360 * Places the caret at the top or bottom of a given element. 1361 * 1362 * @param {HTMLElement} container Focusable element. 1363 * @param {boolean} isReverse True for bottom, false for top. 1364 * @param {DOMRect} [rect] The rectangle to position the caret with. 1365 */ 1366 function placeCaretAtVerticalEdge(container, isReverse, rect) { 1367 return placeCaretAtEdge(container, isReverse, rect?.left); 1368 } 1369 1370 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/insert-after.js 1371 /** 1372 * Internal dependencies 1373 */ 1374 1375 1376 /** 1377 * Given two DOM nodes, inserts the former in the DOM as the next sibling of 1378 * the latter. 1379 * 1380 * @param {Node} newNode Node to be inserted. 1381 * @param {Node} referenceNode Node after which to perform the insertion. 1382 * @return {void} 1383 */ 1384 function insertAfter(newNode, referenceNode) { 1385 assertIsDefined(referenceNode.parentNode, 'referenceNode.parentNode'); 1386 referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling); 1387 } 1388 1389 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/remove.js 1390 /** 1391 * Internal dependencies 1392 */ 1393 1394 1395 /** 1396 * Given a DOM node, removes it from the DOM. 1397 * 1398 * @param {Node} node Node to be removed. 1399 * @return {void} 1400 */ 1401 function remove(node) { 1402 assertIsDefined(node.parentNode, 'node.parentNode'); 1403 node.parentNode.removeChild(node); 1404 } 1405 1406 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/replace.js 1407 /** 1408 * Internal dependencies 1409 */ 1410 1411 1412 1413 1414 /** 1415 * Given two DOM nodes, replaces the former with the latter in the DOM. 1416 * 1417 * @param {Element} processedNode Node to be removed. 1418 * @param {Element} newNode Node to be inserted in its place. 1419 * @return {void} 1420 */ 1421 function replace(processedNode, newNode) { 1422 assertIsDefined(processedNode.parentNode, 'processedNode.parentNode'); 1423 insertAfter(newNode, processedNode.parentNode); 1424 remove(processedNode); 1425 } 1426 1427 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/unwrap.js 1428 /** 1429 * Internal dependencies 1430 */ 1431 1432 1433 /** 1434 * Unwrap the given node. This means any child nodes are moved to the parent. 1435 * 1436 * @param {Node} node The node to unwrap. 1437 * 1438 * @return {void} 1439 */ 1440 function unwrap(node) { 1441 const parent = node.parentNode; 1442 assertIsDefined(parent, 'node.parentNode'); 1443 while (node.firstChild) { 1444 parent.insertBefore(node.firstChild, node); 1445 } 1446 parent.removeChild(node); 1447 } 1448 1449 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/replace-tag.js 1450 /** 1451 * Internal dependencies 1452 */ 1453 1454 1455 /** 1456 * Replaces the given node with a new node with the given tag name. 1457 * 1458 * @param {Element} node The node to replace 1459 * @param {string} tagName The new tag name. 1460 * 1461 * @return {Element} The new node. 1462 */ 1463 function replaceTag(node, tagName) { 1464 const newNode = node.ownerDocument.createElement(tagName); 1465 while (node.firstChild) { 1466 newNode.appendChild(node.firstChild); 1467 } 1468 assertIsDefined(node.parentNode, 'node.parentNode'); 1469 node.parentNode.replaceChild(newNode, node); 1470 return newNode; 1471 } 1472 1473 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/wrap.js 1474 /** 1475 * Internal dependencies 1476 */ 1477 1478 1479 /** 1480 * Wraps the given node with a new node with the given tag name. 1481 * 1482 * @param {Element} newNode The node to insert. 1483 * @param {Element} referenceNode The node to wrap. 1484 */ 1485 function wrap(newNode, referenceNode) { 1486 assertIsDefined(referenceNode.parentNode, 'referenceNode.parentNode'); 1487 referenceNode.parentNode.insertBefore(newNode, referenceNode); 1488 newNode.appendChild(referenceNode); 1489 } 1490 1491 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/safe-html.js 1492 /** 1493 * Internal dependencies 1494 */ 1495 1496 1497 /** 1498 * Strips scripts and on* attributes from HTML. 1499 * 1500 * @param {string} html HTML to sanitize. 1501 * 1502 * @return {string} The sanitized HTML. 1503 */ 1504 function safeHTML(html) { 1505 const { 1506 body 1507 } = document.implementation.createHTMLDocument(''); 1508 body.innerHTML = html; 1509 const elements = body.getElementsByTagName('*'); 1510 let elementIndex = elements.length; 1511 while (elementIndex--) { 1512 const element = elements[elementIndex]; 1513 if (element.tagName === 'SCRIPT') { 1514 remove(element); 1515 } else { 1516 let attributeIndex = element.attributes.length; 1517 while (attributeIndex--) { 1518 const { 1519 name: key 1520 } = element.attributes[attributeIndex]; 1521 if (key.startsWith('on')) { 1522 element.removeAttribute(key); 1523 } 1524 } 1525 } 1526 } 1527 return body.innerHTML; 1528 } 1529 1530 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/strip-html.js 1531 /** 1532 * Internal dependencies 1533 */ 1534 1535 1536 /** 1537 * Removes any HTML tags from the provided string. 1538 * 1539 * @param {string} html The string containing html. 1540 * 1541 * @return {string} The text content with any html removed. 1542 */ 1543 function stripHTML(html) { 1544 // Remove any script tags or on* attributes otherwise their *contents* will be left 1545 // in place following removal of HTML tags. 1546 html = safeHTML(html); 1547 const doc = document.implementation.createHTMLDocument(''); 1548 doc.body.innerHTML = html; 1549 return doc.body.textContent || ''; 1550 } 1551 1552 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/is-empty.js 1553 /** 1554 * Recursively checks if an element is empty. An element is not empty if it 1555 * contains text or contains elements with attributes such as images. 1556 * 1557 * @param {Element} element The element to check. 1558 * 1559 * @return {boolean} Whether or not the element is empty. 1560 */ 1561 function isEmpty(element) { 1562 switch (element.nodeType) { 1563 case element.TEXT_NODE: 1564 // We cannot use \s since it includes special spaces which we want 1565 // to preserve. 1566 return /^[ \f\n\r\t\v\u00a0]*$/.test(element.nodeValue || ''); 1567 case element.ELEMENT_NODE: 1568 if (element.hasAttributes()) { 1569 return false; 1570 } else if (!element.hasChildNodes()) { 1571 return true; 1572 } 1573 return /** @type {Element[]} */Array.from(element.childNodes).every(isEmpty); 1574 default: 1575 return true; 1576 } 1577 } 1578 1579 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/phrasing-content.js 1580 /** 1581 * All phrasing content elements. 1582 * 1583 * @see https://www.w3.org/TR/2011/WD-html5-20110525/content-models.html#phrasing-content-0 1584 */ 1585 1586 /** 1587 * @typedef {Record<string,SemanticElementDefinition>} ContentSchema 1588 */ 1589 1590 /** 1591 * @typedef SemanticElementDefinition 1592 * @property {string[]} [attributes] Content attributes 1593 * @property {ContentSchema} [children] Content attributes 1594 */ 1595 1596 /** 1597 * All text-level semantic elements. 1598 * 1599 * @see https://html.spec.whatwg.org/multipage/text-level-semantics.html 1600 * 1601 * @type {ContentSchema} 1602 */ 1603 const textContentSchema = { 1604 strong: {}, 1605 em: {}, 1606 s: {}, 1607 del: {}, 1608 ins: {}, 1609 a: { 1610 attributes: ['href', 'target', 'rel', 'id'] 1611 }, 1612 code: {}, 1613 abbr: { 1614 attributes: ['title'] 1615 }, 1616 sub: {}, 1617 sup: {}, 1618 br: {}, 1619 small: {}, 1620 // To do: fix blockquote. 1621 // cite: {}, 1622 q: { 1623 attributes: ['cite'] 1624 }, 1625 dfn: { 1626 attributes: ['title'] 1627 }, 1628 data: { 1629 attributes: ['value'] 1630 }, 1631 time: { 1632 attributes: ['datetime'] 1633 }, 1634 var: {}, 1635 samp: {}, 1636 kbd: {}, 1637 i: {}, 1638 b: {}, 1639 u: {}, 1640 mark: {}, 1641 ruby: {}, 1642 rt: {}, 1643 rp: {}, 1644 bdi: { 1645 attributes: ['dir'] 1646 }, 1647 bdo: { 1648 attributes: ['dir'] 1649 }, 1650 wbr: {}, 1651 '#text': {} 1652 }; 1653 1654 // Recursion is needed. 1655 // Possible: strong > em > strong. 1656 // Impossible: strong > strong. 1657 const excludedElements = ['#text', 'br']; 1658 Object.keys(textContentSchema).filter(element => !excludedElements.includes(element)).forEach(tag => { 1659 const { 1660 [tag]: removedTag, 1661 ...restSchema 1662 } = textContentSchema; 1663 textContentSchema[tag].children = restSchema; 1664 }); 1665 1666 /** 1667 * Embedded content elements. 1668 * 1669 * @see https://www.w3.org/TR/2011/WD-html5-20110525/content-models.html#embedded-content-0 1670 * 1671 * @type {ContentSchema} 1672 */ 1673 const embeddedContentSchema = { 1674 audio: { 1675 attributes: ['src', 'preload', 'autoplay', 'mediagroup', 'loop', 'muted'] 1676 }, 1677 canvas: { 1678 attributes: ['width', 'height'] 1679 }, 1680 embed: { 1681 attributes: ['src', 'type', 'width', 'height'] 1682 }, 1683 img: { 1684 attributes: ['alt', 'src', 'srcset', 'usemap', 'ismap', 'width', 'height'] 1685 }, 1686 object: { 1687 attributes: ['data', 'type', 'name', 'usemap', 'form', 'width', 'height'] 1688 }, 1689 video: { 1690 attributes: ['src', 'poster', 'preload', 'playsinline', 'autoplay', 'mediagroup', 'loop', 'muted', 'controls', 'width', 'height'] 1691 } 1692 }; 1693 1694 /** 1695 * Phrasing content elements. 1696 * 1697 * @see https://www.w3.org/TR/2011/WD-html5-20110525/content-models.html#phrasing-content-0 1698 */ 1699 const phrasingContentSchema = { 1700 ...textContentSchema, 1701 ...embeddedContentSchema 1702 }; 1703 1704 /** 1705 * Get schema of possible paths for phrasing content. 1706 * 1707 * @see https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_categories#Phrasing_content 1708 * 1709 * @param {string} [context] Set to "paste" to exclude invisible elements and 1710 * sensitive data. 1711 * 1712 * @return {Partial<ContentSchema>} Schema. 1713 */ 1714 function getPhrasingContentSchema(context) { 1715 if (context !== 'paste') { 1716 return phrasingContentSchema; 1717 } 1718 1719 /** 1720 * @type {Partial<ContentSchema>} 1721 */ 1722 const { 1723 u, 1724 // Used to mark misspelling. Shouldn't be pasted. 1725 abbr, 1726 // Invisible. 1727 data, 1728 // Invisible. 1729 time, 1730 // Invisible. 1731 wbr, 1732 // Invisible. 1733 bdi, 1734 // Invisible. 1735 bdo, 1736 // Invisible. 1737 ...remainingContentSchema 1738 } = { 1739 ...phrasingContentSchema, 1740 // We shouldn't paste potentially sensitive information which is not 1741 // visible to the user when pasted, so strip the attributes. 1742 ins: { 1743 children: phrasingContentSchema.ins.children 1744 }, 1745 del: { 1746 children: phrasingContentSchema.del.children 1747 } 1748 }; 1749 return remainingContentSchema; 1750 } 1751 1752 /** 1753 * Find out whether or not the given node is phrasing content. 1754 * 1755 * @see https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_categories#Phrasing_content 1756 * 1757 * @param {Node} node The node to test. 1758 * 1759 * @return {boolean} True if phrasing content, false if not. 1760 */ 1761 function isPhrasingContent(node) { 1762 const tag = node.nodeName.toLowerCase(); 1763 return getPhrasingContentSchema().hasOwnProperty(tag) || tag === 'span'; 1764 } 1765 1766 /** 1767 * @param {Node} node 1768 * @return {boolean} Node is text content 1769 */ 1770 function isTextContent(node) { 1771 const tag = node.nodeName.toLowerCase(); 1772 return textContentSchema.hasOwnProperty(tag) || tag === 'span'; 1773 } 1774 1775 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/is-element.js 1776 /* eslint-disable jsdoc/valid-types */ 1777 /** 1778 * @param {Node | null | undefined} node 1779 * @return {node is Element} True if node is an Element node 1780 */ 1781 function isElement(node) { 1782 /* eslint-enable jsdoc/valid-types */ 1783 return !!node && node.nodeType === node.ELEMENT_NODE; 1784 } 1785 1786 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/clean-node-list.js 1787 /** 1788 * Internal dependencies 1789 */ 1790 1791 1792 1793 1794 1795 1796 const noop = () => {}; 1797 1798 /* eslint-disable jsdoc/valid-types */ 1799 /** 1800 * @typedef SchemaItem 1801 * @property {string[]} [attributes] Attributes. 1802 * @property {(string | RegExp)[]} [classes] Classnames or RegExp to test against. 1803 * @property {'*' | { [tag: string]: SchemaItem }} [children] Child schemas. 1804 * @property {string[]} [require] Selectors to test required children against. Leave empty or undefined if there are no requirements. 1805 * @property {boolean} allowEmpty Whether to allow nodes without children. 1806 * @property {(node: Node) => boolean} [isMatch] Function to test whether a node is a match. If left undefined any node will be assumed to match. 1807 */ 1808 1809 /** @typedef {{ [tag: string]: SchemaItem }} Schema */ 1810 /* eslint-enable jsdoc/valid-types */ 1811 1812 /** 1813 * Given a schema, unwraps or removes nodes, attributes and classes on a node 1814 * list. 1815 * 1816 * @param {NodeList} nodeList The nodeList to filter. 1817 * @param {Document} doc The document of the nodeList. 1818 * @param {Schema} schema An array of functions that can mutate with the provided node. 1819 * @param {boolean} inline Whether to clean for inline mode. 1820 */ 1821 function cleanNodeList(nodeList, doc, schema, inline) { 1822 Array.from(nodeList).forEach(( /** @type {Node & { nextElementSibling?: unknown }} */node) => { 1823 const tag = node.nodeName.toLowerCase(); 1824 1825 // It's a valid child, if the tag exists in the schema without an isMatch 1826 // function, or with an isMatch function that matches the node. 1827 if (schema.hasOwnProperty(tag) && (!schema[tag].isMatch || schema[tag].isMatch?.(node))) { 1828 if (isElement(node)) { 1829 const { 1830 attributes = [], 1831 classes = [], 1832 children, 1833 require = [], 1834 allowEmpty 1835 } = schema[tag]; 1836 1837 // If the node is empty and it's supposed to have children, 1838 // remove the node. 1839 if (children && !allowEmpty && isEmpty(node)) { 1840 remove(node); 1841 return; 1842 } 1843 if (node.hasAttributes()) { 1844 // Strip invalid attributes. 1845 Array.from(node.attributes).forEach(({ 1846 name 1847 }) => { 1848 if (name !== 'class' && !attributes.includes(name)) { 1849 node.removeAttribute(name); 1850 } 1851 }); 1852 1853 // Strip invalid classes. 1854 // In jsdom-jscore, 'node.classList' can be undefined. 1855 // TODO: Explore patching this in jsdom-jscore. 1856 if (node.classList && node.classList.length) { 1857 const mattchers = classes.map(item => { 1858 if (typeof item === 'string') { 1859 return ( /** @type {string} */className) => className === item; 1860 } else if (item instanceof RegExp) { 1861 return ( /** @type {string} */className) => item.test(className); 1862 } 1863 return noop; 1864 }); 1865 Array.from(node.classList).forEach(name => { 1866 if (!mattchers.some(isMatch => isMatch(name))) { 1867 node.classList.remove(name); 1868 } 1869 }); 1870 if (!node.classList.length) { 1871 node.removeAttribute('class'); 1872 } 1873 } 1874 } 1875 if (node.hasChildNodes()) { 1876 // Do not filter any content. 1877 if (children === '*') { 1878 return; 1879 } 1880 1881 // Continue if the node is supposed to have children. 1882 if (children) { 1883 // If a parent requires certain children, but it does 1884 // not have them, drop the parent and continue. 1885 if (require.length && !node.querySelector(require.join(','))) { 1886 cleanNodeList(node.childNodes, doc, schema, inline); 1887 unwrap(node); 1888 // If the node is at the top, phrasing content, and 1889 // contains children that are block content, unwrap 1890 // the node because it is invalid. 1891 } else if (node.parentNode && node.parentNode.nodeName === 'BODY' && isPhrasingContent(node)) { 1892 cleanNodeList(node.childNodes, doc, schema, inline); 1893 if (Array.from(node.childNodes).some(child => !isPhrasingContent(child))) { 1894 unwrap(node); 1895 } 1896 } else { 1897 cleanNodeList(node.childNodes, doc, children, inline); 1898 } 1899 // Remove children if the node is not supposed to have any. 1900 } else { 1901 while (node.firstChild) { 1902 remove(node.firstChild); 1903 } 1904 } 1905 } 1906 } 1907 // Invalid child. Continue with schema at the same place and unwrap. 1908 } else { 1909 cleanNodeList(node.childNodes, doc, schema, inline); 1910 1911 // For inline mode, insert a line break when unwrapping nodes that 1912 // are not phrasing content. 1913 if (inline && !isPhrasingContent(node) && node.nextElementSibling) { 1914 insertAfter(doc.createElement('br'), node); 1915 } 1916 unwrap(node); 1917 } 1918 }); 1919 } 1920 1921 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/remove-invalid-html.js 1922 /** 1923 * Internal dependencies 1924 */ 1925 1926 1927 /** 1928 * Given a schema, unwraps or removes nodes, attributes and classes on HTML. 1929 * 1930 * @param {string} HTML The HTML to clean up. 1931 * @param {import('./clean-node-list').Schema} schema Schema for the HTML. 1932 * @param {boolean} inline Whether to clean for inline mode. 1933 * 1934 * @return {string} The cleaned up HTML. 1935 */ 1936 function removeInvalidHTML(HTML, schema, inline) { 1937 const doc = document.implementation.createHTMLDocument(''); 1938 doc.body.innerHTML = HTML; 1939 cleanNodeList(doc.body.childNodes, doc, schema, inline); 1940 return doc.body.innerHTML; 1941 } 1942 1943 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom/index.js 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/data-transfer.js 1973 /** 1974 * Gets all files from a DataTransfer object. 1975 * 1976 * @param {DataTransfer} dataTransfer DataTransfer object to inspect. 1977 * 1978 * @return {File[]} An array containing all files. 1979 */ 1980 function getFilesFromDataTransfer(dataTransfer) { 1981 const files = Array.from(dataTransfer.files); 1982 Array.from(dataTransfer.items).forEach(item => { 1983 const file = item.getAsFile(); 1984 if (file && !files.find(({ 1985 name, 1986 type, 1987 size 1988 }) => name === file.name && type === file.type && size === file.size)) { 1989 files.push(file); 1990 } 1991 }); 1992 return files; 1993 } 1994 1995 ;// CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/index.js 1996 /** 1997 * Internal dependencies 1998 */ 1999 2000 2001 2002 /** 2003 * Object grouping `focusable` and `tabbable` utils 2004 * under the keys with the same name. 2005 */ 2006 const build_module_focus = { 2007 focusable: focusable_namespaceObject, 2008 tabbable: tabbable_namespaceObject 2009 }; 2010 2011 2012 2013 2014 (window.wp = window.wp || {}).dom = __webpack_exports__; 2015 /******/ })() 2016 ;
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Thu Nov 21 08:20:01 2024 | Cross-referenced by PHPXref |