wp/wp-includes/js/dist/dom.js
changeset 9 177826044cd9
child 16 a86126ab1dd4
equal deleted inserted replaced
8:c7c34916027a 9:177826044cd9
       
     1 this["wp"] = this["wp"] || {}; this["wp"]["dom"] =
       
     2 /******/ (function(modules) { // webpackBootstrap
       
     3 /******/ 	// The module cache
       
     4 /******/ 	var installedModules = {};
       
     5 /******/
       
     6 /******/ 	// The require function
       
     7 /******/ 	function __webpack_require__(moduleId) {
       
     8 /******/
       
     9 /******/ 		// Check if module is in cache
       
    10 /******/ 		if(installedModules[moduleId]) {
       
    11 /******/ 			return installedModules[moduleId].exports;
       
    12 /******/ 		}
       
    13 /******/ 		// Create a new module (and put it into the cache)
       
    14 /******/ 		var module = installedModules[moduleId] = {
       
    15 /******/ 			i: moduleId,
       
    16 /******/ 			l: false,
       
    17 /******/ 			exports: {}
       
    18 /******/ 		};
       
    19 /******/
       
    20 /******/ 		// Execute the module function
       
    21 /******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
       
    22 /******/
       
    23 /******/ 		// Flag the module as loaded
       
    24 /******/ 		module.l = true;
       
    25 /******/
       
    26 /******/ 		// Return the exports of the module
       
    27 /******/ 		return module.exports;
       
    28 /******/ 	}
       
    29 /******/
       
    30 /******/
       
    31 /******/ 	// expose the modules object (__webpack_modules__)
       
    32 /******/ 	__webpack_require__.m = modules;
       
    33 /******/
       
    34 /******/ 	// expose the module cache
       
    35 /******/ 	__webpack_require__.c = installedModules;
       
    36 /******/
       
    37 /******/ 	// define getter function for harmony exports
       
    38 /******/ 	__webpack_require__.d = function(exports, name, getter) {
       
    39 /******/ 		if(!__webpack_require__.o(exports, name)) {
       
    40 /******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
       
    41 /******/ 		}
       
    42 /******/ 	};
       
    43 /******/
       
    44 /******/ 	// define __esModule on exports
       
    45 /******/ 	__webpack_require__.r = function(exports) {
       
    46 /******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
       
    47 /******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
       
    48 /******/ 		}
       
    49 /******/ 		Object.defineProperty(exports, '__esModule', { value: true });
       
    50 /******/ 	};
       
    51 /******/
       
    52 /******/ 	// create a fake namespace object
       
    53 /******/ 	// mode & 1: value is a module id, require it
       
    54 /******/ 	// mode & 2: merge all properties of value into the ns
       
    55 /******/ 	// mode & 4: return value when already ns object
       
    56 /******/ 	// mode & 8|1: behave like require
       
    57 /******/ 	__webpack_require__.t = function(value, mode) {
       
    58 /******/ 		if(mode & 1) value = __webpack_require__(value);
       
    59 /******/ 		if(mode & 8) return value;
       
    60 /******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
       
    61 /******/ 		var ns = Object.create(null);
       
    62 /******/ 		__webpack_require__.r(ns);
       
    63 /******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
       
    64 /******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
       
    65 /******/ 		return ns;
       
    66 /******/ 	};
       
    67 /******/
       
    68 /******/ 	// getDefaultExport function for compatibility with non-harmony modules
       
    69 /******/ 	__webpack_require__.n = function(module) {
       
    70 /******/ 		var getter = module && module.__esModule ?
       
    71 /******/ 			function getDefault() { return module['default']; } :
       
    72 /******/ 			function getModuleExports() { return module; };
       
    73 /******/ 		__webpack_require__.d(getter, 'a', getter);
       
    74 /******/ 		return getter;
       
    75 /******/ 	};
       
    76 /******/
       
    77 /******/ 	// Object.prototype.hasOwnProperty.call
       
    78 /******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
       
    79 /******/
       
    80 /******/ 	// __webpack_public_path__
       
    81 /******/ 	__webpack_require__.p = "";
       
    82 /******/
       
    83 /******/
       
    84 /******/ 	// Load entry module and return exports
       
    85 /******/ 	return __webpack_require__(__webpack_require__.s = 379);
       
    86 /******/ })
       
    87 /************************************************************************/
       
    88 /******/ ({
       
    89 
       
    90 /***/ 17:
       
    91 /***/ (function(module, __webpack_exports__, __webpack_require__) {
       
    92 
       
    93 "use strict";
       
    94 
       
    95 // CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js
       
    96 function _arrayWithoutHoles(arr) {
       
    97   if (Array.isArray(arr)) {
       
    98     for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) {
       
    99       arr2[i] = arr[i];
       
   100     }
       
   101 
       
   102     return arr2;
       
   103   }
       
   104 }
       
   105 // EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/iterableToArray.js
       
   106 var iterableToArray = __webpack_require__(34);
       
   107 
       
   108 // CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/nonIterableSpread.js
       
   109 function _nonIterableSpread() {
       
   110   throw new TypeError("Invalid attempt to spread non-iterable instance");
       
   111 }
       
   112 // CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/toConsumableArray.js
       
   113 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return _toConsumableArray; });
       
   114 
       
   115 
       
   116 
       
   117 function _toConsumableArray(arr) {
       
   118   return _arrayWithoutHoles(arr) || Object(iterableToArray["a" /* default */])(arr) || _nonIterableSpread();
       
   119 }
       
   120 
       
   121 /***/ }),
       
   122 
       
   123 /***/ 2:
       
   124 /***/ (function(module, exports) {
       
   125 
       
   126 (function() { module.exports = this["lodash"]; }());
       
   127 
       
   128 /***/ }),
       
   129 
       
   130 /***/ 34:
       
   131 /***/ (function(module, __webpack_exports__, __webpack_require__) {
       
   132 
       
   133 "use strict";
       
   134 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return _iterableToArray; });
       
   135 function _iterableToArray(iter) {
       
   136   if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
       
   137 }
       
   138 
       
   139 /***/ }),
       
   140 
       
   141 /***/ 379:
       
   142 /***/ (function(module, __webpack_exports__, __webpack_require__) {
       
   143 
       
   144 "use strict";
       
   145 __webpack_require__.r(__webpack_exports__);
       
   146 var focusable_namespaceObject = {};
       
   147 __webpack_require__.r(focusable_namespaceObject);
       
   148 __webpack_require__.d(focusable_namespaceObject, "find", function() { return find; });
       
   149 var tabbable_namespaceObject = {};
       
   150 __webpack_require__.r(tabbable_namespaceObject);
       
   151 __webpack_require__.d(tabbable_namespaceObject, "isTabbableIndex", function() { return isTabbableIndex; });
       
   152 __webpack_require__.d(tabbable_namespaceObject, "find", function() { return tabbable_find; });
       
   153 
       
   154 // EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/toConsumableArray.js + 2 modules
       
   155 var toConsumableArray = __webpack_require__(17);
       
   156 
       
   157 // CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/focusable.js
       
   158 
       
   159 
       
   160 /**
       
   161  * References:
       
   162  *
       
   163  * Focusable:
       
   164  *  - https://www.w3.org/TR/html5/editing.html#focus-management
       
   165  *
       
   166  * Sequential focus navigation:
       
   167  *  - https://www.w3.org/TR/html5/editing.html#sequential-focus-navigation-and-the-tabindex-attribute
       
   168  *
       
   169  * Disabled elements:
       
   170  *  - https://www.w3.org/TR/html5/disabled-elements.html#disabled-elements
       
   171  *
       
   172  * getClientRects algorithm (requiring layout box):
       
   173  *  - https://www.w3.org/TR/cssom-view-1/#extension-to-the-element-interface
       
   174  *
       
   175  * AREA elements associated with an IMG:
       
   176  *  - https://w3c.github.io/html/editing.html#data-model
       
   177  */
       
   178 var SELECTOR = ['[tabindex]', 'a[href]', 'button:not([disabled])', 'input:not([type="hidden"]):not([disabled])', 'select:not([disabled])', 'textarea:not([disabled])', 'iframe', 'object', 'embed', 'area[href]', '[contenteditable]:not([contenteditable=false])'].join(',');
       
   179 /**
       
   180  * Returns true if the specified element is visible (i.e. neither display: none
       
   181  * nor visibility: hidden).
       
   182  *
       
   183  * @param {Element} element DOM element to test.
       
   184  *
       
   185  * @return {boolean} Whether element is visible.
       
   186  */
       
   187 
       
   188 function isVisible(element) {
       
   189   return element.offsetWidth > 0 || element.offsetHeight > 0 || element.getClientRects().length > 0;
       
   190 }
       
   191 /**
       
   192  * Returns true if the specified area element is a valid focusable element, or
       
   193  * false otherwise. Area is only focusable if within a map where a named map
       
   194  * referenced by an image somewhere in the document.
       
   195  *
       
   196  * @param {Element} element DOM area element to test.
       
   197  *
       
   198  * @return {boolean} Whether area element is valid for focus.
       
   199  */
       
   200 
       
   201 
       
   202 function isValidFocusableArea(element) {
       
   203   var map = element.closest('map[name]');
       
   204 
       
   205   if (!map) {
       
   206     return false;
       
   207   }
       
   208 
       
   209   var img = document.querySelector('img[usemap="#' + map.name + '"]');
       
   210   return !!img && isVisible(img);
       
   211 }
       
   212 /**
       
   213  * Returns all focusable elements within a given context.
       
   214  *
       
   215  * @param {Element} context Element in which to search.
       
   216  *
       
   217  * @return {Element[]} Focusable elements.
       
   218  */
       
   219 
       
   220 
       
   221 function find(context) {
       
   222   var elements = context.querySelectorAll(SELECTOR);
       
   223   return Object(toConsumableArray["a" /* default */])(elements).filter(function (element) {
       
   224     if (!isVisible(element)) {
       
   225       return false;
       
   226     }
       
   227 
       
   228     var nodeName = element.nodeName;
       
   229 
       
   230     if ('AREA' === nodeName) {
       
   231       return isValidFocusableArea(element);
       
   232     }
       
   233 
       
   234     return true;
       
   235   });
       
   236 }
       
   237 
       
   238 // EXTERNAL MODULE: external "lodash"
       
   239 var external_lodash_ = __webpack_require__(2);
       
   240 
       
   241 // CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/tabbable.js
       
   242 /**
       
   243  * External dependencies
       
   244  */
       
   245 
       
   246 /**
       
   247  * Internal dependencies
       
   248  */
       
   249 
       
   250 
       
   251 /**
       
   252  * Returns the tab index of the given element. In contrast with the tabIndex
       
   253  * property, this normalizes the default (0) to avoid browser inconsistencies,
       
   254  * operating under the assumption that this function is only ever called with a
       
   255  * focusable node.
       
   256  *
       
   257  * @see https://bugzilla.mozilla.org/show_bug.cgi?id=1190261
       
   258  *
       
   259  * @param {Element} element Element from which to retrieve.
       
   260  *
       
   261  * @return {?number} Tab index of element (default 0).
       
   262  */
       
   263 
       
   264 function getTabIndex(element) {
       
   265   var tabIndex = element.getAttribute('tabindex');
       
   266   return tabIndex === null ? 0 : parseInt(tabIndex, 10);
       
   267 }
       
   268 /**
       
   269  * Returns true if the specified element is tabbable, or false otherwise.
       
   270  *
       
   271  * @param {Element} element Element to test.
       
   272  *
       
   273  * @return {boolean} Whether element is tabbable.
       
   274  */
       
   275 
       
   276 
       
   277 function isTabbableIndex(element) {
       
   278   return getTabIndex(element) !== -1;
       
   279 }
       
   280 /**
       
   281  * Returns a stateful reducer function which constructs a filtered array of
       
   282  * tabbable elements, where at most one radio input is selected for a given
       
   283  * name, giving priority to checked input, falling back to the first
       
   284  * encountered.
       
   285  *
       
   286  * @return {Function} Radio group collapse reducer.
       
   287  */
       
   288 
       
   289 function createStatefulCollapseRadioGroup() {
       
   290   var CHOSEN_RADIO_BY_NAME = {};
       
   291   return function collapseRadioGroup(result, element) {
       
   292     var nodeName = element.nodeName,
       
   293         type = element.type,
       
   294         checked = element.checked,
       
   295         name = element.name; // For all non-radio tabbables, construct to array by concatenating.
       
   296 
       
   297     if (nodeName !== 'INPUT' || type !== 'radio' || !name) {
       
   298       return result.concat(element);
       
   299     }
       
   300 
       
   301     var hasChosen = CHOSEN_RADIO_BY_NAME.hasOwnProperty(name); // Omit by skipping concatenation if the radio element is not chosen.
       
   302 
       
   303     var isChosen = checked || !hasChosen;
       
   304 
       
   305     if (!isChosen) {
       
   306       return result;
       
   307     } // At this point, if there had been a chosen element, the current
       
   308     // element is checked and should take priority. Retroactively remove
       
   309     // the element which had previously been considered the chosen one.
       
   310 
       
   311 
       
   312     if (hasChosen) {
       
   313       var hadChosenElement = CHOSEN_RADIO_BY_NAME[name];
       
   314       result = Object(external_lodash_["without"])(result, hadChosenElement);
       
   315     }
       
   316 
       
   317     CHOSEN_RADIO_BY_NAME[name] = element;
       
   318     return result.concat(element);
       
   319   };
       
   320 }
       
   321 /**
       
   322  * An array map callback, returning an object with the element value and its
       
   323  * array index location as properties. This is used to emulate a proper stable
       
   324  * sort where equal tabIndex should be left in order of their occurrence in the
       
   325  * document.
       
   326  *
       
   327  * @param {Element} element Element.
       
   328  * @param {number}  index   Array index of element.
       
   329  *
       
   330  * @return {Object} Mapped object with element, index.
       
   331  */
       
   332 
       
   333 
       
   334 function mapElementToObjectTabbable(element, index) {
       
   335   return {
       
   336     element: element,
       
   337     index: index
       
   338   };
       
   339 }
       
   340 /**
       
   341  * An array map callback, returning an element of the given mapped object's
       
   342  * element value.
       
   343  *
       
   344  * @param {Object} object Mapped object with index.
       
   345  *
       
   346  * @return {Element} Mapped object element.
       
   347  */
       
   348 
       
   349 
       
   350 function mapObjectTabbableToElement(object) {
       
   351   return object.element;
       
   352 }
       
   353 /**
       
   354  * A sort comparator function used in comparing two objects of mapped elements.
       
   355  *
       
   356  * @see mapElementToObjectTabbable
       
   357  *
       
   358  * @param {Object} a First object to compare.
       
   359  * @param {Object} b Second object to compare.
       
   360  *
       
   361  * @return {number} Comparator result.
       
   362  */
       
   363 
       
   364 
       
   365 function compareObjectTabbables(a, b) {
       
   366   var aTabIndex = getTabIndex(a.element);
       
   367   var bTabIndex = getTabIndex(b.element);
       
   368 
       
   369   if (aTabIndex === bTabIndex) {
       
   370     return a.index - b.index;
       
   371   }
       
   372 
       
   373   return aTabIndex - bTabIndex;
       
   374 }
       
   375 
       
   376 function tabbable_find(context) {
       
   377   return find(context).filter(isTabbableIndex).map(mapElementToObjectTabbable).sort(compareObjectTabbables).map(mapObjectTabbableToElement).reduce(createStatefulCollapseRadioGroup(), []);
       
   378 }
       
   379 
       
   380 // CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/dom.js
       
   381 /**
       
   382  * External dependencies
       
   383  */
       
   384 
       
   385 /**
       
   386  * Browser dependencies
       
   387  */
       
   388 
       
   389 var _window = window,
       
   390     getComputedStyle = _window.getComputedStyle;
       
   391 var _window$Node = window.Node,
       
   392     TEXT_NODE = _window$Node.TEXT_NODE,
       
   393     ELEMENT_NODE = _window$Node.ELEMENT_NODE,
       
   394     DOCUMENT_POSITION_PRECEDING = _window$Node.DOCUMENT_POSITION_PRECEDING,
       
   395     DOCUMENT_POSITION_FOLLOWING = _window$Node.DOCUMENT_POSITION_FOLLOWING;
       
   396 /**
       
   397  * Returns true if the given selection object is in the forward direction, or
       
   398  * false otherwise.
       
   399  *
       
   400  * @see https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition
       
   401  *
       
   402  * @param {Selection} selection Selection object to check.
       
   403  *
       
   404  * @return {boolean} Whether the selection is forward.
       
   405  */
       
   406 
       
   407 function isSelectionForward(selection) {
       
   408   var anchorNode = selection.anchorNode,
       
   409       focusNode = selection.focusNode,
       
   410       anchorOffset = selection.anchorOffset,
       
   411       focusOffset = selection.focusOffset;
       
   412   var position = anchorNode.compareDocumentPosition(focusNode); // Disable reason: `Node#compareDocumentPosition` returns a bitmask value,
       
   413   // so bitwise operators are intended.
       
   414 
       
   415   /* eslint-disable no-bitwise */
       
   416   // Compare whether anchor node precedes focus node. If focus node (where
       
   417   // end of selection occurs) is after the anchor node, it is forward.
       
   418 
       
   419   if (position & DOCUMENT_POSITION_PRECEDING) {
       
   420     return false;
       
   421   }
       
   422 
       
   423   if (position & DOCUMENT_POSITION_FOLLOWING) {
       
   424     return true;
       
   425   }
       
   426   /* eslint-enable no-bitwise */
       
   427   // `compareDocumentPosition` returns 0 when passed the same node, in which
       
   428   // case compare offsets.
       
   429 
       
   430 
       
   431   if (position === 0) {
       
   432     return anchorOffset <= focusOffset;
       
   433   } // This should never be reached, but return true as default case.
       
   434 
       
   435 
       
   436   return true;
       
   437 }
       
   438 /**
       
   439  * Check whether the selection is at the edge of the container. Checks for
       
   440  * horizontal position by default. Set `onlyVertical` to true to check only
       
   441  * vertically.
       
   442  *
       
   443  * @param {Element} container    Focusable element.
       
   444  * @param {boolean} isReverse    Set to true to check left, false to check right.
       
   445  * @param {boolean} onlyVertical Set to true to check only vertical position.
       
   446  *
       
   447  * @return {boolean} True if at the edge, false if not.
       
   448  */
       
   449 
       
   450 
       
   451 function isEdge(container, isReverse, onlyVertical) {
       
   452   if (Object(external_lodash_["includes"])(['INPUT', 'TEXTAREA'], container.tagName)) {
       
   453     if (container.selectionStart !== container.selectionEnd) {
       
   454       return false;
       
   455     }
       
   456 
       
   457     if (isReverse) {
       
   458       return container.selectionStart === 0;
       
   459     }
       
   460 
       
   461     return container.value.length === container.selectionStart;
       
   462   }
       
   463 
       
   464   if (!container.isContentEditable) {
       
   465     return true;
       
   466   }
       
   467 
       
   468   var selection = window.getSelection();
       
   469 
       
   470   if (!selection.rangeCount) {
       
   471     return false;
       
   472   }
       
   473 
       
   474   var range = selection.getRangeAt(0).cloneRange();
       
   475   var isForward = isSelectionForward(selection);
       
   476   var isCollapsed = selection.isCollapsed; // Collapse in direction of selection.
       
   477 
       
   478   if (!isCollapsed) {
       
   479     range.collapse(!isForward);
       
   480   }
       
   481 
       
   482   var rangeRect = getRectangleFromRange(range);
       
   483 
       
   484   if (!rangeRect) {
       
   485     return false;
       
   486   }
       
   487 
       
   488   var computedStyle = window.getComputedStyle(container);
       
   489   var lineHeight = parseInt(computedStyle.lineHeight, 10) || 0; // Only consider the multiline selection at the edge if the direction is
       
   490   // towards the edge.
       
   491 
       
   492   if (!isCollapsed && rangeRect.height > lineHeight && isForward === isReverse) {
       
   493     return false;
       
   494   }
       
   495 
       
   496   var padding = parseInt(computedStyle["padding".concat(isReverse ? 'Top' : 'Bottom')], 10) || 0; // Calculate a buffer that is half the line height. In some browsers, the
       
   497   // selection rectangle may not fill the entire height of the line, so we add
       
   498   // 3/4 the line height to the selection rectangle to ensure that it is well
       
   499   // over its line boundary.
       
   500 
       
   501   var buffer = 3 * parseInt(lineHeight, 10) / 4;
       
   502   var containerRect = container.getBoundingClientRect();
       
   503   var verticalEdge = isReverse ? containerRect.top + padding > rangeRect.top - buffer : containerRect.bottom - padding < rangeRect.bottom + buffer;
       
   504 
       
   505   if (!verticalEdge) {
       
   506     return false;
       
   507   }
       
   508 
       
   509   if (onlyVertical) {
       
   510     return true;
       
   511   } // In the case of RTL scripts, the horizontal edge is at the opposite side.
       
   512 
       
   513 
       
   514   var direction = computedStyle.direction;
       
   515   var isReverseDir = direction === 'rtl' ? !isReverse : isReverse; // To calculate the horizontal position, we insert a test range and see if
       
   516   // this test range has the same horizontal position. This method proves to
       
   517   // be better than a DOM-based calculation, because it ignores empty text
       
   518   // nodes and a trailing line break element. In other words, we need to check
       
   519   // visual positioning, not DOM positioning.
       
   520 
       
   521   var x = isReverseDir ? containerRect.left + 1 : containerRect.right - 1;
       
   522   var y = isReverse ? containerRect.top + buffer : containerRect.bottom - buffer;
       
   523   var testRange = hiddenCaretRangeFromPoint(document, x, y, container);
       
   524 
       
   525   if (!testRange) {
       
   526     return false;
       
   527   }
       
   528 
       
   529   var side = isReverseDir ? 'left' : 'right';
       
   530   var testRect = getRectangleFromRange(testRange);
       
   531   return Math.round(testRect[side]) === Math.round(rangeRect[side]);
       
   532 }
       
   533 /**
       
   534  * Check whether the selection is horizontally at the edge of the container.
       
   535  *
       
   536  * @param {Element} container Focusable element.
       
   537  * @param {boolean} isReverse Set to true to check left, false for right.
       
   538  *
       
   539  * @return {boolean} True if at the horizontal edge, false if not.
       
   540  */
       
   541 
       
   542 
       
   543 function isHorizontalEdge(container, isReverse) {
       
   544   return isEdge(container, isReverse);
       
   545 }
       
   546 /**
       
   547  * Check whether the selection is vertically at the edge of the container.
       
   548  *
       
   549  * @param {Element} container Focusable element.
       
   550  * @param {boolean} isReverse Set to true to check top, false for bottom.
       
   551  *
       
   552  * @return {boolean} True if at the vertical edge, false if not.
       
   553  */
       
   554 
       
   555 function isVerticalEdge(container, isReverse) {
       
   556   return isEdge(container, isReverse, true);
       
   557 }
       
   558 /**
       
   559  * Get the rectangle of a given Range.
       
   560  *
       
   561  * @param {Range} range The range.
       
   562  *
       
   563  * @return {DOMRect} The rectangle.
       
   564  */
       
   565 
       
   566 function getRectangleFromRange(range) {
       
   567   // For uncollapsed ranges, get the rectangle that bounds the contents of the
       
   568   // range; this a rectangle enclosing the union of the bounding rectangles
       
   569   // for all the elements in the range.
       
   570   if (!range.collapsed) {
       
   571     return range.getBoundingClientRect();
       
   572   }
       
   573 
       
   574   var _range = range,
       
   575       startContainer = _range.startContainer; // Correct invalid "BR" ranges. The cannot contain any children.
       
   576 
       
   577   if (startContainer.nodeName === 'BR') {
       
   578     var parentNode = startContainer.parentNode;
       
   579     var index = Array.from(parentNode.childNodes).indexOf(startContainer);
       
   580     range = document.createRange();
       
   581     range.setStart(parentNode, index);
       
   582     range.setEnd(parentNode, index);
       
   583   }
       
   584 
       
   585   var rect = range.getClientRects()[0]; // If the collapsed range starts (and therefore ends) at an element node,
       
   586   // `getClientRects` can be empty in some browsers. This can be resolved
       
   587   // by adding a temporary text node with zero-width space to the range.
       
   588   //
       
   589   // See: https://stackoverflow.com/a/6847328/995445
       
   590 
       
   591   if (!rect) {
       
   592     var padNode = document.createTextNode("\u200B"); // Do not modify the live range.
       
   593 
       
   594     range = range.cloneRange();
       
   595     range.insertNode(padNode);
       
   596     rect = range.getClientRects()[0];
       
   597     padNode.parentNode.removeChild(padNode);
       
   598   }
       
   599 
       
   600   return rect;
       
   601 }
       
   602 /**
       
   603  * Get the rectangle for the selection in a container.
       
   604  *
       
   605  * @param {Element} container Editable container.
       
   606  *
       
   607  * @return {?DOMRect} The rectangle.
       
   608  */
       
   609 
       
   610 function computeCaretRect(container) {
       
   611   if (!container.isContentEditable) {
       
   612     return;
       
   613   }
       
   614 
       
   615   var selection = window.getSelection();
       
   616   var range = selection.rangeCount ? selection.getRangeAt(0) : null;
       
   617 
       
   618   if (!range) {
       
   619     return;
       
   620   }
       
   621 
       
   622   return getRectangleFromRange(range);
       
   623 }
       
   624 /**
       
   625  * Places the caret at start or end of a given element.
       
   626  *
       
   627  * @param {Element} container Focusable element.
       
   628  * @param {boolean} isReverse True for end, false for start.
       
   629  */
       
   630 
       
   631 function placeCaretAtHorizontalEdge(container, isReverse) {
       
   632   if (!container) {
       
   633     return;
       
   634   }
       
   635 
       
   636   if (Object(external_lodash_["includes"])(['INPUT', 'TEXTAREA'], container.tagName)) {
       
   637     container.focus();
       
   638 
       
   639     if (isReverse) {
       
   640       container.selectionStart = container.value.length;
       
   641       container.selectionEnd = container.value.length;
       
   642     } else {
       
   643       container.selectionStart = 0;
       
   644       container.selectionEnd = 0;
       
   645     }
       
   646 
       
   647     return;
       
   648   }
       
   649 
       
   650   container.focus();
       
   651 
       
   652   if (!container.isContentEditable) {
       
   653     return;
       
   654   } // Select on extent child of the container, not the container itself. This
       
   655   // avoids the selection always being `endOffset` of 1 when placed at end,
       
   656   // where `startContainer`, `endContainer` would always be container itself.
       
   657 
       
   658 
       
   659   var rangeTarget = container[isReverse ? 'lastChild' : 'firstChild']; // If no range target, it implies that the container is empty. Focusing is
       
   660   // sufficient for caret to be placed correctly.
       
   661 
       
   662   if (!rangeTarget) {
       
   663     return;
       
   664   }
       
   665 
       
   666   var selection = window.getSelection();
       
   667   var range = document.createRange();
       
   668   range.selectNodeContents(rangeTarget);
       
   669   range.collapse(!isReverse);
       
   670   selection.removeAllRanges();
       
   671   selection.addRange(range);
       
   672 }
       
   673 /**
       
   674  * Polyfill.
       
   675  * Get a collapsed range for a given point.
       
   676  *
       
   677  * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/caretRangeFromPoint
       
   678  *
       
   679  * @param {Document} doc The document of the range.
       
   680  * @param {number}    x   Horizontal position within the current viewport.
       
   681  * @param {number}    y   Vertical position within the current viewport.
       
   682  *
       
   683  * @return {?Range} The best range for the given point.
       
   684  */
       
   685 
       
   686 function caretRangeFromPoint(doc, x, y) {
       
   687   if (doc.caretRangeFromPoint) {
       
   688     return doc.caretRangeFromPoint(x, y);
       
   689   }
       
   690 
       
   691   if (!doc.caretPositionFromPoint) {
       
   692     return null;
       
   693   }
       
   694 
       
   695   var point = doc.caretPositionFromPoint(x, y); // If x or y are negative, outside viewport, or there is no text entry node.
       
   696   // https://developer.mozilla.org/en-US/docs/Web/API/Document/caretRangeFromPoint
       
   697 
       
   698   if (!point) {
       
   699     return null;
       
   700   }
       
   701 
       
   702   var range = doc.createRange();
       
   703   range.setStart(point.offsetNode, point.offset);
       
   704   range.collapse(true);
       
   705   return range;
       
   706 }
       
   707 /**
       
   708  * Get a collapsed range for a given point.
       
   709  * Gives the container a temporary high z-index (above any UI).
       
   710  * This is preferred over getting the UI nodes and set styles there.
       
   711  *
       
   712  * @param {Document} doc       The document of the range.
       
   713  * @param {number}    x         Horizontal position within the current viewport.
       
   714  * @param {number}    y         Vertical position within the current viewport.
       
   715  * @param {Element}  container Container in which the range is expected to be found.
       
   716  *
       
   717  * @return {?Range} The best range for the given point.
       
   718  */
       
   719 
       
   720 
       
   721 function hiddenCaretRangeFromPoint(doc, x, y, container) {
       
   722   container.style.zIndex = '10000';
       
   723   var range = caretRangeFromPoint(doc, x, y);
       
   724   container.style.zIndex = null;
       
   725   return range;
       
   726 }
       
   727 /**
       
   728  * Places the caret at the top or bottom of a given element.
       
   729  *
       
   730  * @param {Element} container           Focusable element.
       
   731  * @param {boolean} isReverse           True for bottom, false for top.
       
   732  * @param {DOMRect} [rect]              The rectangle to position the caret with.
       
   733  * @param {boolean} [mayUseScroll=true] True to allow scrolling, false to disallow.
       
   734  */
       
   735 
       
   736 
       
   737 function placeCaretAtVerticalEdge(container, isReverse, rect) {
       
   738   var mayUseScroll = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
       
   739 
       
   740   if (!container) {
       
   741     return;
       
   742   }
       
   743 
       
   744   if (!rect || !container.isContentEditable) {
       
   745     placeCaretAtHorizontalEdge(container, isReverse);
       
   746     return;
       
   747   } // Offset by a buffer half the height of the caret rect. This is needed
       
   748   // because caretRangeFromPoint may default to the end of the selection if
       
   749   // offset is too close to the edge. It's unclear how to precisely calculate
       
   750   // this threshold; it may be the padded area of some combination of line
       
   751   // height, caret height, and font size. The buffer offset is effectively
       
   752   // equivalent to a point at half the height of a line of text.
       
   753 
       
   754 
       
   755   var buffer = rect.height / 2;
       
   756   var editableRect = container.getBoundingClientRect();
       
   757   var x = rect.left;
       
   758   var y = isReverse ? editableRect.bottom - buffer : editableRect.top + buffer;
       
   759   var range = hiddenCaretRangeFromPoint(document, x, y, container);
       
   760 
       
   761   if (!range || !container.contains(range.startContainer)) {
       
   762     if (mayUseScroll && (!range || !range.startContainer || !range.startContainer.contains(container))) {
       
   763       // Might be out of view.
       
   764       // Easier than attempting to calculate manually.
       
   765       container.scrollIntoView(isReverse);
       
   766       placeCaretAtVerticalEdge(container, isReverse, rect, false);
       
   767       return;
       
   768     }
       
   769 
       
   770     placeCaretAtHorizontalEdge(container, isReverse);
       
   771     return;
       
   772   } // Check if the closest text node is actually further away.
       
   773   // If so, attempt to get the range again with the y position adjusted to get the right offset.
       
   774 
       
   775 
       
   776   if (range.startContainer.nodeType === TEXT_NODE) {
       
   777     var parentNode = range.startContainer.parentNode;
       
   778     var parentRect = parentNode.getBoundingClientRect();
       
   779     var side = isReverse ? 'bottom' : 'top';
       
   780     var padding = parseInt(getComputedStyle(parentNode).getPropertyValue("padding-".concat(side)), 10) || 0;
       
   781     var actualY = isReverse ? parentRect.bottom - padding - buffer : parentRect.top + padding + buffer;
       
   782 
       
   783     if (y !== actualY) {
       
   784       range = hiddenCaretRangeFromPoint(document, x, actualY, container);
       
   785     }
       
   786   }
       
   787 
       
   788   var selection = window.getSelection();
       
   789   selection.removeAllRanges();
       
   790   selection.addRange(range);
       
   791   container.focus(); // Editable was already focussed, it goes back to old range...
       
   792   // This fixes it.
       
   793 
       
   794   selection.removeAllRanges();
       
   795   selection.addRange(range);
       
   796 }
       
   797 /**
       
   798  * Check whether the given element is a text field, where text field is defined
       
   799  * by the ability to select within the input, or that it is contenteditable.
       
   800  *
       
   801  * See: https://html.spec.whatwg.org/#textFieldSelection
       
   802  *
       
   803  * @param {HTMLElement} element The HTML element.
       
   804  *
       
   805  * @return {boolean} True if the element is an text field, false if not.
       
   806  */
       
   807 
       
   808 function isTextField(element) {
       
   809   try {
       
   810     var nodeName = element.nodeName,
       
   811         selectionStart = element.selectionStart,
       
   812         contentEditable = element.contentEditable;
       
   813     return nodeName === 'INPUT' && selectionStart !== null || nodeName === 'TEXTAREA' || contentEditable === 'true';
       
   814   } catch (error) {
       
   815     // Safari throws an exception when trying to get `selectionStart`
       
   816     // on non-text <input> elements (which, understandably, don't
       
   817     // have the text selection API). We catch this via a try/catch
       
   818     // block, as opposed to a more explicit check of the element's
       
   819     // input types, because of Safari's non-standard behavior. This
       
   820     // also means we don't have to worry about the list of input
       
   821     // types that support `selectionStart` changing as the HTML spec
       
   822     // evolves over time.
       
   823     return false;
       
   824   }
       
   825 }
       
   826 /**
       
   827  * Check wether the current document has a selection.
       
   828  * This checks both for focus in an input field and general text selection.
       
   829  *
       
   830  * @return {boolean} True if there is selection, false if not.
       
   831  */
       
   832 
       
   833 function documentHasSelection() {
       
   834   if (isTextField(document.activeElement)) {
       
   835     return true;
       
   836   }
       
   837 
       
   838   var selection = window.getSelection();
       
   839   var range = selection.rangeCount ? selection.getRangeAt(0) : null;
       
   840   return range && !range.collapsed;
       
   841 }
       
   842 /**
       
   843  * Check whether the contents of the element have been entirely selected.
       
   844  * Returns true if there is no possibility of selection.
       
   845  *
       
   846  * @param {Element} element The element to check.
       
   847  *
       
   848  * @return {boolean} True if entirely selected, false if not.
       
   849  */
       
   850 
       
   851 function isEntirelySelected(element) {
       
   852   if (Object(external_lodash_["includes"])(['INPUT', 'TEXTAREA'], element.nodeName)) {
       
   853     return element.selectionStart === 0 && element.value.length === element.selectionEnd;
       
   854   }
       
   855 
       
   856   if (!element.isContentEditable) {
       
   857     return true;
       
   858   }
       
   859 
       
   860   var selection = window.getSelection();
       
   861   var range = selection.rangeCount ? selection.getRangeAt(0) : null;
       
   862 
       
   863   if (!range) {
       
   864     return true;
       
   865   }
       
   866 
       
   867   var startContainer = range.startContainer,
       
   868       endContainer = range.endContainer,
       
   869       startOffset = range.startOffset,
       
   870       endOffset = range.endOffset;
       
   871 
       
   872   if (startContainer === element && endContainer === element && startOffset === 0 && endOffset === element.childNodes.length) {
       
   873     return true;
       
   874   }
       
   875 
       
   876   var lastChild = element.lastChild;
       
   877   var lastChildContentLength = lastChild.nodeType === TEXT_NODE ? lastChild.data.length : lastChild.childNodes.length;
       
   878   return startContainer === element.firstChild && endContainer === element.lastChild && startOffset === 0 && endOffset === lastChildContentLength;
       
   879 }
       
   880 /**
       
   881  * Given a DOM node, finds the closest scrollable container node.
       
   882  *
       
   883  * @param {Element} node Node from which to start.
       
   884  *
       
   885  * @return {?Element} Scrollable container node, if found.
       
   886  */
       
   887 
       
   888 function getScrollContainer(node) {
       
   889   if (!node) {
       
   890     return;
       
   891   } // Scrollable if scrollable height exceeds displayed...
       
   892 
       
   893 
       
   894   if (node.scrollHeight > node.clientHeight) {
       
   895     // ...except when overflow is defined to be hidden or visible
       
   896     var _window$getComputedSt = window.getComputedStyle(node),
       
   897         overflowY = _window$getComputedSt.overflowY;
       
   898 
       
   899     if (/(auto|scroll)/.test(overflowY)) {
       
   900       return node;
       
   901     }
       
   902   } // Continue traversing
       
   903 
       
   904 
       
   905   return getScrollContainer(node.parentNode);
       
   906 }
       
   907 /**
       
   908  * Returns the closest positioned element, or null under any of the conditions
       
   909  * of the offsetParent specification. Unlike offsetParent, this function is not
       
   910  * limited to HTMLElement and accepts any Node (e.g. Node.TEXT_NODE).
       
   911  *
       
   912  * @see https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetparent
       
   913  *
       
   914  * @param {Node} node Node from which to find offset parent.
       
   915  *
       
   916  * @return {?Node} Offset parent.
       
   917  */
       
   918 
       
   919 function getOffsetParent(node) {
       
   920   // Cannot retrieve computed style or offset parent only anything other than
       
   921   // an element node, so find the closest element node.
       
   922   var closestElement;
       
   923 
       
   924   while (closestElement = node.parentNode) {
       
   925     if (closestElement.nodeType === ELEMENT_NODE) {
       
   926       break;
       
   927     }
       
   928   }
       
   929 
       
   930   if (!closestElement) {
       
   931     return null;
       
   932   } // If the closest element is already positioned, return it, as offsetParent
       
   933   // does not otherwise consider the node itself.
       
   934 
       
   935 
       
   936   if (getComputedStyle(closestElement).position !== 'static') {
       
   937     return closestElement;
       
   938   }
       
   939 
       
   940   return closestElement.offsetParent;
       
   941 }
       
   942 /**
       
   943  * Given two DOM nodes, replaces the former with the latter in the DOM.
       
   944  *
       
   945  * @param {Element} processedNode Node to be removed.
       
   946  * @param {Element} newNode       Node to be inserted in its place.
       
   947  * @return {void}
       
   948  */
       
   949 
       
   950 function replace(processedNode, newNode) {
       
   951   insertAfter(newNode, processedNode.parentNode);
       
   952   remove(processedNode);
       
   953 }
       
   954 /**
       
   955  * Given a DOM node, removes it from the DOM.
       
   956  *
       
   957  * @param {Element} node Node to be removed.
       
   958  * @return {void}
       
   959  */
       
   960 
       
   961 function remove(node) {
       
   962   node.parentNode.removeChild(node);
       
   963 }
       
   964 /**
       
   965  * Given two DOM nodes, inserts the former in the DOM as the next sibling of
       
   966  * the latter.
       
   967  *
       
   968  * @param {Element} newNode       Node to be inserted.
       
   969  * @param {Element} referenceNode Node after which to perform the insertion.
       
   970  * @return {void}
       
   971  */
       
   972 
       
   973 function insertAfter(newNode, referenceNode) {
       
   974   referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
       
   975 }
       
   976 /**
       
   977  * Unwrap the given node. This means any child nodes are moved to the parent.
       
   978  *
       
   979  * @param {Node} node The node to unwrap.
       
   980  *
       
   981  * @return {void}
       
   982  */
       
   983 
       
   984 function unwrap(node) {
       
   985   var parent = node.parentNode;
       
   986 
       
   987   while (node.firstChild) {
       
   988     parent.insertBefore(node.firstChild, node);
       
   989   }
       
   990 
       
   991   parent.removeChild(node);
       
   992 }
       
   993 /**
       
   994  * Replaces the given node with a new node with the given tag name.
       
   995  *
       
   996  * @param {Element}  node    The node to replace
       
   997  * @param {string}   tagName The new tag name.
       
   998  *
       
   999  * @return {Element} The new node.
       
  1000  */
       
  1001 
       
  1002 function replaceTag(node, tagName) {
       
  1003   var newNode = node.ownerDocument.createElement(tagName);
       
  1004 
       
  1005   while (node.firstChild) {
       
  1006     newNode.appendChild(node.firstChild);
       
  1007   }
       
  1008 
       
  1009   node.parentNode.replaceChild(newNode, node);
       
  1010   return newNode;
       
  1011 }
       
  1012 /**
       
  1013  * Wraps the given node with a new node with the given tag name.
       
  1014  *
       
  1015  * @param {Element} newNode       The node to insert.
       
  1016  * @param {Element} referenceNode The node to wrap.
       
  1017  */
       
  1018 
       
  1019 function wrap(newNode, referenceNode) {
       
  1020   referenceNode.parentNode.insertBefore(newNode, referenceNode);
       
  1021   newNode.appendChild(referenceNode);
       
  1022 }
       
  1023 
       
  1024 // CONCATENATED MODULE: ./node_modules/@wordpress/dom/build-module/index.js
       
  1025 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "focus", function() { return build_module_focus; });
       
  1026 /* concated harmony reexport isHorizontalEdge */__webpack_require__.d(__webpack_exports__, "isHorizontalEdge", function() { return isHorizontalEdge; });
       
  1027 /* concated harmony reexport isVerticalEdge */__webpack_require__.d(__webpack_exports__, "isVerticalEdge", function() { return isVerticalEdge; });
       
  1028 /* concated harmony reexport getRectangleFromRange */__webpack_require__.d(__webpack_exports__, "getRectangleFromRange", function() { return getRectangleFromRange; });
       
  1029 /* concated harmony reexport computeCaretRect */__webpack_require__.d(__webpack_exports__, "computeCaretRect", function() { return computeCaretRect; });
       
  1030 /* concated harmony reexport placeCaretAtHorizontalEdge */__webpack_require__.d(__webpack_exports__, "placeCaretAtHorizontalEdge", function() { return placeCaretAtHorizontalEdge; });
       
  1031 /* concated harmony reexport placeCaretAtVerticalEdge */__webpack_require__.d(__webpack_exports__, "placeCaretAtVerticalEdge", function() { return placeCaretAtVerticalEdge; });
       
  1032 /* concated harmony reexport isTextField */__webpack_require__.d(__webpack_exports__, "isTextField", function() { return isTextField; });
       
  1033 /* concated harmony reexport documentHasSelection */__webpack_require__.d(__webpack_exports__, "documentHasSelection", function() { return documentHasSelection; });
       
  1034 /* concated harmony reexport isEntirelySelected */__webpack_require__.d(__webpack_exports__, "isEntirelySelected", function() { return isEntirelySelected; });
       
  1035 /* concated harmony reexport getScrollContainer */__webpack_require__.d(__webpack_exports__, "getScrollContainer", function() { return getScrollContainer; });
       
  1036 /* concated harmony reexport getOffsetParent */__webpack_require__.d(__webpack_exports__, "getOffsetParent", function() { return getOffsetParent; });
       
  1037 /* concated harmony reexport replace */__webpack_require__.d(__webpack_exports__, "replace", function() { return replace; });
       
  1038 /* concated harmony reexport remove */__webpack_require__.d(__webpack_exports__, "remove", function() { return remove; });
       
  1039 /* concated harmony reexport insertAfter */__webpack_require__.d(__webpack_exports__, "insertAfter", function() { return insertAfter; });
       
  1040 /* concated harmony reexport unwrap */__webpack_require__.d(__webpack_exports__, "unwrap", function() { return unwrap; });
       
  1041 /* concated harmony reexport replaceTag */__webpack_require__.d(__webpack_exports__, "replaceTag", function() { return replaceTag; });
       
  1042 /* concated harmony reexport wrap */__webpack_require__.d(__webpack_exports__, "wrap", function() { return wrap; });
       
  1043 /**
       
  1044  * Internal dependencies
       
  1045  */
       
  1046 
       
  1047 
       
  1048 /**
       
  1049  * Object grouping `focusable` and `tabbable` utils
       
  1050  * under the keys with the same name.
       
  1051  */
       
  1052 
       
  1053 var build_module_focus = {
       
  1054   focusable: focusable_namespaceObject,
       
  1055   tabbable: tabbable_namespaceObject
       
  1056 };
       
  1057 
       
  1058 
       
  1059 
       
  1060 /***/ })
       
  1061 
       
  1062 /******/ });