[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/js/dist/ -> dom.js (source)

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


Generated : Sat Feb 22 08:20:01 2025 Cross-referenced by PHPXref