[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

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

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


Generated: Fri Dec 6 01:00:02 2024 Cross-referenced by PHPXref 0.7.1