dom.js 62 KB

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