[ 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  /**
 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  ;// ./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  ;// ./node_modules/@wordpress/dom/build-module/utils/assert-is-defined.js
 382  function assertIsDefined(val, name) {
 383    if (false) {}
 384  }
 385  
 386  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// 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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;// ./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  ;


Generated : Sat Dec 21 08:20:01 2024 Cross-referenced by PHPXref