PluginProbe
Gutenberg / 12.7.2
Gutenberg v12.7.2
24.0.0 23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 All 403 releases
gutenberg / build / compose / index.js

index.js in Gutenberg 12.7.2, at build/compose/index.js

4,795 lines 149.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /******/ (function() { // webpackBootstrap
2 /******/ var __webpack_modules__ = ({
3
4 /***/ 8294:
5 /***/ (function(module) {
6
7 /*!
8 * clipboard.js v2.0.8
9 * https://clipboardjs.com/
10 *
11 * Licensed MIT © Zeno Rocha
12 */
13 (function webpackUniversalModuleDefinition(root, factory) {
14 if(true)
15 module.exports = factory();
16 else {}
17 })(this, function() {
18 return /******/ (function() { // webpackBootstrap
19 /******/ var __webpack_modules__ = ({
20
21 /***/ 134:
22 /***/ (function(__unused_webpack_module, __webpack_exports__, __nested_webpack_require_622__) {
23
24 "use strict";
25
26 // EXPORTS
27 __nested_webpack_require_622__.d(__webpack_exports__, {
28 "default": function() { return /* binding */ clipboard; }
29 });
30
31 // EXTERNAL MODULE: ./node_modules/tiny-emitter/index.js
32 var tiny_emitter = __nested_webpack_require_622__(279);
33 var tiny_emitter_default = /*#__PURE__*/__nested_webpack_require_622__.n(tiny_emitter);
34 // EXTERNAL MODULE: ./node_modules/good-listener/src/listen.js
35 var listen = __nested_webpack_require_622__(370);
36 var listen_default = /*#__PURE__*/__nested_webpack_require_622__.n(listen);
37 // EXTERNAL MODULE: ./node_modules/select/src/select.js
38 var src_select = __nested_webpack_require_622__(817);
39 var select_default = /*#__PURE__*/__nested_webpack_require_622__.n(src_select);
40 ;// CONCATENATED MODULE: ./src/clipboard-action.js
41 function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
42
43 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
44
45 function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
46
47 function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
48
49
50 /**
51 * Inner class which performs selection from either `text` or `target`
52 * properties and then executes copy or cut operations.
53 */
54
55 var ClipboardAction = /*#__PURE__*/function () {
56 /**
57 * @param {Object} options
58 */
59 function ClipboardAction(options) {
60 _classCallCheck(this, ClipboardAction);
61
62 this.resolveOptions(options);
63 this.initSelection();
64 }
65 /**
66 * Defines base properties passed from constructor.
67 * @param {Object} options
68 */
69
70
71 _createClass(ClipboardAction, [{
72 key: "resolveOptions",
73 value: function resolveOptions() {
74 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
75 this.action = options.action;
76 this.container = options.container;
77 this.emitter = options.emitter;
78 this.target = options.target;
79 this.text = options.text;
80 this.trigger = options.trigger;
81 this.selectedText = '';
82 }
83 /**
84 * Decides which selection strategy is going to be applied based
85 * on the existence of `text` and `target` properties.
86 */
87
88 }, {
89 key: "initSelection",
90 value: function initSelection() {
91 if (this.text) {
92 this.selectFake();
93 } else if (this.target) {
94 this.selectTarget();
95 }
96 }
97 /**
98 * Creates a fake textarea element, sets its value from `text` property,
99 */
100
101 }, {
102 key: "createFakeElement",
103 value: function createFakeElement() {
104 var isRTL = document.documentElement.getAttribute('dir') === 'rtl';
105 this.fakeElem = document.createElement('textarea'); // Prevent zooming on iOS
106
107 this.fakeElem.style.fontSize = '12pt'; // Reset box model
108
109 this.fakeElem.style.border = '0';
110 this.fakeElem.style.padding = '0';
111 this.fakeElem.style.margin = '0'; // Move element out of screen horizontally
112
113 this.fakeElem.style.position = 'absolute';
114 this.fakeElem.style[isRTL ? 'right' : 'left'] = '-9999px'; // Move element to the same position vertically
115
116 var yPosition = window.pageYOffset || document.documentElement.scrollTop;
117 this.fakeElem.style.top = "".concat(yPosition, "px");
118 this.fakeElem.setAttribute('readonly', '');
119 this.fakeElem.value = this.text;
120 return this.fakeElem;
121 }
122 /**
123 * Get's the value of fakeElem,
124 * and makes a selection on it.
125 */
126
127 }, {
128 key: "selectFake",
129 value: function selectFake() {
130 var _this = this;
131
132 var fakeElem = this.createFakeElement();
133
134 this.fakeHandlerCallback = function () {
135 return _this.removeFake();
136 };
137
138 this.fakeHandler = this.container.addEventListener('click', this.fakeHandlerCallback) || true;
139 this.container.appendChild(fakeElem);
140 this.selectedText = select_default()(fakeElem);
141 this.copyText();
142 this.removeFake();
143 }
144 /**
145 * Only removes the fake element after another click event, that way
146 * a user can hit `Ctrl+C` to copy because selection still exists.
147 */
148
149 }, {
150 key: "removeFake",
151 value: function removeFake() {
152 if (this.fakeHandler) {
153 this.container.removeEventListener('click', this.fakeHandlerCallback);
154 this.fakeHandler = null;
155 this.fakeHandlerCallback = null;
156 }
157
158 if (this.fakeElem) {
159 this.container.removeChild(this.fakeElem);
160 this.fakeElem = null;
161 }
162 }
163 /**
164 * Selects the content from element passed on `target` property.
165 */
166
167 }, {
168 key: "selectTarget",
169 value: function selectTarget() {
170 this.selectedText = select_default()(this.target);
171 this.copyText();
172 }
173 /**
174 * Executes the copy operation based on the current selection.
175 */
176
177 }, {
178 key: "copyText",
179 value: function copyText() {
180 var succeeded;
181
182 try {
183 succeeded = document.execCommand(this.action);
184 } catch (err) {
185 succeeded = false;
186 }
187
188 this.handleResult(succeeded);
189 }
190 /**
191 * Fires an event based on the copy operation result.
192 * @param {Boolean} succeeded
193 */
194
195 }, {
196 key: "handleResult",
197 value: function handleResult(succeeded) {
198 this.emitter.emit(succeeded ? 'success' : 'error', {
199 action: this.action,
200 text: this.selectedText,
201 trigger: this.trigger,
202 clearSelection: this.clearSelection.bind(this)
203 });
204 }
205 /**
206 * Moves focus away from `target` and back to the trigger, removes current selection.
207 */
208
209 }, {
210 key: "clearSelection",
211 value: function clearSelection() {
212 if (this.trigger) {
213 this.trigger.focus();
214 }
215
216 document.activeElement.blur();
217 window.getSelection().removeAllRanges();
218 }
219 /**
220 * Sets the `action` to be performed which can be either 'copy' or 'cut'.
221 * @param {String} action
222 */
223
224 }, {
225 key: "destroy",
226
227 /**
228 * Destroy lifecycle.
229 */
230 value: function destroy() {
231 this.removeFake();
232 }
233 }, {
234 key: "action",
235 set: function set() {
236 var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'copy';
237 this._action = action;
238
239 if (this._action !== 'copy' && this._action !== 'cut') {
240 throw new Error('Invalid "action" value, use either "copy" or "cut"');
241 }
242 }
243 /**
244 * Gets the `action` property.
245 * @return {String}
246 */
247 ,
248 get: function get() {
249 return this._action;
250 }
251 /**
252 * Sets the `target` property using an element
253 * that will be have its content copied.
254 * @param {Element} target
255 */
256
257 }, {
258 key: "target",
259 set: function set(target) {
260 if (target !== undefined) {
261 if (target && _typeof(target) === 'object' && target.nodeType === 1) {
262 if (this.action === 'copy' && target.hasAttribute('disabled')) {
263 throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');
264 }
265
266 if (this.action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {
267 throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');
268 }
269
270 this._target = target;
271 } else {
272 throw new Error('Invalid "target" value, use a valid Element');
273 }
274 }
275 }
276 /**
277 * Gets the `target` property.
278 * @return {String|HTMLElement}
279 */
280 ,
281 get: function get() {
282 return this._target;
283 }
284 }]);
285
286 return ClipboardAction;
287 }();
288
289 /* harmony default export */ var clipboard_action = (ClipboardAction);
290 ;// CONCATENATED MODULE: ./src/clipboard.js
291 function clipboard_typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { clipboard_typeof = function _typeof(obj) { return typeof obj; }; } else { clipboard_typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return clipboard_typeof(obj); }
292
293 function clipboard_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
294
295 function clipboard_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
296
297 function clipboard_createClass(Constructor, protoProps, staticProps) { if (protoProps) clipboard_defineProperties(Constructor.prototype, protoProps); if (staticProps) clipboard_defineProperties(Constructor, staticProps); return Constructor; }
298
299 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
300
301 function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
302
303 function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
304
305 function _possibleConstructorReturn(self, call) { if (call && (clipboard_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
306
307 function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
308
309 function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
310
311 function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
312
313
314
315
316 /**
317 * Helper function to retrieve attribute value.
318 * @param {String} suffix
319 * @param {Element} element
320 */
321
322 function getAttributeValue(suffix, element) {
323 var attribute = "data-clipboard-".concat(suffix);
324
325 if (!element.hasAttribute(attribute)) {
326 return;
327 }
328
329 return element.getAttribute(attribute);
330 }
331 /**
332 * Base class which takes one or more elements, adds event listeners to them,
333 * and instantiates a new `ClipboardAction` on each click.
334 */
335
336
337 var Clipboard = /*#__PURE__*/function (_Emitter) {
338 _inherits(Clipboard, _Emitter);
339
340 var _super = _createSuper(Clipboard);
341
342 /**
343 * @param {String|HTMLElement|HTMLCollection|NodeList} trigger
344 * @param {Object} options
345 */
346 function Clipboard(trigger, options) {
347 var _this;
348
349 clipboard_classCallCheck(this, Clipboard);
350
351 _this = _super.call(this);
352
353 _this.resolveOptions(options);
354
355 _this.listenClick(trigger);
356
357 return _this;
358 }
359 /**
360 * Defines if attributes would be resolved using internal setter functions
361 * or custom functions that were passed in the constructor.
362 * @param {Object} options
363 */
364
365
366 clipboard_createClass(Clipboard, [{
367 key: "resolveOptions",
368 value: function resolveOptions() {
369 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
370 this.action = typeof options.action === 'function' ? options.action : this.defaultAction;
371 this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;
372 this.text = typeof options.text === 'function' ? options.text : this.defaultText;
373 this.container = clipboard_typeof(options.container) === 'object' ? options.container : document.body;
374 }
375 /**
376 * Adds a click event listener to the passed trigger.
377 * @param {String|HTMLElement|HTMLCollection|NodeList} trigger
378 */
379
380 }, {
381 key: "listenClick",
382 value: function listenClick(trigger) {
383 var _this2 = this;
384
385 this.listener = listen_default()(trigger, 'click', function (e) {
386 return _this2.onClick(e);
387 });
388 }
389 /**
390 * Defines a new `ClipboardAction` on each click event.
391 * @param {Event} e
392 */
393
394 }, {
395 key: "onClick",
396 value: function onClick(e) {
397 var trigger = e.delegateTarget || e.currentTarget;
398
399 if (this.clipboardAction) {
400 this.clipboardAction = null;
401 }
402
403 this.clipboardAction = new clipboard_action({
404 action: this.action(trigger),
405 target: this.target(trigger),
406 text: this.text(trigger),
407 container: this.container,
408 trigger: trigger,
409 emitter: this
410 });
411 }
412 /**
413 * Default `action` lookup function.
414 * @param {Element} trigger
415 */
416
417 }, {
418 key: "defaultAction",
419 value: function defaultAction(trigger) {
420 return getAttributeValue('action', trigger);
421 }
422 /**
423 * Default `target` lookup function.
424 * @param {Element} trigger
425 */
426
427 }, {
428 key: "defaultTarget",
429 value: function defaultTarget(trigger) {
430 var selector = getAttributeValue('target', trigger);
431
432 if (selector) {
433 return document.querySelector(selector);
434 }
435 }
436 /**
437 * Returns the support of the given action, or all actions if no action is
438 * given.
439 * @param {String} [action]
440 */
441
442 }, {
443 key: "defaultText",
444
445 /**
446 * Default `text` lookup function.
447 * @param {Element} trigger
448 */
449 value: function defaultText(trigger) {
450 return getAttributeValue('text', trigger);
451 }
452 /**
453 * Destroy lifecycle.
454 */
455
456 }, {
457 key: "destroy",
458 value: function destroy() {
459 this.listener.destroy();
460
461 if (this.clipboardAction) {
462 this.clipboardAction.destroy();
463 this.clipboardAction = null;
464 }
465 }
466 }], [{
467 key: "isSupported",
468 value: function isSupported() {
469 var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut'];
470 var actions = typeof action === 'string' ? [action] : action;
471 var support = !!document.queryCommandSupported;
472 actions.forEach(function (action) {
473 support = support && !!document.queryCommandSupported(action);
474 });
475 return support;
476 }
477 }]);
478
479 return Clipboard;
480 }((tiny_emitter_default()));
481
482 /* harmony default export */ var clipboard = (Clipboard);
483
484 /***/ }),
485
486 /***/ 828:
487 /***/ (function(module) {
488
489 var DOCUMENT_NODE_TYPE = 9;
490
491 /**
492 * A polyfill for Element.matches()
493 */
494 if (typeof Element !== 'undefined' && !Element.prototype.matches) {
495 var proto = Element.prototype;
496
497 proto.matches = proto.matchesSelector ||
498 proto.mozMatchesSelector ||
499 proto.msMatchesSelector ||
500 proto.oMatchesSelector ||
501 proto.webkitMatchesSelector;
502 }
503
504 /**
505 * Finds the closest parent that matches a selector.
506 *
507 * @param {Element} element
508 * @param {String} selector
509 * @return {Function}
510 */
511 function closest (element, selector) {
512 while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {
513 if (typeof element.matches === 'function' &&
514 element.matches(selector)) {
515 return element;
516 }
517 element = element.parentNode;
518 }
519 }
520
521 module.exports = closest;
522
523
524 /***/ }),
525
526 /***/ 438:
527 /***/ (function(module, __unused_webpack_exports, __nested_webpack_require_17417__) {
528
529 var closest = __nested_webpack_require_17417__(828);
530
531 /**
532 * Delegates event to a selector.
533 *
534 * @param {Element} element
535 * @param {String} selector
536 * @param {String} type
537 * @param {Function} callback
538 * @param {Boolean} useCapture
539 * @return {Object}
540 */
541 function _delegate(element, selector, type, callback, useCapture) {
542 var listenerFn = listener.apply(this, arguments);
543
544 element.addEventListener(type, listenerFn, useCapture);
545
546 return {
547 destroy: function() {
548 element.removeEventListener(type, listenerFn, useCapture);
549 }
550 }
551 }
552
553 /**
554 * Delegates event to a selector.
555 *
556 * @param {Element|String|Array} [elements]
557 * @param {String} selector
558 * @param {String} type
559 * @param {Function} callback
560 * @param {Boolean} useCapture
561 * @return {Object}
562 */
563 function delegate(elements, selector, type, callback, useCapture) {
564 // Handle the regular Element usage
565 if (typeof elements.addEventListener === 'function') {
566 return _delegate.apply(null, arguments);
567 }
568
569 // Handle Element-less usage, it defaults to global delegation
570 if (typeof type === 'function') {
571 // Use `document` as the first parameter, then apply arguments
572 // This is a short way to .unshift `arguments` without running into deoptimizations
573 return _delegate.bind(null, document).apply(null, arguments);
574 }
575
576 // Handle Selector-based usage
577 if (typeof elements === 'string') {
578 elements = document.querySelectorAll(elements);
579 }
580
581 // Handle Array-like based usage
582 return Array.prototype.map.call(elements, function (element) {
583 return _delegate(element, selector, type, callback, useCapture);
584 });
585 }
586
587 /**
588 * Finds closest match and invokes callback.
589 *
590 * @param {Element} element
591 * @param {String} selector
592 * @param {String} type
593 * @param {Function} callback
594 * @return {Function}
595 */
596 function listener(element, selector, type, callback) {
597 return function(e) {
598 e.delegateTarget = closest(e.target, selector);
599
600 if (e.delegateTarget) {
601 callback.call(element, e);
602 }
603 }
604 }
605
606 module.exports = delegate;
607
608
609 /***/ }),
610
611 /***/ 879:
612 /***/ (function(__unused_webpack_module, exports) {
613
614 /**
615 * Check if argument is a HTML element.
616 *
617 * @param {Object} value
618 * @return {Boolean}
619 */
620 exports.node = function(value) {
621 return value !== undefined
622 && value instanceof HTMLElement
623 && value.nodeType === 1;
624 };
625
626 /**
627 * Check if argument is a list of HTML elements.
628 *
629 * @param {Object} value
630 * @return {Boolean}
631 */
632 exports.nodeList = function(value) {
633 var type = Object.prototype.toString.call(value);
634
635 return value !== undefined
636 && (type === '[object NodeList]' || type === '[object HTMLCollection]')
637 && ('length' in value)
638 && (value.length === 0 || exports.node(value[0]));
639 };
640
641 /**
642 * Check if argument is a string.
643 *
644 * @param {Object} value
645 * @return {Boolean}
646 */
647 exports.string = function(value) {
648 return typeof value === 'string'
649 || value instanceof String;
650 };
651
652 /**
653 * Check if argument is a function.
654 *
655 * @param {Object} value
656 * @return {Boolean}
657 */
658 exports.fn = function(value) {
659 var type = Object.prototype.toString.call(value);
660
661 return type === '[object Function]';
662 };
663
664
665 /***/ }),
666
667 /***/ 370:
668 /***/ (function(module, __unused_webpack_exports, __nested_webpack_require_20781__) {
669
670 var is = __nested_webpack_require_20781__(879);
671 var delegate = __nested_webpack_require_20781__(438);
672
673 /**
674 * Validates all params and calls the right
675 * listener function based on its target type.
676 *
677 * @param {String|HTMLElement|HTMLCollection|NodeList} target
678 * @param {String} type
679 * @param {Function} callback
680 * @return {Object}
681 */
682 function listen(target, type, callback) {
683 if (!target && !type && !callback) {
684 throw new Error('Missing required arguments');
685 }
686
687 if (!is.string(type)) {
688 throw new TypeError('Second argument must be a String');
689 }
690
691 if (!is.fn(callback)) {
692 throw new TypeError('Third argument must be a Function');
693 }
694
695 if (is.node(target)) {
696 return listenNode(target, type, callback);
697 }
698 else if (is.nodeList(target)) {
699 return listenNodeList(target, type, callback);
700 }
701 else if (is.string(target)) {
702 return listenSelector(target, type, callback);
703 }
704 else {
705 throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');
706 }
707 }
708
709 /**
710 * Adds an event listener to a HTML element
711 * and returns a remove listener function.
712 *
713 * @param {HTMLElement} node
714 * @param {String} type
715 * @param {Function} callback
716 * @return {Object}
717 */
718 function listenNode(node, type, callback) {
719 node.addEventListener(type, callback);
720
721 return {
722 destroy: function() {
723 node.removeEventListener(type, callback);
724 }
725 }
726 }
727
728 /**
729 * Add an event listener to a list of HTML elements
730 * and returns a remove listener function.
731 *
732 * @param {NodeList|HTMLCollection} nodeList
733 * @param {String} type
734 * @param {Function} callback
735 * @return {Object}
736 */
737 function listenNodeList(nodeList, type, callback) {
738 Array.prototype.forEach.call(nodeList, function(node) {
739 node.addEventListener(type, callback);
740 });
741
742 return {
743 destroy: function() {
744 Array.prototype.forEach.call(nodeList, function(node) {
745 node.removeEventListener(type, callback);
746 });
747 }
748 }
749 }
750
751 /**
752 * Add an event listener to a selector
753 * and returns a remove listener function.
754 *
755 * @param {String} selector
756 * @param {String} type
757 * @param {Function} callback
758 * @return {Object}
759 */
760 function listenSelector(selector, type, callback) {
761 return delegate(document.body, selector, type, callback);
762 }
763
764 module.exports = listen;
765
766
767 /***/ }),
768
769 /***/ 817:
770 /***/ (function(module) {
771
772 function select(element) {
773 var selectedText;
774
775 if (element.nodeName === 'SELECT') {
776 element.focus();
777
778 selectedText = element.value;
779 }
780 else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {
781 var isReadOnly = element.hasAttribute('readonly');
782
783 if (!isReadOnly) {
784 element.setAttribute('readonly', '');
785 }
786
787 element.select();
788 element.setSelectionRange(0, element.value.length);
789
790 if (!isReadOnly) {
791 element.removeAttribute('readonly');
792 }
793
794 selectedText = element.value;
795 }
796 else {
797 if (element.hasAttribute('contenteditable')) {
798 element.focus();
799 }
800
801 var selection = window.getSelection();
802 var range = document.createRange();
803
804 range.selectNodeContents(element);
805 selection.removeAllRanges();
806 selection.addRange(range);
807
808 selectedText = selection.toString();
809 }
810
811 return selectedText;
812 }
813
814 module.exports = select;
815
816
817 /***/ }),
818
819 /***/ 279:
820 /***/ (function(module) {
821
822 function E () {
823 // Keep this empty so it's easier to inherit from
824 // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)
825 }
826
827 E.prototype = {
828 on: function (name, callback, ctx) {
829 var e = this.e || (this.e = {});
830
831 (e[name] || (e[name] = [])).push({
832 fn: callback,
833 ctx: ctx
834 });
835
836 return this;
837 },
838
839 once: function (name, callback, ctx) {
840 var self = this;
841 function listener () {
842 self.off(name, listener);
843 callback.apply(ctx, arguments);
844 };
845
846 listener._ = callback
847 return this.on(name, listener, ctx);
848 },
849
850 emit: function (name) {
851 var data = [].slice.call(arguments, 1);
852 var evtArr = ((this.e || (this.e = {}))[name] || []).slice();
853 var i = 0;
854 var len = evtArr.length;
855
856 for (i; i < len; i++) {
857 evtArr[i].fn.apply(evtArr[i].ctx, data);
858 }
859
860 return this;
861 },
862
863 off: function (name, callback) {
864 var e = this.e || (this.e = {});
865 var evts = e[name];
866 var liveEvents = [];
867
868 if (evts && callback) {
869 for (var i = 0, len = evts.length; i < len; i++) {
870 if (evts[i].fn !== callback && evts[i].fn._ !== callback)
871 liveEvents.push(evts[i]);
872 }
873 }
874
875 // Remove event from queue to prevent memory leak
876 // Suggested by https://github.com/lazd
877 // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910
878
879 (liveEvents.length)
880 ? e[name] = liveEvents
881 : delete e[name];
882
883 return this;
884 }
885 };
886
887 module.exports = E;
888 module.exports.TinyEmitter = E;
889
890
891 /***/ })
892
893 /******/ });
894 /************************************************************************/
895 /******/ // The module cache
896 /******/ var __webpack_module_cache__ = {};
897 /******/
898 /******/ // The require function
899 /******/ function __nested_webpack_require_26163__(moduleId) {
900 /******/ // Check if module is in cache
901 /******/ if(__webpack_module_cache__[moduleId]) {
902 /******/ return __webpack_module_cache__[moduleId].exports;
903 /******/ }
904 /******/ // Create a new module (and put it into the cache)
905 /******/ var module = __webpack_module_cache__[moduleId] = {
906 /******/ // no module.id needed
907 /******/ // no module.loaded needed
908 /******/ exports: {}
909 /******/ };
910 /******/
911 /******/ // Execute the module function
912 /******/ __webpack_modules__[moduleId](module, module.exports, __nested_webpack_require_26163__);
913 /******/
914 /******/ // Return the exports of the module
915 /******/ return module.exports;
916 /******/ }
917 /******/
918 /************************************************************************/
919 /******/ /* webpack/runtime/compat get default export */
920 /******/ !function() {
921 /******/ // getDefaultExport function for compatibility with non-harmony modules
922 /******/ __nested_webpack_require_26163__.n = function(module) {
923 /******/ var getter = module && module.__esModule ?
924 /******/ function() { return module['default']; } :
925 /******/ function() { return module; };
926 /******/ __nested_webpack_require_26163__.d(getter, { a: getter });
927 /******/ return getter;
928 /******/ };
929 /******/ }();
930 /******/
931 /******/ /* webpack/runtime/define property getters */
932 /******/ !function() {
933 /******/ // define getter functions for harmony exports
934 /******/ __nested_webpack_require_26163__.d = function(exports, definition) {
935 /******/ for(var key in definition) {
936 /******/ if(__nested_webpack_require_26163__.o(definition, key) && !__nested_webpack_require_26163__.o(exports, key)) {
937 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
938 /******/ }
939 /******/ }
940 /******/ };
941 /******/ }();
942 /******/
943 /******/ /* webpack/runtime/hasOwnProperty shorthand */
944 /******/ !function() {
945 /******/ __nested_webpack_require_26163__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
946 /******/ }();
947 /******/
948 /************************************************************************/
949 /******/ // module exports must be returned from runtime so entry inlining is disabled
950 /******/ // startup
951 /******/ // Load entry module and return exports
952 /******/ return __nested_webpack_require_26163__(134);
953 /******/ })()
954 .default;
955 });
956
957 /***/ }),
958
959 /***/ 7973:
960 /***/ (function(module, exports, __webpack_require__) {
961
962 var __WEBPACK_AMD_DEFINE_RESULT__;/*global define:false */
963 /**
964 * Copyright 2012-2017 Craig Campbell
965 *
966 * Licensed under the Apache License, Version 2.0 (the "License");
967 * you may not use this file except in compliance with the License.
968 * You may obtain a copy of the License at
969 *
970 * http://www.apache.org/licenses/LICENSE-2.0
971 *
972 * Unless required by applicable law or agreed to in writing, software
973 * distributed under the License is distributed on an "AS IS" BASIS,
974 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
975 * See the License for the specific language governing permissions and
976 * limitations under the License.
977 *
978 * Mousetrap is a simple keyboard shortcut library for Javascript with
979 * no external dependencies
980 *
981 * @version 1.6.5
982 * @url craig.is/killing/mice
983 */
984 (function(window, document, undefined) {
985
986 // Check if mousetrap is used inside browser, if not, return
987 if (!window) {
988 return;
989 }
990
991 /**
992 * mapping of special keycodes to their corresponding keys
993 *
994 * everything in this dictionary cannot use keypress events
995 * so it has to be here to map to the correct keycodes for
996 * keyup/keydown events
997 *
998 * @type {Object}
999 */
1000 var _MAP = {
1001 8: 'backspace',
1002 9: 'tab',
1003 13: 'enter',
1004 16: 'shift',
1005 17: 'ctrl',
1006 18: 'alt',
1007 20: 'capslock',
1008 27: 'esc',
1009 32: 'space',
1010 33: 'pageup',
1011 34: 'pagedown',
1012 35: 'end',
1013 36: 'home',
1014 37: 'left',
1015 38: 'up',
1016 39: 'right',
1017 40: 'down',
1018 45: 'ins',
1019 46: 'del',
1020 91: 'meta',
1021 93: 'meta',
1022 224: 'meta'
1023 };
1024
1025 /**
1026 * mapping for special characters so they can support
1027 *
1028 * this dictionary is only used incase you want to bind a
1029 * keyup or keydown event to one of these keys
1030 *
1031 * @type {Object}
1032 */
1033 var _KEYCODE_MAP = {
1034 106: '*',
1035 107: '+',
1036 109: '-',
1037 110: '.',
1038 111 : '/',
1039 186: ';',
1040 187: '=',
1041 188: ',',
1042 189: '-',
1043 190: '.',
1044 191: '/',
1045 192: '`',
1046 219: '[',
1047 220: '\\',
1048 221: ']',
1049 222: '\''
1050 };
1051
1052 /**
1053 * this is a mapping of keys that require shift on a US keypad
1054 * back to the non shift equivelents
1055 *
1056 * this is so you can use keyup events with these keys
1057 *
1058 * note that this will only work reliably on US keyboards
1059 *
1060 * @type {Object}
1061 */
1062 var _SHIFT_MAP = {
1063 '~': '`',
1064 '!': '1',
1065 '@': '2',
1066 '#': '3',
1067 '$': '4',
1068 '%': '5',
1069 '^': '6',
1070 '&': '7',
1071 '*': '8',
1072 '(': '9',
1073 ')': '0',
1074 '_': '-',
1075 '+': '=',
1076 ':': ';',
1077 '\"': '\'',
1078 '<': ',',
1079 '>': '.',
1080 '?': '/',
1081 '|': '\\'
1082 };
1083
1084 /**
1085 * this is a list of special strings you can use to map
1086 * to modifier keys when you specify your keyboard shortcuts
1087 *
1088 * @type {Object}
1089 */
1090 var _SPECIAL_ALIASES = {
1091 'option': 'alt',
1092 'command': 'meta',
1093 'return': 'enter',
1094 'escape': 'esc',
1095 'plus': '+',
1096 'mod': /Mac|iPod|iPhone|iPad/.test(navigator.platform) ? 'meta' : 'ctrl'
1097 };
1098
1099 /**
1100 * variable to store the flipped version of _MAP from above
1101 * needed to check if we should use keypress or not when no action
1102 * is specified
1103 *
1104 * @type {Object|undefined}
1105 */
1106 var _REVERSE_MAP;
1107
1108 /**
1109 * loop through the f keys, f1 to f19 and add them to the map
1110 * programatically
1111 */
1112 for (var i = 1; i < 20; ++i) {
1113 _MAP[111 + i] = 'f' + i;
1114 }
1115
1116 /**
1117 * loop through to map numbers on the numeric keypad
1118 */
1119 for (i = 0; i <= 9; ++i) {
1120
1121 // This needs to use a string cause otherwise since 0 is falsey
1122 // mousetrap will never fire for numpad 0 pressed as part of a keydown
1123 // event.
1124 //
1125 // @see https://github.com/ccampbell/mousetrap/pull/258
1126 _MAP[i + 96] = i.toString();
1127 }
1128
1129 /**
1130 * cross browser add event method
1131 *
1132 * @param {Element|HTMLDocument} object
1133 * @param {string} type
1134 * @param {Function} callback
1135 * @returns void
1136 */
1137 function _addEvent(object, type, callback) {
1138 if (object.addEventListener) {
1139 object.addEventListener(type, callback, false);
1140 return;
1141 }
1142
1143 object.attachEvent('on' + type, callback);
1144 }
1145
1146 /**
1147 * takes the event and returns the key character
1148 *
1149 * @param {Event} e
1150 * @return {string}
1151 */
1152 function _characterFromEvent(e) {
1153
1154 // for keypress events we should return the character as is
1155 if (e.type == 'keypress') {
1156 var character = String.fromCharCode(e.which);
1157
1158 // if the shift key is not pressed then it is safe to assume
1159 // that we want the character to be lowercase. this means if
1160 // you accidentally have caps lock on then your key bindings
1161 // will continue to work
1162 //
1163 // the only side effect that might not be desired is if you
1164 // bind something like 'A' cause you want to trigger an
1165 // event when capital A is pressed caps lock will no longer
1166 // trigger the event. shift+a will though.
1167 if (!e.shiftKey) {
1168 character = character.toLowerCase();
1169 }
1170
1171 return character;
1172 }
1173
1174 // for non keypress events the special maps are needed
1175 if (_MAP[e.which]) {
1176 return _MAP[e.which];
1177 }
1178
1179 if (_KEYCODE_MAP[e.which]) {
1180 return _KEYCODE_MAP[e.which];
1181 }
1182
1183 // if it is not in the special map
1184
1185 // with keydown and keyup events the character seems to always
1186 // come in as an uppercase character whether you are pressing shift
1187 // or not. we should make sure it is always lowercase for comparisons
1188 return String.fromCharCode(e.which).toLowerCase();
1189 }
1190
1191 /**
1192 * checks if two arrays are equal
1193 *
1194 * @param {Array} modifiers1
1195 * @param {Array} modifiers2
1196 * @returns {boolean}
1197 */
1198 function _modifiersMatch(modifiers1, modifiers2) {
1199 return modifiers1.sort().join(',') === modifiers2.sort().join(',');
1200 }
1201
1202 /**
1203 * takes a key event and figures out what the modifiers are
1204 *
1205 * @param {Event} e
1206 * @returns {Array}
1207 */
1208 function _eventModifiers(e) {
1209 var modifiers = [];
1210
1211 if (e.shiftKey) {
1212 modifiers.push('shift');
1213 }
1214
1215 if (e.altKey) {
1216 modifiers.push('alt');
1217 }
1218
1219 if (e.ctrlKey) {
1220 modifiers.push('ctrl');
1221 }
1222
1223 if (e.metaKey) {
1224 modifiers.push('meta');
1225 }
1226
1227 return modifiers;
1228 }
1229
1230 /**
1231 * prevents default for this event
1232 *
1233 * @param {Event} e
1234 * @returns void
1235 */
1236 function _preventDefault(e) {
1237 if (e.preventDefault) {
1238 e.preventDefault();
1239 return;
1240 }
1241
1242 e.returnValue = false;
1243 }
1244
1245 /**
1246 * stops propogation for this event
1247 *
1248 * @param {Event} e
1249 * @returns void
1250 */
1251 function _stopPropagation(e) {
1252 if (e.stopPropagation) {
1253 e.stopPropagation();
1254 return;
1255 }
1256
1257 e.cancelBubble = true;
1258 }
1259
1260 /**
1261 * determines if the keycode specified is a modifier key or not
1262 *
1263 * @param {string} key
1264 * @returns {boolean}
1265 */
1266 function _isModifier(key) {
1267 return key == 'shift' || key == 'ctrl' || key == 'alt' || key == 'meta';
1268 }
1269
1270 /**
1271 * reverses the map lookup so that we can look for specific keys
1272 * to see what can and can't use keypress
1273 *
1274 * @return {Object}
1275 */
1276 function _getReverseMap() {
1277 if (!_REVERSE_MAP) {
1278 _REVERSE_MAP = {};
1279 for (var key in _MAP) {
1280
1281 // pull out the numeric keypad from here cause keypress should
1282 // be able to detect the keys from the character
1283 if (key > 95 && key < 112) {
1284 continue;
1285 }
1286
1287 if (_MAP.hasOwnProperty(key)) {
1288 _REVERSE_MAP[_MAP[key]] = key;
1289 }
1290 }
1291 }
1292 return _REVERSE_MAP;
1293 }
1294
1295 /**
1296 * picks the best action based on the key combination
1297 *
1298 * @param {string} key - character for key
1299 * @param {Array} modifiers
1300 * @param {string=} action passed in
1301 */
1302 function _pickBestAction(key, modifiers, action) {
1303
1304 // if no action was picked in we should try to pick the one
1305 // that we think would work best for this key
1306 if (!action) {
1307 action = _getReverseMap()[key] ? 'keydown' : 'keypress';
1308 }
1309
1310 // modifier keys don't work as expected with keypress,
1311 // switch to keydown
1312 if (action == 'keypress' && modifiers.length) {
1313 action = 'keydown';
1314 }
1315
1316 return action;
1317 }
1318
1319 /**
1320 * Converts from a string key combination to an array
1321 *
1322 * @param {string} combination like "command+shift+l"
1323 * @return {Array}
1324 */
1325 function _keysFromString(combination) {
1326 if (combination === '+') {
1327 return ['+'];
1328 }
1329
1330 combination = combination.replace(/\+{2}/g, '+plus');
1331 return combination.split('+');
1332 }
1333
1334 /**
1335 * Gets info for a specific key combination
1336 *
1337 * @param {string} combination key combination ("command+s" or "a" or "*")
1338 * @param {string=} action
1339 * @returns {Object}
1340 */
1341 function _getKeyInfo(combination, action) {
1342 var keys;
1343 var key;
1344 var i;
1345 var modifiers = [];
1346
1347 // take the keys from this pattern and figure out what the actual
1348 // pattern is all about
1349 keys = _keysFromString(combination);
1350
1351 for (i = 0; i < keys.length; ++i) {
1352 key = keys[i];
1353
1354 // normalize key names
1355 if (_SPECIAL_ALIASES[key]) {
1356 key = _SPECIAL_ALIASES[key];
1357 }
1358
1359 // if this is not a keypress event then we should
1360 // be smart about using shift keys
1361 // this will only work for US keyboards however
1362 if (action && action != 'keypress' && _SHIFT_MAP[key]) {
1363 key = _SHIFT_MAP[key];
1364 modifiers.push('shift');
1365 }
1366
1367 // if this key is a modifier then add it to the list of modifiers
1368 if (_isModifier(key)) {
1369 modifiers.push(key);
1370 }
1371 }
1372
1373 // depending on what the key combination is
1374 // we will try to pick the best event for it
1375 action = _pickBestAction(key, modifiers, action);
1376
1377 return {
1378 key: key,
1379 modifiers: modifiers,
1380 action: action
1381 };
1382 }
1383
1384 function _belongsTo(element, ancestor) {
1385 if (element === null || element === document) {
1386 return false;
1387 }
1388
1389 if (element === ancestor) {
1390 return true;
1391 }
1392
1393 return _belongsTo(element.parentNode, ancestor);
1394 }
1395
1396 function Mousetrap(targetElement) {
1397 var self = this;
1398
1399 targetElement = targetElement || document;
1400
1401 if (!(self instanceof Mousetrap)) {
1402 return new Mousetrap(targetElement);
1403 }
1404
1405 /**
1406 * element to attach key events to
1407 *
1408 * @type {Element}
1409 */
1410 self.target = targetElement;
1411
1412 /**
1413 * a list of all the callbacks setup via Mousetrap.bind()
1414 *
1415 * @type {Object}
1416 */
1417 self._callbacks = {};
1418
1419 /**
1420 * direct map of string combinations to callbacks used for trigger()
1421 *
1422 * @type {Object}
1423 */
1424 self._directMap = {};
1425
1426 /**
1427 * keeps track of what level each sequence is at since multiple
1428 * sequences can start out with the same sequence
1429 *
1430 * @type {Object}
1431 */
1432 var _sequenceLevels = {};
1433
1434 /**
1435 * variable to store the setTimeout call
1436 *
1437 * @type {null|number}
1438 */
1439 var _resetTimer;
1440
1441 /**
1442 * temporary state where we will ignore the next keyup
1443 *
1444 * @type {boolean|string}
1445 */
1446 var _ignoreNextKeyup = false;
1447
1448 /**
1449 * temporary state where we will ignore the next keypress
1450 *
1451 * @type {boolean}
1452 */
1453 var _ignoreNextKeypress = false;
1454
1455 /**
1456 * are we currently inside of a sequence?
1457 * type of action ("keyup" or "keydown" or "keypress") or false
1458 *
1459 * @type {boolean|string}
1460 */
1461 var _nextExpectedAction = false;
1462
1463 /**
1464 * resets all sequence counters except for the ones passed in
1465 *
1466 * @param {Object} doNotReset
1467 * @returns void
1468 */
1469 function _resetSequences(doNotReset) {
1470 doNotReset = doNotReset || {};
1471
1472 var activeSequences = false,
1473 key;
1474
1475 for (key in _sequenceLevels) {
1476 if (doNotReset[key]) {
1477 activeSequences = true;
1478 continue;
1479 }
1480 _sequenceLevels[key] = 0;
1481 }
1482
1483 if (!activeSequences) {
1484 _nextExpectedAction = false;
1485 }
1486 }
1487
1488 /**
1489 * finds all callbacks that match based on the keycode, modifiers,
1490 * and action
1491 *
1492 * @param {string} character
1493 * @param {Array} modifiers
1494 * @param {Event|Object} e
1495 * @param {string=} sequenceName - name of the sequence we are looking for
1496 * @param {string=} combination
1497 * @param {number=} level
1498 * @returns {Array}
1499 */
1500 function _getMatches(character, modifiers, e, sequenceName, combination, level) {
1501 var i;
1502 var callback;
1503 var matches = [];
1504 var action = e.type;
1505
1506 // if there are no events related to this keycode
1507 if (!self._callbacks[character]) {
1508 return [];
1509 }
1510
1511 // if a modifier key is coming up on its own we should allow it
1512 if (action == 'keyup' && _isModifier(character)) {
1513 modifiers = [character];
1514 }
1515
1516 // loop through all callbacks for the key that was pressed
1517 // and see if any of them match
1518 for (i = 0; i < self._callbacks[character].length; ++i) {
1519 callback = self._callbacks[character][i];
1520
1521 // if a sequence name is not specified, but this is a sequence at
1522 // the wrong level then move onto the next match
1523 if (!sequenceName && callback.seq && _sequenceLevels[callback.seq] != callback.level) {
1524 continue;
1525 }
1526
1527 // if the action we are looking for doesn't match the action we got
1528 // then we should keep going
1529 if (action != callback.action) {
1530 continue;
1531 }
1532
1533 // if this is a keypress event and the meta key and control key
1534 // are not pressed that means that we need to only look at the
1535 // character, otherwise check the modifiers as well
1536 //
1537 // chrome will not fire a keypress if meta or control is down
1538 // safari will fire a keypress if meta or meta+shift is down
1539 // firefox will fire a keypress if meta or control is down
1540 if ((action == 'keypress' && !e.metaKey && !e.ctrlKey) || _modifiersMatch(modifiers, callback.modifiers)) {
1541
1542 // when you bind a combination or sequence a second time it
1543 // should overwrite the first one. if a sequenceName or
1544 // combination is specified in this call it does just that
1545 //
1546 // @todo make deleting its own method?
1547 var deleteCombo = !sequenceName && callback.combo == combination;
1548 var deleteSequence = sequenceName && callback.seq == sequenceName && callback.level == level;
1549 if (deleteCombo || deleteSequence) {
1550 self._callbacks[character].splice(i, 1);
1551 }
1552
1553 matches.push(callback);
1554 }
1555 }
1556
1557 return matches;
1558 }
1559
1560 /**
1561 * actually calls the callback function
1562 *
1563 * if your callback function returns false this will use the jquery
1564 * convention - prevent default and stop propogation on the event
1565 *
1566 * @param {Function} callback
1567 * @param {Event} e
1568 * @returns void
1569 */
1570 function _fireCallback(callback, e, combo, sequence) {
1571
1572 // if this event should not happen stop here
1573 if (self.stopCallback(e, e.target || e.srcElement, combo, sequence)) {
1574 return;
1575 }
1576
1577 if (callback(e, combo) === false) {
1578 _preventDefault(e);
1579 _stopPropagation(e);
1580 }
1581 }
1582
1583 /**
1584 * handles a character key event
1585 *
1586 * @param {string} character
1587 * @param {Array} modifiers
1588 * @param {Event} e
1589 * @returns void
1590 */
1591 self._handleKey = function(character, modifiers, e) {
1592 var callbacks = _getMatches(character, modifiers, e);
1593 var i;
1594 var doNotReset = {};
1595 var maxLevel = 0;
1596 var processedSequenceCallback = false;
1597
1598 // Calculate the maxLevel for sequences so we can only execute the longest callback sequence
1599 for (i = 0; i < callbacks.length; ++i) {
1600 if (callbacks[i].seq) {
1601 maxLevel = Math.max(maxLevel, callbacks[i].level);
1602 }
1603 }
1604
1605 // loop through matching callbacks for this key event
1606 for (i = 0; i < callbacks.length; ++i) {
1607
1608 // fire for all sequence callbacks
1609 // this is because if for example you have multiple sequences
1610 // bound such as "g i" and "g t" they both need to fire the
1611 // callback for matching g cause otherwise you can only ever
1612 // match the first one
1613 if (callbacks[i].seq) {
1614
1615 // only fire callbacks for the maxLevel to prevent
1616 // subsequences from also firing
1617 //
1618 // for example 'a option b' should not cause 'option b' to fire
1619 // even though 'option b' is part of the other sequence
1620 //
1621 // any sequences that do not match here will be discarded
1622 // below by the _resetSequences call
1623 if (callbacks[i].level != maxLevel) {
1624 continue;
1625 }
1626
1627 processedSequenceCallback = true;
1628
1629 // keep a list of which sequences were matches for later
1630 doNotReset[callbacks[i].seq] = 1;
1631 _fireCallback(callbacks[i].callback, e, callbacks[i].combo, callbacks[i].seq);
1632 continue;
1633 }
1634
1635 // if there were no sequence matches but we are still here
1636 // that means this is a regular match so we should fire that
1637 if (!processedSequenceCallback) {
1638 _fireCallback(callbacks[i].callback, e, callbacks[i].combo);
1639 }
1640 }
1641
1642 // if the key you pressed matches the type of sequence without
1643 // being a modifier (ie "keyup" or "keypress") then we should
1644 // reset all sequences that were not matched by this event
1645 //
1646 // this is so, for example, if you have the sequence "h a t" and you
1647 // type "h e a r t" it does not match. in this case the "e" will
1648 // cause the sequence to reset
1649 //
1650 // modifier keys are ignored because you can have a sequence
1651 // that contains modifiers such as "enter ctrl+space" and in most
1652 // cases the modifier key will be pressed before the next key
1653 //
1654 // also if you have a sequence such as "ctrl+b a" then pressing the
1655 // "b" key will trigger a "keypress" and a "keydown"
1656 //
1657 // the "keydown" is expected when there is a modifier, but the
1658 // "keypress" ends up matching the _nextExpectedAction since it occurs
1659 // after and that causes the sequence to reset
1660 //
1661 // we ignore keypresses in a sequence that directly follow a keydown
1662 // for the same character
1663 var ignoreThisKeypress = e.type == 'keypress' && _ignoreNextKeypress;
1664 if (e.type == _nextExpectedAction && !_isModifier(character) && !ignoreThisKeypress) {
1665 _resetSequences(doNotReset);
1666 }
1667
1668 _ignoreNextKeypress = processedSequenceCallback && e.type == 'keydown';
1669 };
1670
1671 /**
1672 * handles a keydown event
1673 *
1674 * @param {Event} e
1675 * @returns void
1676 */
1677 function _handleKeyEvent(e) {
1678
1679 // normalize e.which for key events
1680 // @see http://stackoverflow.com/questions/4285627/javascript-keycode-vs-charcode-utter-confusion
1681 if (typeof e.which !== 'number') {
1682 e.which = e.keyCode;
1683 }
1684
1685 var character = _characterFromEvent(e);
1686
1687 // no character found then stop
1688 if (!character) {
1689 return;
1690 }
1691
1692 // need to use === for the character check because the character can be 0
1693 if (e.type == 'keyup' && _ignoreNextKeyup === character) {
1694 _ignoreNextKeyup = false;
1695 return;
1696 }
1697
1698 self.handleKey(character, _eventModifiers(e), e);
1699 }
1700
1701 /**
1702 * called to set a 1 second timeout on the specified sequence
1703 *
1704 * this is so after each key press in the sequence you have 1 second
1705 * to press the next key before you have to start over
1706 *
1707 * @returns void
1708 */
1709 function _resetSequenceTimer() {
1710 clearTimeout(_resetTimer);
1711 _resetTimer = setTimeout(_resetSequences, 1000);
1712 }
1713
1714 /**
1715 * binds a key sequence to an event
1716 *
1717 * @param {string} combo - combo specified in bind call
1718 * @param {Array} keys
1719 * @param {Function} callback
1720 * @param {string=} action
1721 * @returns void
1722 */
1723 function _bindSequence(combo, keys, callback, action) {
1724
1725 // start off by adding a sequence level record for this combination
1726 // and setting the level to 0
1727 _sequenceLevels[combo] = 0;
1728
1729 /**
1730 * callback to increase the sequence level for this sequence and reset
1731 * all other sequences that were active
1732 *
1733 * @param {string} nextAction
1734 * @returns {Function}
1735 */
1736 function _increaseSequence(nextAction) {
1737 return function() {
1738 _nextExpectedAction = nextAction;
1739 ++_sequenceLevels[combo];
1740 _resetSequenceTimer();
1741 };
1742 }
1743
1744 /**
1745 * wraps the specified callback inside of another function in order
1746 * to reset all sequence counters as soon as this sequence is done
1747 *
1748 * @param {Event} e
1749 * @returns void
1750 */
1751 function _callbackAndReset(e) {
1752 _fireCallback(callback, e, combo);
1753
1754 // we should ignore the next key up if the action is key down
1755 // or keypress. this is so if you finish a sequence and
1756 // release the key the final key will not trigger a keyup
1757 if (action !== 'keyup') {
1758 _ignoreNextKeyup = _characterFromEvent(e);
1759 }
1760
1761 // weird race condition if a sequence ends with the key
1762 // another sequence begins with
1763 setTimeout(_resetSequences, 10);
1764 }
1765
1766 // loop through keys one at a time and bind the appropriate callback
1767 // function. for any key leading up to the final one it should
1768 // increase the sequence. after the final, it should reset all sequences
1769 //
1770 // if an action is specified in the original bind call then that will
1771 // be used throughout. otherwise we will pass the action that the
1772 // next key in the sequence should match. this allows a sequence
1773 // to mix and match keypress and keydown events depending on which
1774 // ones are better suited to the key provided
1775 for (var i = 0; i < keys.length; ++i) {
1776 var isFinal = i + 1 === keys.length;
1777 var wrappedCallback = isFinal ? _callbackAndReset : _increaseSequence(action || _getKeyInfo(keys[i + 1]).action);
1778 _bindSingle(keys[i], wrappedCallback, action, combo, i);
1779 }
1780 }
1781
1782 /**
1783 * binds a single keyboard combination
1784 *
1785 * @param {string} combination
1786 * @param {Function} callback
1787 * @param {string=} action
1788 * @param {string=} sequenceName - name of sequence if part of sequence
1789 * @param {number=} level - what part of the sequence the command is
1790 * @returns void
1791 */
1792 function _bindSingle(combination, callback, action, sequenceName, level) {
1793
1794 // store a direct mapped reference for use with Mousetrap.trigger
1795 self._directMap[combination + ':' + action] = callback;
1796
1797 // make sure multiple spaces in a row become a single space
1798 combination = combination.replace(/\s+/g, ' ');
1799
1800 var sequence = combination.split(' ');
1801 var info;
1802
1803 // if this pattern is a sequence of keys then run through this method
1804 // to reprocess each pattern one key at a time
1805 if (sequence.length > 1) {
1806 _bindSequence(combination, sequence, callback, action);
1807 return;
1808 }
1809
1810 info = _getKeyInfo(combination, action);
1811
1812 // make sure to initialize array if this is the first time
1813 // a callback is added for this key
1814 self._callbacks[info.key] = self._callbacks[info.key] || [];
1815
1816 // remove an existing match if there is one
1817 _getMatches(info.key, info.modifiers, {type: info.action}, sequenceName, combination, level);
1818
1819 // add this call back to the array
1820 // if it is a sequence put it at the beginning
1821 // if not put it at the end
1822 //
1823 // this is important because the way these are processed expects
1824 // the sequence ones to come first
1825 self._callbacks[info.key][sequenceName ? 'unshift' : 'push']({
1826 callback: callback,
1827 modifiers: info.modifiers,
1828 action: info.action,
1829 seq: sequenceName,
1830 level: level,
1831 combo: combination
1832 });
1833 }
1834
1835 /**
1836 * binds multiple combinations to the same callback
1837 *
1838 * @param {Array} combinations
1839 * @param {Function} callback
1840 * @param {string|undefined} action
1841 * @returns void
1842 */
1843 self._bindMultiple = function(combinations, callback, action) {
1844 for (var i = 0; i < combinations.length; ++i) {
1845 _bindSingle(combinations[i], callback, action);
1846 }
1847 };
1848
1849 // start!
1850 _addEvent(targetElement, 'keypress', _handleKeyEvent);
1851 _addEvent(targetElement, 'keydown', _handleKeyEvent);
1852 _addEvent(targetElement, 'keyup', _handleKeyEvent);
1853 }
1854
1855 /**
1856 * binds an event to mousetrap
1857 *
1858 * can be a single key, a combination of keys separated with +,
1859 * an array of keys, or a sequence of keys separated by spaces
1860 *
1861 * be sure to list the modifier keys first to make sure that the
1862 * correct key ends up getting bound (the last key in the pattern)
1863 *
1864 * @param {string|Array} keys
1865 * @param {Function} callback
1866 * @param {string=} action - 'keypress', 'keydown', or 'keyup'
1867 * @returns void
1868 */
1869 Mousetrap.prototype.bind = function(keys, callback, action) {
1870 var self = this;
1871 keys = keys instanceof Array ? keys : [keys];
1872 self._bindMultiple.call(self, keys, callback, action);
1873 return self;
1874 };
1875
1876 /**
1877 * unbinds an event to mousetrap
1878 *
1879 * the unbinding sets the callback function of the specified key combo
1880 * to an empty function and deletes the corresponding key in the
1881 * _directMap dict.
1882 *
1883 * TODO: actually remove this from the _callbacks dictionary instead
1884 * of binding an empty function
1885 *
1886 * the keycombo+action has to be exactly the same as
1887 * it was defined in the bind method
1888 *
1889 * @param {string|Array} keys
1890 * @param {string} action
1891 * @returns void
1892 */
1893 Mousetrap.prototype.unbind = function(keys, action) {
1894 var self = this;
1895 return self.bind.call(self, keys, function() {}, action);
1896 };
1897
1898 /**
1899 * triggers an event that has already been bound
1900 *
1901 * @param {string} keys
1902 * @param {string=} action
1903 * @returns void
1904 */
1905 Mousetrap.prototype.trigger = function(keys, action) {
1906 var self = this;
1907 if (self._directMap[keys + ':' + action]) {
1908 self._directMap[keys + ':' + action]({}, keys);
1909 }
1910 return self;
1911 };
1912
1913 /**
1914 * resets the library back to its initial state. this is useful
1915 * if you want to clear out the current keyboard shortcuts and bind
1916 * new ones - for example if you switch to another page
1917 *
1918 * @returns void
1919 */
1920 Mousetrap.prototype.reset = function() {
1921 var self = this;
1922 self._callbacks = {};
1923 self._directMap = {};
1924 return self;
1925 };
1926
1927 /**
1928 * should we stop this event before firing off callbacks
1929 *
1930 * @param {Event} e
1931 * @param {Element} element
1932 * @return {boolean}
1933 */
1934 Mousetrap.prototype.stopCallback = function(e, element) {
1935 var self = this;
1936
1937 // if the element has the class "mousetrap" then no need to stop
1938 if ((' ' + element.className + ' ').indexOf(' mousetrap ') > -1) {
1939 return false;
1940 }
1941
1942 if (_belongsTo(element, self.target)) {
1943 return false;
1944 }
1945
1946 // Events originating from a shadow DOM are re-targetted and `e.target` is the shadow host,
1947 // not the initial event target in the shadow tree. Note that not all events cross the
1948 // shadow boundary.
1949 // For shadow trees with `mode: 'open'`, the initial event target is the first element in
1950 // the event’s composed path. For shadow trees with `mode: 'closed'`, the initial event
1951 // target cannot be obtained.
1952 if ('composedPath' in e && typeof e.composedPath === 'function') {
1953 // For open shadow trees, update `element` so that the following check works.
1954 var initialEventTarget = e.composedPath()[0];
1955 if (initialEventTarget !== e.target) {
1956 element = initialEventTarget;
1957 }
1958 }
1959
1960 // stop for input, select, and textarea
1961 return element.tagName == 'INPUT' || element.tagName == 'SELECT' || element.tagName == 'TEXTAREA' || element.isContentEditable;
1962 };
1963
1964 /**
1965 * exposes _handleKey publicly so it can be overwritten by extensions
1966 */
1967 Mousetrap.prototype.handleKey = function() {
1968 var self = this;
1969 return self._handleKey.apply(self, arguments);
1970 };
1971
1972 /**
1973 * allow custom key mappings
1974 */
1975 Mousetrap.addKeycodes = function(object) {
1976 for (var key in object) {
1977 if (object.hasOwnProperty(key)) {
1978 _MAP[key] = object[key];
1979 }
1980 }
1981 _REVERSE_MAP = null;
1982 };
1983
1984 /**
1985 * Init the global mousetrap functions
1986 *
1987 * This method is needed to allow the global mousetrap functions to work
1988 * now that mousetrap is a constructor function.
1989 */
1990 Mousetrap.init = function() {
1991 var documentMousetrap = Mousetrap(document);
1992 for (var method in documentMousetrap) {
1993 if (method.charAt(0) !== '_') {
1994 Mousetrap[method] = (function(method) {
1995 return function() {
1996 return documentMousetrap[method].apply(documentMousetrap, arguments);
1997 };
1998 } (method));
1999 }
2000 }
2001 };
2002
2003 Mousetrap.init();
2004
2005 // expose mousetrap to the global object
2006 window.Mousetrap = Mousetrap;
2007
2008 // expose as a common js module
2009 if ( true && module.exports) {
2010 module.exports = Mousetrap;
2011 }
2012
2013 // expose mousetrap as an AMD module
2014 if (true) {
2015 !(__WEBPACK_AMD_DEFINE_RESULT__ = (function() {
2016 return Mousetrap;
2017 }).call(exports, __webpack_require__, exports, module),
2018 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
2019 }
2020 }) (typeof window !== 'undefined' ? window : null, typeof window !== 'undefined' ? document : null);
2021
2022
2023 /***/ }),
2024
2025 /***/ 5538:
2026 /***/ (function() {
2027
2028 /**
2029 * adds a bindGlobal method to Mousetrap that allows you to
2030 * bind specific keyboard shortcuts that will still work
2031 * inside a text input field
2032 *
2033 * usage:
2034 * Mousetrap.bindGlobal('ctrl+s', _saveChanges);
2035 */
2036 /* global Mousetrap:true */
2037 (function(Mousetrap) {
2038 if (! Mousetrap) {
2039 return;
2040 }
2041 var _globalCallbacks = {};
2042 var _originalStopCallback = Mousetrap.prototype.stopCallback;
2043
2044 Mousetrap.prototype.stopCallback = function(e, element, combo, sequence) {
2045 var self = this;
2046
2047 if (self.paused) {
2048 return true;
2049 }
2050
2051 if (_globalCallbacks[combo] || _globalCallbacks[sequence]) {
2052 return false;
2053 }
2054
2055 return _originalStopCallback.call(self, e, element, combo);
2056 };
2057
2058 Mousetrap.prototype.bindGlobal = function(keys, callback, action) {
2059 var self = this;
2060 self.bind(keys, callback, action);
2061
2062 if (keys instanceof Array) {
2063 for (var i = 0; i < keys.length; i++) {
2064 _globalCallbacks[keys[i]] = true;
2065 }
2066 return;
2067 }
2068
2069 _globalCallbacks[keys] = true;
2070 };
2071
2072 Mousetrap.init();
2073 }) (typeof Mousetrap !== "undefined" ? Mousetrap : undefined);
2074
2075
2076 /***/ }),
2077
2078 /***/ 235:
2079 /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
2080
2081 var e=__webpack_require__(9196),n={display:"block",opacity:0,position:"absolute",top:0,left:0,height:"100%",width:"100%",overflow:"hidden",pointerEvents:"none",zIndex:-1},t=function(t){var r=t.onResize,u=e.useRef();return function(n,t){var r=function(){return n.current&&n.current.contentDocument&&n.current.contentDocument.defaultView};function u(){t();var e=r();e&&e.addEventListener("resize",t)}e.useEffect((function(){return r()?u():n.current&&n.current.addEventListener&&n.current.addEventListener("load",u),function(){var e=r();e&&"function"==typeof e.removeEventListener&&e.removeEventListener("resize",t)}}),[])}(u,(function(){return r(u)})),e.createElement("iframe",{style:n,src:"about:blank",ref:u,"aria-hidden":!0,tabIndex:-1,frameBorder:0})},r=function(e){return{width:null!=e?e.offsetWidth:null,height:null!=e?e.offsetHeight:null}};module.exports=function(n){void 0===n&&(n=r);var u=e.useState(n(null)),o=u[0],i=u[1],c=e.useCallback((function(e){return i(n(e.current))}),[n]);return[e.useMemo((function(){return e.createElement(t,{onResize:c})}),[c]),o]};
2082
2083
2084 /***/ }),
2085
2086 /***/ 9196:
2087 /***/ (function(module) {
2088
2089 "use strict";
2090 module.exports = window["React"];
2091
2092 /***/ })
2093
2094 /******/ });
2095 /************************************************************************/
2096 /******/ // The module cache
2097 /******/ var __webpack_module_cache__ = {};
2098 /******/
2099 /******/ // The require function
2100 /******/ function __webpack_require__(moduleId) {
2101 /******/ // Check if module is in cache
2102 /******/ var cachedModule = __webpack_module_cache__[moduleId];
2103 /******/ if (cachedModule !== undefined) {
2104 /******/ return cachedModule.exports;
2105 /******/ }
2106 /******/ // Create a new module (and put it into the cache)
2107 /******/ var module = __webpack_module_cache__[moduleId] = {
2108 /******/ // no module.id needed
2109 /******/ // no module.loaded needed
2110 /******/ exports: {}
2111 /******/ };
2112 /******/
2113 /******/ // Execute the module function
2114 /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
2115 /******/
2116 /******/ // Return the exports of the module
2117 /******/ return module.exports;
2118 /******/ }
2119 /******/
2120 /************************************************************************/
2121 /******/ /* webpack/runtime/compat get default export */
2122 /******/ !function() {
2123 /******/ // getDefaultExport function for compatibility with non-harmony modules
2124 /******/ __webpack_require__.n = function(module) {
2125 /******/ var getter = module && module.__esModule ?
2126 /******/ function() { return module['default']; } :
2127 /******/ function() { return module; };
2128 /******/ __webpack_require__.d(getter, { a: getter });
2129 /******/ return getter;
2130 /******/ };
2131 /******/ }();
2132 /******/
2133 /******/ /* webpack/runtime/define property getters */
2134 /******/ !function() {
2135 /******/ // define getter functions for harmony exports
2136 /******/ __webpack_require__.d = function(exports, definition) {
2137 /******/ for(var key in definition) {
2138 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
2139 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
2140 /******/ }
2141 /******/ }
2142 /******/ };
2143 /******/ }();
2144 /******/
2145 /******/ /* webpack/runtime/hasOwnProperty shorthand */
2146 /******/ !function() {
2147 /******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
2148 /******/ }();
2149 /******/
2150 /******/ /* webpack/runtime/make namespace object */
2151 /******/ !function() {
2152 /******/ // define __esModule on exports
2153 /******/ __webpack_require__.r = function(exports) {
2154 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
2155 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2156 /******/ }
2157 /******/ Object.defineProperty(exports, '__esModule', { value: true });
2158 /******/ };
2159 /******/ }();
2160 /******/
2161 /************************************************************************/
2162 var __webpack_exports__ = {};
2163 // This entry need to be wrapped in an IIFE because it need to be in strict mode.
2164 !function() {
2165 "use strict";
2166 // ESM COMPAT FLAG
2167 __webpack_require__.r(__webpack_exports__);
2168
2169 // EXPORTS
2170 __webpack_require__.d(__webpack_exports__, {
2171 "__experimentalUseDialog": function() { return /* reexport */ use_dialog; },
2172 "__experimentalUseDisabled": function() { return /* reexport */ useDisabled; },
2173 "__experimentalUseDragging": function() { return /* reexport */ useDragging; },
2174 "__experimentalUseDropZone": function() { return /* reexport */ useDropZone; },
2175 "__experimentalUseFixedWindowList": function() { return /* reexport */ useFixedWindowList; },
2176 "__experimentalUseFocusOutside": function() { return /* reexport */ useFocusOutside; },
2177 "compose": function() { return /* reexport */ compose; },
2178 "createHigherOrderComponent": function() { return /* reexport */ create_higher_order_component; },
2179 "ifCondition": function() { return /* reexport */ if_condition; },
2180 "pure": function() { return /* reexport */ higher_order_pure; },
2181 "useAsyncList": function() { return /* reexport */ use_async_list; },
2182 "useConstrainedTabbing": function() { return /* reexport */ use_constrained_tabbing; },
2183 "useCopyOnClick": function() { return /* reexport */ useCopyOnClick; },
2184 "useCopyToClipboard": function() { return /* reexport */ useCopyToClipboard; },
2185 "useDebounce": function() { return /* reexport */ useDebounce; },
2186 "useFocusOnMount": function() { return /* reexport */ useFocusOnMount; },
2187 "useFocusReturn": function() { return /* reexport */ use_focus_return; },
2188 "useFocusableIframe": function() { return /* reexport */ useFocusableIframe; },
2189 "useInstanceId": function() { return /* reexport */ useInstanceId; },
2190 "useIsomorphicLayoutEffect": function() { return /* reexport */ use_isomorphic_layout_effect; },
2191 "useKeyboardShortcut": function() { return /* reexport */ use_keyboard_shortcut; },
2192 "useMediaQuery": function() { return /* reexport */ useMediaQuery; },
2193 "useMergeRefs": function() { return /* reexport */ useMergeRefs; },
2194 "usePrevious": function() { return /* reexport */ usePrevious; },
2195 "useReducedMotion": function() { return /* reexport */ use_reduced_motion; },
2196 "useRefEffect": function() { return /* reexport */ useRefEffect; },
2197 "useResizeObserver": function() { return /* reexport */ use_resize_observer; },
2198 "useThrottle": function() { return /* reexport */ useThrottle; },
2199 "useViewportMatch": function() { return /* reexport */ use_viewport_match; },
2200 "useWarnOnChange": function() { return /* reexport */ use_warn_on_change; },
2201 "withGlobalEvents": function() { return /* reexport */ withGlobalEvents; },
2202 "withInstanceId": function() { return /* reexport */ with_instance_id; },
2203 "withSafeTimeout": function() { return /* reexport */ with_safe_timeout; },
2204 "withState": function() { return /* reexport */ withState; }
2205 });
2206
2207 ;// CONCATENATED MODULE: external "lodash"
2208 var external_lodash_namespaceObject = window["lodash"];
2209 ;// CONCATENATED MODULE: ./packages/compose/build-module/utils/create-higher-order-component/index.js
2210 /**
2211 * External dependencies
2212 */
2213
2214
2215 /**
2216 * Given a function mapping a component to an enhanced component and modifier
2217 * name, returns the enhanced component augmented with a generated displayName.
2218 *
2219 * @param mapComponent Function mapping component to enhanced component.
2220 * @param modifierName Seed name from which to generated display name.
2221 *
2222 * @return Component class with generated display name assigned.
2223 */
2224 function createHigherOrderComponent(mapComponent, modifierName) {
2225 return Inner => {
2226 const Outer = mapComponent(Inner);
2227 const displayName = Inner.displayName || Inner.name || 'Component';
2228 Outer.displayName = `${(0,external_lodash_namespaceObject.upperFirst)((0,external_lodash_namespaceObject.camelCase)(modifierName))}(${displayName})`;
2229 return Outer;
2230 };
2231 }
2232
2233 /* harmony default export */ var create_higher_order_component = (createHigherOrderComponent);
2234
2235 ;// CONCATENATED MODULE: ./packages/compose/build-module/higher-order/compose.js
2236 /**
2237 * External dependencies
2238 */
2239
2240 /**
2241 * Composes multiple higher-order components into a single higher-order component. Performs right-to-left function
2242 * composition, where each successive invocation is supplied the return value of the previous.
2243 *
2244 * This is just a re-export of `lodash`'s `flowRight` function.
2245 *
2246 * @see https://docs-lodash.com/v4/flow-right/
2247 */
2248
2249 /* harmony default export */ var compose = (external_lodash_namespaceObject.flowRight);
2250
2251 ;// CONCATENATED MODULE: external ["wp","element"]
2252 var external_wp_element_namespaceObject = window["wp"]["element"];
2253 ;// CONCATENATED MODULE: ./packages/compose/build-module/higher-order/if-condition/index.js
2254
2255
2256 /**
2257 * Internal dependencies
2258 */
2259
2260 /**
2261 * Higher-order component creator, creating a new component which renders if
2262 * the given condition is satisfied or with the given optional prop name.
2263 *
2264 * @example
2265 * ```ts
2266 * type Props = { foo: string };
2267 * const Component = ( props: Props ) => <div>{ props.foo }</div>;
2268 * const ConditionalComponent = ifCondition( ( props: Props ) => props.foo.length !== 0 )( Component );
2269 * <ConditionalComponent foo="" />; // => null
2270 * <ConditionalComponent foo="bar" />; // => <div>bar</div>;
2271 * ```
2272 *
2273 * @param predicate Function to test condition.
2274 *
2275 * @return Higher-order component.
2276 */
2277
2278 const ifCondition = predicate => create_higher_order_component(WrappedComponent => props => {
2279 if (!predicate(props)) {
2280 return null;
2281 }
2282
2283 return (0,external_wp_element_namespaceObject.createElement)(WrappedComponent, props);
2284 }, 'ifCondition');
2285
2286 /* harmony default export */ var if_condition = (ifCondition);
2287
2288 ;// CONCATENATED MODULE: external ["wp","isShallowEqual"]
2289 var external_wp_isShallowEqual_namespaceObject = window["wp"]["isShallowEqual"];
2290 var external_wp_isShallowEqual_default = /*#__PURE__*/__webpack_require__.n(external_wp_isShallowEqual_namespaceObject);
2291 ;// CONCATENATED MODULE: ./packages/compose/build-module/higher-order/pure/index.js
2292
2293
2294 /**
2295 * WordPress dependencies
2296 */
2297
2298
2299 /**
2300 * Internal dependencies
2301 */
2302
2303
2304 /**
2305 * External dependencies
2306 */
2307
2308 /**
2309 * Given a component returns the enhanced component augmented with a component
2310 * only re-rendering when its props/state change
2311 */
2312 const pure = create_higher_order_component(Wrapped => {
2313 if (Wrapped.prototype instanceof external_wp_element_namespaceObject.Component) {
2314 return class extends Wrapped {
2315 shouldComponentUpdate(nextProps, nextState) {
2316 return !external_wp_isShallowEqual_default()(nextProps, this.props) || !external_wp_isShallowEqual_default()(nextState, this.state);
2317 }
2318
2319 };
2320 }
2321
2322 return class extends external_wp_element_namespaceObject.Component {
2323 shouldComponentUpdate(nextProps) {
2324 return !external_wp_isShallowEqual_default()(nextProps, this.props);
2325 }
2326
2327 render() {
2328 return (0,external_wp_element_namespaceObject.createElement)(Wrapped, this.props);
2329 }
2330
2331 };
2332 }, 'pure');
2333 /* harmony default export */ var higher_order_pure = (pure);
2334
2335 ;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/extends.js
2336 function _extends() {
2337 _extends = Object.assign || function (target) {
2338 for (var i = 1; i < arguments.length; i++) {
2339 var source = arguments[i];
2340
2341 for (var key in source) {
2342 if (Object.prototype.hasOwnProperty.call(source, key)) {
2343 target[key] = source[key];
2344 }
2345 }
2346 }
2347
2348 return target;
2349 };
2350
2351 return _extends.apply(this, arguments);
2352 }
2353 ;// CONCATENATED MODULE: external ["wp","deprecated"]
2354 var external_wp_deprecated_namespaceObject = window["wp"]["deprecated"];
2355 var external_wp_deprecated_default = /*#__PURE__*/__webpack_require__.n(external_wp_deprecated_namespaceObject);
2356 ;// CONCATENATED MODULE: ./packages/compose/build-module/higher-order/with-global-events/listener.js
2357 /**
2358 * External dependencies
2359 */
2360
2361 /**
2362 * Class responsible for orchestrating event handling on the global window,
2363 * binding a single event to be shared across all handling instances, and
2364 * removing the handler when no instances are listening for the event.
2365 */
2366
2367 class Listener {
2368 constructor() {
2369 /** @type {any} */
2370 this.listeners = {};
2371 this.handleEvent = this.handleEvent.bind(this);
2372 }
2373
2374 add(
2375 /** @type {any} */
2376 eventType,
2377 /** @type {any} */
2378 instance) {
2379 if (!this.listeners[eventType]) {
2380 // Adding first listener for this type, so bind event.
2381 window.addEventListener(eventType, this.handleEvent);
2382 this.listeners[eventType] = [];
2383 }
2384
2385 this.listeners[eventType].push(instance);
2386 }
2387
2388 remove(
2389 /** @type {any} */
2390 eventType,
2391 /** @type {any} */
2392 instance) {
2393 this.listeners[eventType] = (0,external_lodash_namespaceObject.without)(this.listeners[eventType], instance);
2394
2395 if (!this.listeners[eventType].length) {
2396 // Removing last listener for this type, so unbind event.
2397 window.removeEventListener(eventType, this.handleEvent);
2398 delete this.listeners[eventType];
2399 }
2400 }
2401
2402 handleEvent(
2403 /** @type {any} */
2404 event) {
2405 (0,external_lodash_namespaceObject.forEach)(this.listeners[event.type], instance => {
2406 instance.handleEvent(event);
2407 });
2408 }
2409
2410 }
2411
2412 /* harmony default export */ var listener = (Listener);
2413
2414 ;// CONCATENATED MODULE: ./packages/compose/build-module/higher-order/with-global-events/index.js
2415
2416
2417
2418 /**
2419 * External dependencies
2420 */
2421
2422 /**
2423 * WordPress dependencies
2424 */
2425
2426
2427
2428 /**
2429 * Internal dependencies
2430 */
2431
2432
2433
2434 /**
2435 * Listener instance responsible for managing document event handling.
2436 */
2437
2438 const with_global_events_listener = new listener();
2439 /* eslint-disable jsdoc/no-undefined-types */
2440
2441 /**
2442 * Higher-order component creator which, given an object of DOM event types and
2443 * values corresponding to a callback function name on the component, will
2444 * create or update a window event handler to invoke the callback when an event
2445 * occurs. On behalf of the consuming developer, the higher-order component
2446 * manages unbinding when the component unmounts, and binding at most a single
2447 * event handler for the entire application.
2448 *
2449 * @deprecated
2450 *
2451 * @param {Record<keyof GlobalEventHandlersEventMap, string>} eventTypesToHandlers Object with keys of DOM
2452 * event type, the value a
2453 * name of the function on
2454 * the original component's
2455 * instance which handles
2456 * the event.
2457 *
2458 * @return {any} Higher-order component.
2459 */
2460
2461 function withGlobalEvents(eventTypesToHandlers) {
2462 external_wp_deprecated_default()('wp.compose.withGlobalEvents', {
2463 since: '5.7',
2464 alternative: 'useEffect'
2465 }); // @ts-ignore We don't need to fix the type-related issues because this is deprecated.
2466
2467 return create_higher_order_component(WrappedComponent => {
2468 class Wrapper extends external_wp_element_namespaceObject.Component {
2469 constructor(
2470 /** @type {any} */
2471 props) {
2472 super(props);
2473 this.handleEvent = this.handleEvent.bind(this);
2474 this.handleRef = this.handleRef.bind(this);
2475 }
2476
2477 componentDidMount() {
2478 (0,external_lodash_namespaceObject.forEach)(eventTypesToHandlers, (_, eventType) => {
2479 with_global_events_listener.add(eventType, this);
2480 });
2481 }
2482
2483 componentWillUnmount() {
2484 (0,external_lodash_namespaceObject.forEach)(eventTypesToHandlers, (_, eventType) => {
2485 with_global_events_listener.remove(eventType, this);
2486 });
2487 }
2488
2489 handleEvent(
2490 /** @type {any} */
2491 event) {
2492 const handler = eventTypesToHandlers[
2493 /** @type {keyof GlobalEventHandlersEventMap} */
2494 event.type
2495 /* eslint-enable jsdoc/no-undefined-types */
2496 ];
2497
2498 if (typeof this.wrappedRef[handler] === 'function') {
2499 this.wrappedRef[handler](event);
2500 }
2501 }
2502
2503 handleRef(
2504 /** @type {any} */
2505 el) {
2506 this.wrappedRef = el; // Any component using `withGlobalEvents` that is not setting a `ref`
2507 // will cause `this.props.forwardedRef` to be `null`, so we need this
2508 // check.
2509
2510 if (this.props.forwardedRef) {
2511 this.props.forwardedRef(el);
2512 }
2513 }
2514
2515 render() {
2516 return (0,external_wp_element_namespaceObject.createElement)(WrappedComponent, _extends({}, this.props.ownProps, {
2517 ref: this.handleRef
2518 }));
2519 }
2520
2521 }
2522
2523 return (0,external_wp_element_namespaceObject.forwardRef)((props, ref) => {
2524 return (0,external_wp_element_namespaceObject.createElement)(Wrapper, {
2525 ownProps: props,
2526 forwardedRef: ref
2527 });
2528 });
2529 }, 'withGlobalEvents');
2530 }
2531
2532 ;// CONCATENATED MODULE: ./packages/compose/build-module/hooks/use-instance-id/index.js
2533 // Disable reason: Object and object are distinctly different types in TypeScript and we mean the lowercase object in thise case
2534 // but eslint wants to force us to use `Object`. See https://stackoverflow.com/questions/49464634/difference-between-object-and-object-in-typescript
2535
2536 /* eslint-disable jsdoc/check-types */
2537
2538 /**
2539 * WordPress dependencies
2540 */
2541
2542 /**
2543 * @type {WeakMap<object, number>}
2544 */
2545
2546 const instanceMap = new WeakMap();
2547 /**
2548 * Creates a new id for a given object.
2549 *
2550 * @param {object} object Object reference to create an id for.
2551 * @return {number} The instance id (index).
2552 */
2553
2554 function createId(object) {
2555 const instances = instanceMap.get(object) || 0;
2556 instanceMap.set(object, instances + 1);
2557 return instances;
2558 }
2559 /**
2560 * Provides a unique instance ID.
2561 *
2562 * @param {object} object Object reference to create an id for.
2563 * @param {string} [prefix] Prefix for the unique id.
2564 * @param {string | number} [preferredId=''] Default ID to use.
2565 * @return {string | number} The unique instance id.
2566 */
2567
2568
2569 function useInstanceId(object, prefix) {
2570 let preferredId = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
2571 return (0,external_wp_element_namespaceObject.useMemo)(() => {
2572 if (preferredId) return preferredId;
2573 const id = createId(object);
2574 return prefix ? `${prefix}-${id}` : id;
2575 }, [object]);
2576 }
2577 /* eslint-enable jsdoc/check-types */
2578
2579 ;// CONCATENATED MODULE: ./packages/compose/build-module/higher-order/with-instance-id/index.js
2580
2581
2582
2583 /**
2584 * Internal dependencies
2585 */
2586
2587
2588 /**
2589 * A Higher Order Component used to be provide a unique instance ID by
2590 * component.
2591 */
2592
2593 const withInstanceId = create_higher_order_component(WrappedComponent => {
2594 return props => {
2595 const instanceId = useInstanceId(WrappedComponent); // @ts-ignore
2596
2597 return (0,external_wp_element_namespaceObject.createElement)(WrappedComponent, _extends({}, props, {
2598 instanceId: instanceId
2599 }));
2600 };
2601 }, 'withInstanceId');
2602 /* harmony default export */ var with_instance_id = (withInstanceId);
2603
2604 ;// CONCATENATED MODULE: ./packages/compose/build-module/higher-order/with-safe-timeout/index.js
2605
2606
2607 /**
2608 * External dependencies
2609 */
2610
2611
2612 /**
2613 * WordPress dependencies
2614 */
2615
2616 /**
2617 * Internal dependencies
2618 */
2619
2620
2621 /**
2622 * We cannot use the `Window['setTimeout']` and `Window['clearTimeout']`
2623 * types here because those functions include functionality that is not handled
2624 * by this component, like the ability to pass extra arguments.
2625 *
2626 * In the case of this component, we only handle the simplest case where
2627 * `setTimeout` only accepts a function (not a string) and an optional delay.
2628 */
2629
2630 /**
2631 * A higher-order component used to provide and manage delayed function calls
2632 * that ought to be bound to a component's lifecycle.
2633 */
2634 const withSafeTimeout = create_higher_order_component(OriginalComponent => {
2635 return class WrappedComponent extends external_wp_element_namespaceObject.Component {
2636 constructor(props) {
2637 super(props);
2638 this.timeouts = [];
2639 this.setTimeout = this.setTimeout.bind(this);
2640 this.clearTimeout = this.clearTimeout.bind(this);
2641 }
2642
2643 componentWillUnmount() {
2644 this.timeouts.forEach(clearTimeout);
2645 }
2646
2647 setTimeout(fn, delay) {
2648 const id = setTimeout(() => {
2649 fn();
2650 this.clearTimeout(id);
2651 }, delay);
2652 this.timeouts.push(id);
2653 return id;
2654 }
2655
2656 clearTimeout(id) {
2657 clearTimeout(id);
2658 this.timeouts = (0,external_lodash_namespaceObject.without)(this.timeouts, id);
2659 }
2660
2661 render() {
2662 const props = { ...this.props,
2663 setTimeout: this.setTimeout,
2664 clearTimeout: this.clearTimeout
2665 };
2666 return (0,external_wp_element_namespaceObject.createElement)(OriginalComponent, props);
2667 }
2668
2669 };
2670 }, 'withSafeTimeout');
2671 /* harmony default export */ var with_safe_timeout = (withSafeTimeout);
2672
2673 ;// CONCATENATED MODULE: ./packages/compose/build-module/higher-order/with-state/index.js
2674
2675
2676
2677 /**
2678 * WordPress dependencies
2679 */
2680
2681
2682 /**
2683 * Internal dependencies
2684 */
2685
2686
2687 /**
2688 * A Higher Order Component used to provide and manage internal component state
2689 * via props.
2690 *
2691 * @deprecated Use `useState` instead.
2692 *
2693 * @param {any} initialState Optional initial state of the component.
2694 *
2695 * @return {any} A higher order component wrapper accepting a component that takes the state props + its own props + `setState` and returning a component that only accepts the own props.
2696 */
2697
2698 function withState() {
2699 let initialState = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
2700 external_wp_deprecated_default()('wp.compose.withState', {
2701 since: '5.8',
2702 alternative: 'wp.element.useState'
2703 });
2704 return create_higher_order_component(OriginalComponent => {
2705 return class WrappedComponent extends external_wp_element_namespaceObject.Component {
2706 constructor(
2707 /** @type {any} */
2708 props) {
2709 super(props);
2710 this.setState = this.setState.bind(this);
2711 this.state = initialState;
2712 }
2713
2714 render() {
2715 return (0,external_wp_element_namespaceObject.createElement)(OriginalComponent, _extends({}, this.props, this.state, {
2716 setState: this.setState
2717 }));
2718 }
2719
2720 };
2721 }, 'withState');
2722 }
2723
2724 ;// CONCATENATED MODULE: external ["wp","keycodes"]
2725 var external_wp_keycodes_namespaceObject = window["wp"]["keycodes"];
2726 ;// CONCATENATED MODULE: external ["wp","dom"]
2727 var external_wp_dom_namespaceObject = window["wp"]["dom"];
2728 ;// CONCATENATED MODULE: ./packages/compose/build-module/hooks/use-ref-effect/index.js
2729 /**
2730 * External dependencies
2731 */
2732
2733 /**
2734 * WordPress dependencies
2735 */
2736
2737 /**
2738 * Effect-like ref callback. Just like with `useEffect`, this allows you to
2739 * return a cleanup function to be run if the ref changes or one of the
2740 * dependencies changes. The ref is provided as an argument to the callback
2741 * functions. The main difference between this and `useEffect` is that
2742 * the `useEffect` callback is not called when the ref changes, but this is.
2743 * Pass the returned ref callback as the component's ref and merge multiple refs
2744 * with `useMergeRefs`.
2745 *
2746 * It's worth noting that if the dependencies array is empty, there's not
2747 * strictly a need to clean up event handlers for example, because the node is
2748 * to be removed. It *is* necessary if you add dependencies because the ref
2749 * callback will be called multiple times for the same node.
2750 *
2751 * @param callback Callback with ref as argument.
2752 * @param dependencies Dependencies of the callback.
2753 *
2754 * @return Ref callback.
2755 */
2756
2757 function useRefEffect(callback, dependencies) {
2758 const cleanup = (0,external_wp_element_namespaceObject.useRef)();
2759 return (0,external_wp_element_namespaceObject.useCallback)(node => {
2760 if (node) {
2761 cleanup.current = callback(node);
2762 } else if (cleanup.current) {
2763 cleanup.current();
2764 }
2765 }, dependencies);
2766 }
2767
2768 ;// CONCATENATED MODULE: ./packages/compose/build-module/hooks/use-constrained-tabbing/index.js
2769 /**
2770 * WordPress dependencies
2771 */
2772
2773
2774 /**
2775 * Internal dependencies
2776 */
2777
2778
2779 /**
2780 * In Dialogs/modals, the tabbing must be constrained to the content of
2781 * the wrapper element. This hook adds the behavior to the returned ref.
2782 *
2783 * @return {import('react').RefCallback<Element>} Element Ref.
2784 *
2785 * @example
2786 * ```js
2787 * import { useConstrainedTabbing } from '@wordpress/compose';
2788 *
2789 * const ConstrainedTabbingExample = () => {
2790 * const constrainedTabbingRef = useConstrainedTabbing()
2791 * return (
2792 * <div ref={ constrainedTabbingRef }>
2793 * <Button />
2794 * <Button />
2795 * </div>
2796 * );
2797 * }
2798 * ```
2799 */
2800
2801 function useConstrainedTabbing() {
2802 return useRefEffect((
2803 /** @type {HTMLElement} */
2804 node) => {
2805 /** @type {number|undefined} */
2806 let timeoutId;
2807
2808 function onKeyDown(
2809 /** @type {KeyboardEvent} */
2810 event) {
2811 const {
2812 keyCode,
2813 shiftKey,
2814 target
2815 } = event;
2816
2817 if (keyCode !== external_wp_keycodes_namespaceObject.TAB) {
2818 return;
2819 }
2820
2821 const action = shiftKey ? 'findPrevious' : 'findNext';
2822 const nextElement = external_wp_dom_namespaceObject.focus.tabbable[action](
2823 /** @type {HTMLElement} */
2824 target) || null; // If the element that is about to receive focus is outside the
2825 // area, move focus to a div and insert it at the start or end of
2826 // the area, depending on the direction. Without preventing default
2827 // behaviour, the browser will then move focus to the next element.
2828
2829 if (node.contains(nextElement)) {
2830 return;
2831 }
2832
2833 const domAction = shiftKey ? 'append' : 'prepend';
2834 const {
2835 ownerDocument
2836 } = node;
2837 const trap = ownerDocument.createElement('div');
2838 trap.tabIndex = -1;
2839 node[domAction](trap);
2840 trap.focus(); // Remove after the browser moves focus to the next element.
2841
2842 timeoutId = setTimeout(() => node.removeChild(trap));
2843 }
2844
2845 node.addEventListener('keydown', onKeyDown);
2846 return () => {
2847 node.removeEventListener('keydown', onKeyDown);
2848 clearTimeout(timeoutId);
2849 };
2850 }, []);
2851 }
2852
2853 /* harmony default export */ var use_constrained_tabbing = (useConstrainedTabbing);
2854
2855 // EXTERNAL MODULE: ./node_modules/clipboard/dist/clipboard.js
2856 var dist_clipboard = __webpack_require__(8294);
2857 var clipboard_default = /*#__PURE__*/__webpack_require__.n(dist_clipboard);
2858 ;// CONCATENATED MODULE: ./packages/compose/build-module/hooks/use-copy-on-click/index.js
2859 /**
2860 * External dependencies
2861 */
2862
2863 /**
2864 * WordPress dependencies
2865 */
2866
2867
2868
2869 /* eslint-disable jsdoc/no-undefined-types */
2870
2871 /**
2872 * Copies the text to the clipboard when the element is clicked.
2873 *
2874 * @deprecated
2875 *
2876 * @param {import('react').RefObject<string | Element | NodeListOf<Element>>} ref Reference with the element.
2877 * @param {string|Function} text The text to copy.
2878 * @param {number} [timeout] Optional timeout to reset the returned
2879 * state. 4 seconds by default.
2880 *
2881 * @return {boolean} Whether or not the text has been copied. Resets after the
2882 * timeout.
2883 */
2884
2885 function useCopyOnClick(ref, text) {
2886 let timeout = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 4000;
2887
2888 /* eslint-enable jsdoc/no-undefined-types */
2889 external_wp_deprecated_default()('wp.compose.useCopyOnClick', {
2890 since: '5.8',
2891 alternative: 'wp.compose.useCopyToClipboard'
2892 });
2893 /** @type {import('react').MutableRefObject<Clipboard | undefined>} */
2894
2895 const clipboard = (0,external_wp_element_namespaceObject.useRef)();
2896 const [hasCopied, setHasCopied] = (0,external_wp_element_namespaceObject.useState)(false);
2897 (0,external_wp_element_namespaceObject.useEffect)(() => {
2898 /** @type {number | undefined} */
2899 let timeoutId;
2900
2901 if (!ref.current) {
2902 return;
2903 } // Clipboard listens to click events.
2904
2905
2906 clipboard.current = new (clipboard_default())(ref.current, {
2907 text: () => typeof text === 'function' ? text() : text
2908 });
2909 clipboard.current.on('success', _ref => {
2910 let {
2911 clearSelection,
2912 trigger
2913 } = _ref;
2914 // Clearing selection will move focus back to the triggering button,
2915 // ensuring that it is not reset to the body, and further that it is
2916 // kept within the rendered node.
2917 clearSelection(); // Handle ClipboardJS focus bug, see https://github.com/zenorocha/clipboard.js/issues/680
2918
2919 if (trigger) {
2920 /** @type {HTMLElement} */
2921 trigger.focus();
2922 }
2923
2924 if (timeout) {
2925 setHasCopied(true);
2926 clearTimeout(timeoutId);
2927 timeoutId = setTimeout(() => setHasCopied(false), timeout);
2928 }
2929 });
2930 return () => {
2931 if (clipboard.current) {
2932 clipboard.current.destroy();
2933 }
2934
2935 clearTimeout(timeoutId);
2936 };
2937 }, [text, timeout, setHasCopied]);
2938 return hasCopied;
2939 }
2940
2941 ;// CONCATENATED MODULE: ./packages/compose/build-module/hooks/use-copy-to-clipboard/index.js
2942 /**
2943 * External dependencies
2944 */
2945
2946 /**
2947 * WordPress dependencies
2948 */
2949
2950
2951 /**
2952 * Internal dependencies
2953 */
2954
2955
2956 /**
2957 * @template T
2958 * @param {T} value
2959 * @return {import('react').RefObject<T>} The updated ref
2960 */
2961
2962 function useUpdatedRef(value) {
2963 const ref = (0,external_wp_element_namespaceObject.useRef)(value);
2964 ref.current = value;
2965 return ref;
2966 }
2967 /**
2968 * Copies the given text to the clipboard when the element is clicked.
2969 *
2970 * @template {HTMLElement} TElementType
2971 * @param {string | (() => string)} text The text to copy. Use a function if not
2972 * already available and expensive to compute.
2973 * @param {Function} onSuccess Called when to text is copied.
2974 *
2975 * @return {import('react').Ref<TElementType>} A ref to assign to the target element.
2976 */
2977
2978
2979 function useCopyToClipboard(text, onSuccess) {
2980 // Store the dependencies as refs and continuesly update them so they're
2981 // fresh when the callback is called.
2982 const textRef = useUpdatedRef(text);
2983 const onSuccessRef = useUpdatedRef(onSuccess);
2984 return useRefEffect(node => {
2985 // Clipboard listens to click events.
2986 const clipboard = new (clipboard_default())(node, {
2987 text() {
2988 return typeof textRef.current === 'function' ? textRef.current() : textRef.current || '';
2989 }
2990
2991 });
2992 clipboard.on('success', _ref => {
2993 let {
2994 clearSelection
2995 } = _ref;
2996 // Clearing selection will move focus back to the triggering
2997 // button, ensuring that it is not reset to the body, and
2998 // further that it is kept within the rendered node.
2999 clearSelection(); // Handle ClipboardJS focus bug, see
3000 // https://github.com/zenorocha/clipboard.js/issues/680
3001
3002 node.focus();
3003
3004 if (onSuccessRef.current) {
3005 onSuccessRef.current();
3006 }
3007 });
3008 return () => {
3009 clipboard.destroy();
3010 };
3011 }, []);
3012 }
3013
3014 ;// CONCATENATED MODULE: ./packages/compose/build-module/hooks/use-focus-on-mount/index.js
3015 /**
3016 * WordPress dependencies
3017 */
3018
3019
3020 /**
3021 * Hook used to focus the first tabbable element on mount.
3022 *
3023 * @param {boolean | 'firstElement'} focusOnMount Focus on mount mode.
3024 * @return {import('react').RefCallback<HTMLElement>} Ref callback.
3025 *
3026 * @example
3027 * ```js
3028 * import { useFocusOnMount } from '@wordpress/compose';
3029 *
3030 * const WithFocusOnMount = () => {
3031 * const ref = useFocusOnMount()
3032 * return (
3033 * <div ref={ ref }>
3034 * <Button />
3035 * <Button />
3036 * </div>
3037 * );
3038 * }
3039 * ```
3040 */
3041
3042 function useFocusOnMount() {
3043 let focusOnMount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'firstElement';
3044 const focusOnMountRef = (0,external_wp_element_namespaceObject.useRef)(focusOnMount);
3045 (0,external_wp_element_namespaceObject.useEffect)(() => {
3046 focusOnMountRef.current = focusOnMount;
3047 }, [focusOnMount]);
3048 return (0,external_wp_element_namespaceObject.useCallback)(node => {
3049 var _node$ownerDocument$a, _node$ownerDocument;
3050
3051 if (!node || focusOnMountRef.current === false) {
3052 return;
3053 }
3054
3055 if (node.contains((_node$ownerDocument$a = (_node$ownerDocument = node.ownerDocument) === null || _node$ownerDocument === void 0 ? void 0 : _node$ownerDocument.activeElement) !== null && _node$ownerDocument$a !== void 0 ? _node$ownerDocument$a : null)) {
3056 return;
3057 }
3058
3059 let target = node;
3060
3061 if (focusOnMountRef.current === 'firstElement') {
3062 const firstTabbable = external_wp_dom_namespaceObject.focus.tabbable.find(node)[0];
3063
3064 if (firstTabbable) {
3065 target =
3066 /** @type {HTMLElement} */
3067 firstTabbable;
3068 }
3069 }
3070
3071 target.focus();
3072 }, []);
3073 }
3074
3075 ;// CONCATENATED MODULE: ./packages/compose/build-module/hooks/use-focus-return/index.js
3076 /**
3077 * WordPress dependencies
3078 */
3079
3080 /**
3081 * When opening modals/sidebars/dialogs, the focus
3082 * must move to the opened area and return to the
3083 * previously focused element when closed.
3084 * The current hook implements the returning behavior.
3085 *
3086 * @param {() => void} [onFocusReturn] Overrides the default return behavior.
3087 * @return {import('react').RefCallback<HTMLElement>} Element Ref.
3088 *
3089 * @example
3090 * ```js
3091 * import { useFocusReturn } from '@wordpress/compose';
3092 *
3093 * const WithFocusReturn = () => {
3094 * const ref = useFocusReturn()
3095 * return (
3096 * <div ref={ ref }>
3097 * <Button />
3098 * <Button />
3099 * </div>
3100 * );
3101 * }
3102 * ```
3103 */
3104
3105 function useFocusReturn(onFocusReturn) {
3106 /** @type {import('react').MutableRefObject<null | HTMLElement>} */
3107 const ref = (0,external_wp_element_namespaceObject.useRef)(null);
3108 /** @type {import('react').MutableRefObject<null | Element>} */
3109
3110 const focusedBeforeMount = (0,external_wp_element_namespaceObject.useRef)(null);
3111 const onFocusReturnRef = (0,external_wp_element_namespaceObject.useRef)(onFocusReturn);
3112 (0,external_wp_element_namespaceObject.useEffect)(() => {
3113 onFocusReturnRef.current = onFocusReturn;
3114 }, [onFocusReturn]);
3115 return (0,external_wp_element_namespaceObject.useCallback)(node => {
3116 if (node) {
3117 // Set ref to be used when unmounting.
3118 ref.current = node; // Only set when the node mounts.
3119
3120 if (focusedBeforeMount.current) {
3121 return;
3122 }
3123
3124 focusedBeforeMount.current = node.ownerDocument.activeElement;
3125 } else if (focusedBeforeMount.current) {
3126 var _ref$current, _ref$current2, _ref$current3;
3127
3128 const isFocused = (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.contains((_ref$current2 = ref.current) === null || _ref$current2 === void 0 ? void 0 : _ref$current2.ownerDocument.activeElement);
3129
3130 if ((_ref$current3 = ref.current) !== null && _ref$current3 !== void 0 && _ref$current3.isConnected && !isFocused) {
3131 return;
3132 } // Defer to the component's own explicit focus return behavior, if
3133 // specified. This allows for support that the `onFocusReturn`
3134 // decides to allow the default behavior to occur under some
3135 // conditions.
3136
3137
3138 if (onFocusReturnRef.current) {
3139 onFocusReturnRef.current();
3140 } else {
3141 var _focusedBeforeMount$c;
3142
3143 /** @type {null | HTMLElement} */
3144 (_focusedBeforeMount$c = focusedBeforeMount.current) === null || _focusedBeforeMount$c === void 0 ? void 0 : _focusedBeforeMount$c.focus();
3145 }
3146 }
3147 }, []);
3148 }
3149
3150 /* harmony default export */ var use_focus_return = (useFocusReturn);
3151
3152 ;// CONCATENATED MODULE: ./packages/compose/build-module/hooks/use-focus-outside/index.js
3153 /**
3154 * External dependencies
3155 */
3156
3157 /**
3158 * WordPress dependencies
3159 */
3160
3161
3162 /**
3163 * Input types which are classified as button types, for use in considering
3164 * whether element is a (focus-normalized) button.
3165 *
3166 * @type {string[]}
3167 */
3168
3169 const INPUT_BUTTON_TYPES = ['button', 'submit'];
3170 /**
3171 * @typedef {HTMLButtonElement | HTMLLinkElement | HTMLInputElement} FocusNormalizedButton
3172 */
3173 // Disable reason: Rule doesn't support predicate return types
3174
3175 /* eslint-disable jsdoc/valid-types */
3176
3177 /**
3178 * Returns true if the given element is a button element subject to focus
3179 * normalization, or false otherwise.
3180 *
3181 * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Clicking_and_focus
3182 *
3183 * @param {EventTarget} eventTarget The target from a mouse or touch event.
3184 *
3185 * @return {eventTarget is FocusNormalizedButton} Whether element is a button.
3186 */
3187
3188 function isFocusNormalizedButton(eventTarget) {
3189 if (!(eventTarget instanceof window.HTMLElement)) {
3190 return false;
3191 }
3192
3193 switch (eventTarget.nodeName) {
3194 case 'A':
3195 case 'BUTTON':
3196 return true;
3197
3198 case 'INPUT':
3199 return (0,external_lodash_namespaceObject.includes)(INPUT_BUTTON_TYPES,
3200 /** @type {HTMLInputElement} */
3201 eventTarget.type);
3202 }
3203
3204 return false;
3205 }
3206 /* eslint-enable jsdoc/valid-types */
3207
3208 /**
3209 * @typedef {import('react').SyntheticEvent} SyntheticEvent
3210 */
3211
3212 /**
3213 * @callback EventCallback
3214 * @param {SyntheticEvent} event input related event.
3215 */
3216
3217 /**
3218 * @typedef FocusOutsideReactElement
3219 * @property {EventCallback} handleFocusOutside callback for a focus outside event.
3220 */
3221
3222 /**
3223 * @typedef {import('react').MutableRefObject<FocusOutsideReactElement | undefined>} FocusOutsideRef
3224 */
3225
3226 /**
3227 * @typedef {Object} FocusOutsideReturnValue
3228 * @property {EventCallback} onFocus An event handler for focus events.
3229 * @property {EventCallback} onBlur An event handler for blur events.
3230 * @property {EventCallback} onMouseDown An event handler for mouse down events.
3231 * @property {EventCallback} onMouseUp An event handler for mouse up events.
3232 * @property {EventCallback} onTouchStart An event handler for touch start events.
3233 * @property {EventCallback} onTouchEnd An event handler for touch end events.
3234 */
3235
3236 /**
3237 * A react hook that can be used to check whether focus has moved outside the
3238 * element the event handlers are bound to.
3239 *
3240 * @param {EventCallback} onFocusOutside A callback triggered when focus moves outside
3241 * the element the event handlers are bound to.
3242 *
3243 * @return {FocusOutsideReturnValue} An object containing event handlers. Bind the event handlers
3244 * to a wrapping element element to capture when focus moves
3245 * outside that element.
3246 */
3247
3248
3249 function useFocusOutside(onFocusOutside) {
3250 const currentOnFocusOutside = (0,external_wp_element_namespaceObject.useRef)(onFocusOutside);
3251 (0,external_wp_element_namespaceObject.useEffect)(() => {
3252 currentOnFocusOutside.current = onFocusOutside;
3253 }, [onFocusOutside]);
3254 const preventBlurCheck = (0,external_wp_element_namespaceObject.useRef)(false);
3255 /**
3256 * @type {import('react').MutableRefObject<number | undefined>}
3257 */
3258
3259 const blurCheckTimeoutId = (0,external_wp_element_namespaceObject.useRef)();
3260 /**
3261 * Cancel a blur check timeout.
3262 */
3263
3264 const cancelBlurCheck = (0,external_wp_element_namespaceObject.useCallback)(() => {
3265 clearTimeout(blurCheckTimeoutId.current);
3266 }, []); // Cancel blur checks on unmount.
3267
3268 (0,external_wp_element_namespaceObject.useEffect)(() => {
3269 return () => cancelBlurCheck();
3270 }, []); // Cancel a blur check if the callback or ref is no longer provided.
3271
3272 (0,external_wp_element_namespaceObject.useEffect)(() => {
3273 if (!onFocusOutside) {
3274 cancelBlurCheck();
3275 }
3276 }, [onFocusOutside, cancelBlurCheck]);
3277 /**
3278 * Handles a mousedown or mouseup event to respectively assign and
3279 * unassign a flag for preventing blur check on button elements. Some
3280 * browsers, namely Firefox and Safari, do not emit a focus event on
3281 * button elements when clicked, while others do. The logic here
3282 * intends to normalize this as treating click on buttons as focus.
3283 *
3284 * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Clicking_and_focus
3285 *
3286 * @param {SyntheticEvent} event Event for mousedown or mouseup.
3287 */
3288
3289 const normalizeButtonFocus = (0,external_wp_element_namespaceObject.useCallback)(event => {
3290 const {
3291 type,
3292 target
3293 } = event;
3294 const isInteractionEnd = (0,external_lodash_namespaceObject.includes)(['mouseup', 'touchend'], type);
3295
3296 if (isInteractionEnd) {
3297 preventBlurCheck.current = false;
3298 } else if (isFocusNormalizedButton(target)) {
3299 preventBlurCheck.current = true;
3300 }
3301 }, []);
3302 /**
3303 * A callback triggered when a blur event occurs on the element the handler
3304 * is bound to.
3305 *
3306 * Calls the `onFocusOutside` callback in an immediate timeout if focus has
3307 * move outside the bound element and is still within the document.
3308 *
3309 * @param {SyntheticEvent} event Blur event.
3310 */
3311
3312 const queueBlurCheck = (0,external_wp_element_namespaceObject.useCallback)(event => {
3313 // React does not allow using an event reference asynchronously
3314 // due to recycling behavior, except when explicitly persisted.
3315 event.persist(); // Skip blur check if clicking button. See `normalizeButtonFocus`.
3316
3317 if (preventBlurCheck.current) {
3318 return;
3319 }
3320
3321 blurCheckTimeoutId.current = setTimeout(() => {
3322 // If document is not focused then focus should remain
3323 // inside the wrapped component and therefore we cancel
3324 // this blur event thereby leaving focus in place.
3325 // https://developer.mozilla.org/en-US/docs/Web/API/Document/hasFocus.
3326 if (!document.hasFocus()) {
3327 event.preventDefault();
3328 return;
3329 }
3330
3331 if ('function' === typeof currentOnFocusOutside.current) {
3332 currentOnFocusOutside.current(event);
3333 }
3334 }, 0);
3335 }, []);
3336 return {
3337 onFocus: cancelBlurCheck,
3338 onMouseDown: normalizeButtonFocus,
3339 onMouseUp: normalizeButtonFocus,
3340 onTouchStart: normalizeButtonFocus,
3341 onTouchEnd: normalizeButtonFocus,
3342 onBlur: queueBlurCheck
3343 };
3344 }
3345
3346 ;// CONCATENATED MODULE: ./packages/compose/build-module/hooks/use-merge-refs/index.js
3347 /**
3348 * WordPress dependencies
3349 */
3350
3351 /* eslint-disable jsdoc/valid-types */
3352
3353 /**
3354 * @template T
3355 * @typedef {T extends import('react').Ref<infer R> ? R : never} TypeFromRef
3356 */
3357
3358 /* eslint-enable jsdoc/valid-types */
3359
3360 /**
3361 * @template T
3362 * @param {import('react').Ref<T>} ref
3363 * @param {T} value
3364 */
3365
3366 function assignRef(ref, value) {
3367 if (typeof ref === 'function') {
3368 ref(value);
3369 } else if (ref && ref.hasOwnProperty('current')) {
3370 /* eslint-disable jsdoc/no-undefined-types */
3371
3372 /** @type {import('react').MutableRefObject<T>} */
3373 ref.current = value;
3374 /* eslint-enable jsdoc/no-undefined-types */
3375 }
3376 }
3377 /**
3378 * Merges refs into one ref callback.
3379 *
3380 * It also ensures that the merged ref callbacks are only called when they
3381 * change (as a result of a `useCallback` dependency update) OR when the ref
3382 * value changes, just as React does when passing a single ref callback to the
3383 * component.
3384 *
3385 * As expected, if you pass a new function on every render, the ref callback
3386 * will be called after every render.
3387 *
3388 * If you don't wish a ref callback to be called after every render, wrap it
3389 * with `useCallback( callback, dependencies )`. When a dependency changes, the
3390 * old ref callback will be called with `null` and the new ref callback will be
3391 * called with the same value.
3392 *
3393 * To make ref callbacks easier to use, you can also pass the result of
3394 * `useRefEffect`, which makes cleanup easier by allowing you to return a
3395 * cleanup function instead of handling `null`.
3396 *
3397 * It's also possible to _disable_ a ref (and its behaviour) by simply not
3398 * passing the ref.
3399 *
3400 * ```jsx
3401 * const ref = useRefEffect( ( node ) => {
3402 * node.addEventListener( ... );
3403 * return () => {
3404 * node.removeEventListener( ... );
3405 * };
3406 * }, [ ...dependencies ] );
3407 * const otherRef = useRef();
3408 * const mergedRefs useMergeRefs( [
3409 * enabled && ref,
3410 * otherRef,
3411 * ] );
3412 * return <div ref={ mergedRefs } />;
3413 * ```
3414 *
3415 * @template {import('react').Ref<any>} TRef
3416 * @param {Array<TRef>} refs The refs to be merged.
3417 *
3418 * @return {import('react').RefCallback<TypeFromRef<TRef>>} The merged ref callback.
3419 */
3420
3421
3422 function useMergeRefs(refs) {
3423 const element = (0,external_wp_element_namespaceObject.useRef)();
3424 const didElementChange = (0,external_wp_element_namespaceObject.useRef)(false);
3425 /* eslint-disable jsdoc/no-undefined-types */
3426
3427 /** @type {import('react').MutableRefObject<TRef[]>} */
3428
3429 /* eslint-enable jsdoc/no-undefined-types */
3430
3431 const previousRefs = (0,external_wp_element_namespaceObject.useRef)([]);
3432 const currentRefs = (0,external_wp_element_namespaceObject.useRef)(refs); // Update on render before the ref callback is called, so the ref callback
3433 // always has access to the current refs.
3434
3435 currentRefs.current = refs; // If any of the refs change, call the previous ref with `null` and the new
3436 // ref with the node, except when the element changes in the same cycle, in
3437 // which case the ref callbacks will already have been called.
3438
3439 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => {
3440 if (didElementChange.current === false) {
3441 refs.forEach((ref, index) => {
3442 const previousRef = previousRefs.current[index];
3443
3444 if (ref !== previousRef) {
3445 assignRef(previousRef, null);
3446 assignRef(ref, element.current);
3447 }
3448 });
3449 }
3450
3451 previousRefs.current = refs;
3452 }, refs); // No dependencies, must be reset after every render so ref callbacks are
3453 // correctly called after a ref change.
3454
3455 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => {
3456 didElementChange.current = false;
3457 }); // There should be no dependencies so that `callback` is only called when
3458 // the node changes.
3459
3460 return (0,external_wp_element_namespaceObject.useCallback)(value => {
3461 // Update the element so it can be used when calling ref callbacks on a
3462 // dependency change.
3463 assignRef(element, value);
3464 didElementChange.current = true; // When an element changes, the current ref callback should be called
3465 // with the new element and the previous one with `null`.
3466
3467 const refsToAssign = value ? currentRefs.current : previousRefs.current; // Update the latest refs.
3468
3469 for (const ref of refsToAssign) {
3470 assignRef(ref, value);
3471 }
3472 }, []);
3473 }
3474
3475 ;// CONCATENATED MODULE: ./packages/compose/build-module/hooks/use-dialog/index.js
3476 /**
3477 * WordPress dependencies
3478 */
3479
3480
3481 /**
3482 * Internal dependencies
3483 */
3484
3485
3486
3487
3488
3489
3490 /* eslint-disable jsdoc/valid-types */
3491
3492 /**
3493 * @typedef DialogOptions
3494 * @property {Parameters<useFocusOnMount>[0]} focusOnMount Focus on mount arguments.
3495 * @property {() => void} onClose Function to call when the dialog is closed.
3496 */
3497
3498 /* eslint-enable jsdoc/valid-types */
3499
3500 /**
3501 * Returns a ref and props to apply to a dialog wrapper to enable the following behaviors:
3502 * - constrained tabbing.
3503 * - focus on mount.
3504 * - return focus on unmount.
3505 * - focus outside.
3506 *
3507 * @param {DialogOptions} options Dialog Options.
3508 */
3509
3510 function useDialog(options) {
3511 /**
3512 * @type {import('react').MutableRefObject<DialogOptions | undefined>}
3513 */
3514 const currentOptions = (0,external_wp_element_namespaceObject.useRef)();
3515 (0,external_wp_element_namespaceObject.useEffect)(() => {
3516 currentOptions.current = options;
3517 }, Object.values(options));
3518 const constrainedTabbingRef = use_constrained_tabbing();
3519 const focusOnMountRef = useFocusOnMount(options.focusOnMount);
3520 const focusReturnRef = use_focus_return();
3521 const focusOutsideProps = useFocusOutside(event => {
3522 var _currentOptions$curre, _currentOptions$curre2;
3523
3524 // This unstable prop is here only to manage backward compatibility
3525 // for the Popover component otherwise, the onClose should be enough.
3526 // @ts-ignore unstable property
3527 if ((_currentOptions$curre = currentOptions.current) !== null && _currentOptions$curre !== void 0 && _currentOptions$curre.__unstableOnClose) {
3528 // @ts-ignore unstable property
3529 currentOptions.current.__unstableOnClose('focus-outside', event);
3530 } else if ((_currentOptions$curre2 = currentOptions.current) !== null && _currentOptions$curre2 !== void 0 && _currentOptions$curre2.onClose) {
3531 currentOptions.current.onClose();
3532 }
3533 });
3534 const closeOnEscapeRef = (0,external_wp_element_namespaceObject.useCallback)(node => {
3535 if (!node) {
3536 return;
3537 }
3538
3539 node.addEventListener('keydown', (
3540 /** @type {KeyboardEvent} */
3541 event) => {
3542 var _currentOptions$curre3;
3543
3544 // Close on escape
3545 if (event.keyCode === external_wp_keycodes_namespaceObject.ESCAPE && !event.defaultPrevented && (_currentOptions$curre3 = currentOptions.current) !== null && _currentOptions$curre3 !== void 0 && _currentOptions$curre3.onClose) {
3546 event.preventDefault();
3547 currentOptions.current.onClose();
3548 }
3549 });
3550 }, []);
3551 return [useMergeRefs([options.focusOnMount !== false ? constrainedTabbingRef : null, options.focusOnMount !== false ? focusReturnRef : null, options.focusOnMount !== false ? focusOnMountRef : null, closeOnEscapeRef]), { ...focusOutsideProps,
3552 tabIndex: '-1'
3553 }];
3554 }
3555
3556 /* harmony default export */ var use_dialog = (useDialog);
3557
3558 ;// CONCATENATED MODULE: ./packages/compose/build-module/hooks/use-disabled/index.js
3559 /**
3560 * External dependencies
3561 */
3562
3563 /**
3564 * WordPress dependencies
3565 */
3566
3567
3568
3569 /**
3570 * Names of control nodes which qualify for disabled behavior.
3571 *
3572 * See WHATWG HTML Standard: 4.10.18.5: "Enabling and disabling form controls: the disabled attribute".
3573 *
3574 * @see https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#enabling-and-disabling-form-controls:-the-disabled-attribute
3575 *
3576 * @type {string[]}
3577 */
3578
3579 const DISABLED_ELIGIBLE_NODE_NAMES = ['BUTTON', 'FIELDSET', 'INPUT', 'OPTGROUP', 'OPTION', 'SELECT', 'TEXTAREA'];
3580 /**
3581 * In some circumstances, such as block previews, all focusable DOM elements
3582 * (input fields, links, buttons, etc.) need to be disabled. This hook adds the
3583 * behavior to disable nested DOM elements to the returned ref.
3584 *
3585 * @return {import('react').RefObject<HTMLElement>} Element Ref.
3586 *
3587 * @example
3588 * ```js
3589 * import { __experimentalUseDisabled as useDisabled } from '@wordpress/compose';
3590 * const DisabledExample = () => {
3591 * const disabledRef = useDisabled();
3592 * return (
3593 * <div ref={ disabledRef }>
3594 * <a href="#">This link will have tabindex set to -1</a>
3595 * <input placeholder="This input will have the disabled attribute added to it." type="text" />
3596 * </div>
3597 * );
3598 * };
3599 * ```
3600 */
3601
3602 function useDisabled() {
3603 /** @type {import('react').RefObject<HTMLElement>} */
3604 const node = (0,external_wp_element_namespaceObject.useRef)(null);
3605
3606 const disable = () => {
3607 if (!node.current) {
3608 return;
3609 }
3610
3611 external_wp_dom_namespaceObject.focus.focusable.find(node.current).forEach(focusable => {
3612 if ((0,external_lodash_namespaceObject.includes)(DISABLED_ELIGIBLE_NODE_NAMES, focusable.nodeName)) {
3613 focusable.setAttribute('disabled', '');
3614 }
3615
3616 if (focusable.nodeName === 'A') {
3617 focusable.setAttribute('tabindex', '-1');
3618 }
3619
3620 const tabIndex = focusable.getAttribute('tabindex');
3621
3622 if (tabIndex !== null && tabIndex !== '-1') {
3623 focusable.removeAttribute('tabindex');
3624 }
3625
3626 if (focusable.hasAttribute('contenteditable')) {
3627 focusable.setAttribute('contenteditable', 'false');
3628 }
3629 });
3630 }; // Debounce re-disable since disabling process itself will incur
3631 // additional mutations which should be ignored.
3632
3633
3634 const debouncedDisable = (0,external_wp_element_namespaceObject.useCallback)((0,external_lodash_namespaceObject.debounce)(disable, undefined, {
3635 leading: true
3636 }), []);
3637 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => {
3638 disable();
3639 /** @type {MutationObserver | undefined} */
3640
3641 let observer;
3642
3643 if (node.current) {
3644 observer = new window.MutationObserver(debouncedDisable);
3645 observer.observe(node.current, {
3646 childList: true,
3647 attributes: true,
3648 subtree: true
3649 });
3650 }
3651
3652 return () => {
3653 if (observer) {
3654 observer.disconnect();
3655 }
3656
3657 debouncedDisable.cancel();
3658 };
3659 }, []);
3660 return node;
3661 }
3662
3663 ;// CONCATENATED MODULE: ./packages/compose/build-module/hooks/use-isomorphic-layout-effect/index.js
3664 /**
3665 * WordPress dependencies
3666 */
3667
3668 /**
3669 * Preferred over direct usage of `useLayoutEffect` when supporting
3670 * server rendered components (SSR) because currently React
3671 * throws a warning when using useLayoutEffect in that environment.
3672 */
3673
3674 const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? external_wp_element_namespaceObject.useLayoutEffect : external_wp_element_namespaceObject.useEffect;
3675 /* harmony default export */ var use_isomorphic_layout_effect = (useIsomorphicLayoutEffect);
3676
3677 ;// CONCATENATED MODULE: ./packages/compose/build-module/hooks/use-dragging/index.js
3678 /**
3679 * WordPress dependencies
3680 */
3681
3682 /**
3683 * Internal dependencies
3684 */
3685
3686
3687 /**
3688 * @param {Object} props
3689 * @param {(e: MouseEvent) => void} props.onDragStart
3690 * @param {(e: MouseEvent) => void} props.onDragMove
3691 * @param {(e: MouseEvent) => void} props.onDragEnd
3692 */
3693
3694 function useDragging(_ref) {
3695 let {
3696 onDragStart,
3697 onDragMove,
3698 onDragEnd
3699 } = _ref;
3700 const [isDragging, setIsDragging] = (0,external_wp_element_namespaceObject.useState)(false);
3701 const eventsRef = (0,external_wp_element_namespaceObject.useRef)({
3702 onDragStart,
3703 onDragMove,
3704 onDragEnd
3705 });
3706 use_isomorphic_layout_effect(() => {
3707 eventsRef.current.onDragStart = onDragStart;
3708 eventsRef.current.onDragMove = onDragMove;
3709 eventsRef.current.onDragEnd = onDragEnd;
3710 }, [onDragStart, onDragMove, onDragEnd]);
3711 const onMouseMove = (0,external_wp_element_namespaceObject.useCallback)((
3712 /** @type {MouseEvent} */
3713 event) => eventsRef.current.onDragMove && eventsRef.current.onDragMove(event), []);
3714 const endDrag = (0,external_wp_element_namespaceObject.useCallback)((
3715 /** @type {MouseEvent} */
3716 event) => {
3717 if (eventsRef.current.onDragEnd) {
3718 eventsRef.current.onDragEnd(event);
3719 }
3720
3721 document.removeEventListener('mousemove', onMouseMove);
3722 document.removeEventListener('mouseup', endDrag);
3723 setIsDragging(false);
3724 }, []);
3725 const startDrag = (0,external_wp_element_namespaceObject.useCallback)((
3726 /** @type {MouseEvent} */
3727 event) => {
3728 if (eventsRef.current.onDragStart) {
3729 eventsRef.current.onDragStart(event);
3730 }
3731
3732 document.addEventListener('mousemove', onMouseMove);
3733 document.addEventListener('mouseup', endDrag);
3734 setIsDragging(true);
3735 }, []); // Remove the global events when unmounting if needed.
3736
3737 (0,external_wp_element_namespaceObject.useEffect)(() => {
3738 return () => {
3739 if (isDragging) {
3740 document.removeEventListener('mousemove', onMouseMove);
3741 document.removeEventListener('mouseup', endDrag);
3742 }
3743 };
3744 }, [isDragging]);
3745 return {
3746 startDrag,
3747 endDrag,
3748 isDragging
3749 };
3750 }
3751
3752 // EXTERNAL MODULE: ./node_modules/mousetrap/mousetrap.js
3753 var mousetrap_mousetrap = __webpack_require__(7973);
3754 var mousetrap_default = /*#__PURE__*/__webpack_require__.n(mousetrap_mousetrap);
3755 // EXTERNAL MODULE: ./node_modules/mousetrap/plugins/global-bind/mousetrap-global-bind.js
3756 var mousetrap_global_bind = __webpack_require__(5538);
3757 ;// CONCATENATED MODULE: ./packages/compose/build-module/hooks/use-keyboard-shortcut/index.js
3758 /**
3759 * External dependencies
3760 */
3761
3762
3763
3764 /**
3765 * WordPress dependencies
3766 */
3767
3768
3769 /**
3770 * A block selection object.
3771 *
3772 * @typedef {Object} WPKeyboardShortcutConfig
3773 *
3774 * @property {boolean} [bindGlobal] Handle keyboard events anywhere including inside textarea/input fields.
3775 * @property {string} [eventName] Event name used to trigger the handler, defaults to keydown.
3776 * @property {boolean} [isDisabled] Disables the keyboard handler if the value is true.
3777 * @property {import('react').RefObject<HTMLElement>} [target] React reference to the DOM element used to catch the keyboard event.
3778 */
3779
3780 /**
3781 * Return true if platform is MacOS.
3782 *
3783 * @param {Window} [_window] window object by default; used for DI testing.
3784 *
3785 * @return {boolean} True if MacOS; false otherwise.
3786 */
3787
3788 function isAppleOS() {
3789 let _window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window;
3790
3791 const {
3792 platform
3793 } = _window.navigator;
3794 return platform.indexOf('Mac') !== -1 || (0,external_lodash_namespaceObject.includes)(['iPad', 'iPhone'], platform);
3795 }
3796 /* eslint-disable jsdoc/valid-types */
3797
3798 /**
3799 * Attach a keyboard shortcut handler.
3800 *
3801 * @see https://craig.is/killing/mice#api.bind for information about the `callback` parameter.
3802 *
3803 * @param {string[]|string} shortcuts Keyboard Shortcuts.
3804 * @param {(e: import('mousetrap').ExtendedKeyboardEvent, combo: string) => void} callback Shortcut callback.
3805 * @param {WPKeyboardShortcutConfig} options Shortcut options.
3806 */
3807
3808
3809 function useKeyboardShortcut(
3810 /* eslint-enable jsdoc/valid-types */
3811 shortcuts, callback) {
3812 let {
3813 bindGlobal = false,
3814 eventName = 'keydown',
3815 isDisabled = false,
3816 // This is important for performance considerations.
3817 target
3818 } = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
3819 const currentCallback = (0,external_wp_element_namespaceObject.useRef)(callback);
3820 (0,external_wp_element_namespaceObject.useEffect)(() => {
3821 currentCallback.current = callback;
3822 }, [callback]);
3823 (0,external_wp_element_namespaceObject.useEffect)(() => {
3824 if (isDisabled) {
3825 return;
3826 }
3827
3828 const mousetrap = new (mousetrap_default())(target && target.current ? target.current : // We were passing `document` here previously, so to successfully cast it to Element we must cast it first to `unknown`.
3829 // Not sure if this is a mistake but it was the behavior previous to the addition of types so we're just doing what's
3830 // necessary to maintain the existing behavior
3831
3832 /** @type {Element} */
3833
3834 /** @type {unknown} */
3835 document);
3836 (0,external_lodash_namespaceObject.castArray)(shortcuts).forEach(shortcut => {
3837 const keys = shortcut.split('+'); // Determines whether a key is a modifier by the length of the string.
3838 // E.g. if I add a pass a shortcut Shift+Cmd+M, it'll determine that
3839 // the modifiers are Shift and Cmd because they're not a single character.
3840
3841 const modifiers = new Set(keys.filter(value => value.length > 1));
3842 const hasAlt = modifiers.has('alt');
3843 const hasShift = modifiers.has('shift'); // This should be better moved to the shortcut registration instead.
3844
3845 if (isAppleOS() && (modifiers.size === 1 && hasAlt || modifiers.size === 2 && hasAlt && hasShift)) {
3846 throw new Error(`Cannot bind ${shortcut}. Alt and Shift+Alt modifiers are reserved for character input.`);
3847 }
3848
3849 const bindFn = bindGlobal ? 'bindGlobal' : 'bind'; // @ts-ignore `bindGlobal` is an undocumented property
3850
3851 mousetrap[bindFn](shortcut, function () {
3852 return (
3853 /* eslint-enable jsdoc/valid-types */
3854 currentCallback.current(...arguments)
3855 );
3856 }, eventName);
3857 });
3858 return () => {
3859 mousetrap.reset();
3860 };
3861 }, [shortcuts, bindGlobal, eventName, target, isDisabled]);
3862 }
3863
3864 /* harmony default export */ var use_keyboard_shortcut = (useKeyboardShortcut);
3865
3866 ;// CONCATENATED MODULE: ./packages/compose/build-module/hooks/use-media-query/index.js
3867 /**
3868 * WordPress dependencies
3869 */
3870
3871 /**
3872 * Runs a media query and returns its value when it changes.
3873 *
3874 * @param {string} [query] Media Query.
3875 * @return {boolean} return value of the media query.
3876 */
3877
3878 function useMediaQuery(query) {
3879 const [match, setMatch] = (0,external_wp_element_namespaceObject.useState)(() => !!(query && typeof window !== 'undefined' && window.matchMedia(query).matches));
3880 (0,external_wp_element_namespaceObject.useEffect)(() => {
3881 if (!query) {
3882 return;
3883 }
3884
3885 const updateMatch = () => setMatch(window.matchMedia(query).matches);
3886
3887 updateMatch();
3888 const list = window.matchMedia(query);
3889 list.addListener(updateMatch);
3890 return () => {
3891 list.removeListener(updateMatch);
3892 };
3893 }, [query]);
3894 return !!query && match;
3895 }
3896
3897 ;// CONCATENATED MODULE: ./packages/compose/build-module/hooks/use-previous/index.js
3898 /**
3899 * WordPress dependencies
3900 */
3901
3902 /**
3903 * Use something's value from the previous render.
3904 * Based on https://usehooks.com/usePrevious/.
3905 *
3906 * @param value The value to track.
3907 *
3908 * @return The value from the previous render.
3909 */
3910
3911 function usePrevious(value) {
3912 const ref = (0,external_wp_element_namespaceObject.useRef)(); // Store current value in ref.
3913
3914 (0,external_wp_element_namespaceObject.useEffect)(() => {
3915 ref.current = value;
3916 }, [value]); // Re-run when value changes.
3917 // Return previous value (happens before update in useEffect above).
3918
3919 return ref.current;
3920 }
3921
3922 ;// CONCATENATED MODULE: ./packages/compose/build-module/hooks/use-reduced-motion/index.js
3923 /**
3924 * Internal dependencies
3925 */
3926
3927 /**
3928 * Hook returning whether the user has a preference for reduced motion.
3929 *
3930 * @return {boolean} Reduced motion preference value.
3931 */
3932
3933 const useReducedMotion = () => useMediaQuery('(prefers-reduced-motion: reduce)');
3934
3935 /* harmony default export */ var use_reduced_motion = (useReducedMotion);
3936
3937 ;// CONCATENATED MODULE: ./packages/compose/build-module/hooks/use-viewport-match/index.js
3938 /**
3939 * WordPress dependencies
3940 */
3941
3942 /**
3943 * Internal dependencies
3944 */
3945
3946
3947 /**
3948 * @typedef {"huge" | "wide" | "large" | "medium" | "small" | "mobile"} WPBreakpoint
3949 */
3950
3951 /**
3952 * Hash of breakpoint names with pixel width at which it becomes effective.
3953 *
3954 * @see _breakpoints.scss
3955 *
3956 * @type {Record<WPBreakpoint, number>}
3957 */
3958
3959 const BREAKPOINTS = {
3960 huge: 1440,
3961 wide: 1280,
3962 large: 960,
3963 medium: 782,
3964 small: 600,
3965 mobile: 480
3966 };
3967 /**
3968 * @typedef {">=" | "<"} WPViewportOperator
3969 */
3970
3971 /**
3972 * Object mapping media query operators to the condition to be used.
3973 *
3974 * @type {Record<WPViewportOperator, string>}
3975 */
3976
3977 const CONDITIONS = {
3978 '>=': 'min-width',
3979 '<': 'max-width'
3980 };
3981 /**
3982 * Object mapping media query operators to a function that given a breakpointValue and a width evaluates if the operator matches the values.
3983 *
3984 * @type {Record<WPViewportOperator, (breakpointValue: number, width: number) => boolean>}
3985 */
3986
3987 const OPERATOR_EVALUATORS = {
3988 '>=': (breakpointValue, width) => width >= breakpointValue,
3989 '<': (breakpointValue, width) => width < breakpointValue
3990 };
3991 const ViewportMatchWidthContext = (0,external_wp_element_namespaceObject.createContext)(
3992 /** @type {null | number} */
3993 null);
3994 /**
3995 * Returns true if the viewport matches the given query, or false otherwise.
3996 *
3997 * @param {WPBreakpoint} breakpoint Breakpoint size name.
3998 * @param {WPViewportOperator} [operator=">="] Viewport operator.
3999 *
4000 * @example
4001 *
4002 * ```js
4003 * useViewportMatch( 'huge', '<' );
4004 * useViewportMatch( 'medium' );
4005 * ```
4006 *
4007 * @return {boolean} Whether viewport matches query.
4008 */
4009
4010 const useViewportMatch = function (breakpoint) {
4011 let operator = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '>=';
4012 const simulatedWidth = (0,external_wp_element_namespaceObject.useContext)(ViewportMatchWidthContext);
4013 const mediaQuery = !simulatedWidth && `(${CONDITIONS[operator]}: ${BREAKPOINTS[breakpoint]}px)`;
4014 const mediaQueryResult = useMediaQuery(mediaQuery || undefined);
4015
4016 if (simulatedWidth) {
4017 return OPERATOR_EVALUATORS[operator](BREAKPOINTS[breakpoint], simulatedWidth);
4018 }
4019
4020 return mediaQueryResult;
4021 };
4022
4023 useViewportMatch.__experimentalWidthProvider = ViewportMatchWidthContext.Provider;
4024 /* harmony default export */ var use_viewport_match = (useViewportMatch);
4025
4026 // EXTERNAL MODULE: ./node_modules/react-resize-aware/dist/index.js
4027 var dist = __webpack_require__(235);
4028 var dist_default = /*#__PURE__*/__webpack_require__.n(dist);
4029 ;// CONCATENATED MODULE: ./packages/compose/build-module/hooks/use-resize-observer/index.js
4030 /**
4031 * External dependencies
4032 */
4033
4034 /**
4035 * Hook which allows to listen the resize event of any target element when it changes sizes.
4036 * _Note: `useResizeObserver` will report `null` until after first render_
4037 *
4038 * Simply a re-export of `react-resize-aware` so refer to its documentation <https://github.com/FezVrasta/react-resize-aware>
4039 * for more details.
4040 *
4041 * @see https://github.com/FezVrasta/react-resize-aware
4042 *
4043 * @example
4044 *
4045 * ```js
4046 * const App = () => {
4047 * const [ resizeListener, sizes ] = useResizeObserver();
4048 *
4049 * return (
4050 * <div>
4051 * { resizeListener }
4052 * Your content here
4053 * </div>
4054 * );
4055 * };
4056 * ```
4057 *
4058 */
4059
4060 /* harmony default export */ var use_resize_observer = ((dist_default()));
4061
4062 ;// CONCATENATED MODULE: external ["wp","priorityQueue"]
4063 var external_wp_priorityQueue_namespaceObject = window["wp"]["priorityQueue"];
4064 ;// CONCATENATED MODULE: ./packages/compose/build-module/hooks/use-async-list/index.js
4065 /**
4066 * WordPress dependencies
4067 */
4068
4069
4070
4071 /**
4072 * Returns the first items from list that are present on state.
4073 *
4074 * @param list New array.
4075 * @param state Current state.
4076 * @return First items present iin state.
4077 */
4078 function getFirstItemsPresentInState(list, state) {
4079 const firstItems = [];
4080
4081 for (let i = 0; i < list.length; i++) {
4082 const item = list[i];
4083
4084 if (!state.includes(item)) {
4085 break;
4086 }
4087
4088 firstItems.push(item);
4089 }
4090
4091 return firstItems;
4092 }
4093 /**
4094 * React hook returns an array which items get asynchronously appended from a source array.
4095 * This behavior is useful if we want to render a list of items asynchronously for performance reasons.
4096 *
4097 * @param list Source array.
4098 * @param config Configuration object.
4099 *
4100 * @return Async array.
4101 */
4102
4103
4104 function useAsyncList(list) {
4105 let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
4106 step: 1
4107 };
4108 const {
4109 step = 1
4110 } = config;
4111 const [current, setCurrent] = (0,external_wp_element_namespaceObject.useState)([]);
4112 (0,external_wp_element_namespaceObject.useEffect)(() => {
4113 // On reset, we keep the first items that were previously rendered.
4114 let firstItems = getFirstItemsPresentInState(list, current);
4115
4116 if (firstItems.length < step) {
4117 firstItems = firstItems.concat(list.slice(firstItems.length, step));
4118 }
4119
4120 setCurrent(firstItems);
4121 let nextIndex = firstItems.length;
4122 const asyncQueue = (0,external_wp_priorityQueue_namespaceObject.createQueue)();
4123
4124 const append = () => {
4125 if (list.length <= nextIndex) {
4126 return;
4127 }
4128
4129 setCurrent(state => [...state, ...list.slice(nextIndex, nextIndex + step)]);
4130 nextIndex += step;
4131 asyncQueue.add({}, append);
4132 };
4133
4134 asyncQueue.add({}, append);
4135 return () => asyncQueue.reset();
4136 }, [list]);
4137 return current;
4138 }
4139
4140 /* harmony default export */ var use_async_list = (useAsyncList);
4141
4142 ;// CONCATENATED MODULE: ./packages/compose/build-module/hooks/use-warn-on-change/index.js
4143 /**
4144 * Internal dependencies
4145 */
4146 // Disable reason: Object and object are distinctly different types in TypeScript and we mean the lowercase object in thise case
4147 // but eslint wants to force us to use `Object`. See https://stackoverflow.com/questions/49464634/difference-between-object-and-object-in-typescript
4148
4149 /* eslint-disable jsdoc/check-types */
4150
4151 /**
4152 * Hook that performs a shallow comparison between the preview value of an object
4153 * and the new one, if there's a difference, it prints it to the console.
4154 * this is useful in performance related work, to check why a component re-renders.
4155 *
4156 * @example
4157 *
4158 * ```jsx
4159 * function MyComponent(props) {
4160 * useWarnOnChange(props);
4161 *
4162 * return "Something";
4163 * }
4164 * ```
4165 *
4166 * @param {object} object Object which changes to compare.
4167 * @param {string} prefix Just a prefix to show when console logging.
4168 */
4169
4170 function useWarnOnChange(object) {
4171 let prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'Change detection';
4172 const previousValues = usePrevious(object);
4173 Object.entries(previousValues !== null && previousValues !== void 0 ? previousValues : []).forEach(_ref => {
4174 let [key, value] = _ref;
4175
4176 if (value !== object[
4177 /** @type {keyof typeof object} */
4178 key]) {
4179 // eslint-disable-next-line no-console
4180 console.warn(`${prefix}: ${key} key changed:`, value, object[
4181 /** @type {keyof typeof object} */
4182 key]
4183 /* eslint-enable jsdoc/check-types */
4184 );
4185 }
4186 });
4187 }
4188
4189 /* harmony default export */ var use_warn_on_change = (useWarnOnChange);
4190
4191 // EXTERNAL MODULE: external "React"
4192 var external_React_ = __webpack_require__(9196);
4193 ;// CONCATENATED MODULE: ./node_modules/use-memo-one/dist/use-memo-one.esm.js
4194
4195
4196 function areInputsEqual(newInputs, lastInputs) {
4197 if (newInputs.length !== lastInputs.length) {
4198 return false;
4199 }
4200
4201 for (var i = 0; i < newInputs.length; i++) {
4202 if (newInputs[i] !== lastInputs[i]) {
4203 return false;
4204 }
4205 }
4206
4207 return true;
4208 }
4209
4210 function useMemoOne(getResult, inputs) {
4211 var initial = (0,external_React_.useState)(function () {
4212 return {
4213 inputs: inputs,
4214 result: getResult()
4215 };
4216 })[0];
4217 var committed = (0,external_React_.useRef)(initial);
4218 var isInputMatch = Boolean(inputs && committed.current.inputs && areInputsEqual(inputs, committed.current.inputs));
4219 var cache = isInputMatch ? committed.current : {
4220 inputs: inputs,
4221 result: getResult()
4222 };
4223 (0,external_React_.useEffect)(function () {
4224 committed.current = cache;
4225 }, [cache]);
4226 return cache.result;
4227 }
4228 function useCallbackOne(callback, inputs) {
4229 return useMemoOne(function () {
4230 return callback;
4231 }, inputs);
4232 }
4233 var useMemo = (/* unused pure expression or super */ null && (useMemoOne));
4234 var useCallback = (/* unused pure expression or super */ null && (useCallbackOne));
4235
4236
4237
4238 ;// CONCATENATED MODULE: ./packages/compose/build-module/hooks/use-debounce/index.js
4239 /**
4240 * External dependencies
4241 */
4242
4243
4244 /**
4245 * WordPress dependencies
4246 */
4247
4248
4249 /* eslint-disable jsdoc/valid-types */
4250
4251 /**
4252 * Debounces a function with Lodash's `debounce`. A new debounced function will
4253 * be returned and any scheduled calls cancelled if any of the arguments change,
4254 * including the function to debounce, so please wrap functions created on
4255 * render in components in `useCallback`.
4256 *
4257 * @see https://docs-lodash.com/v4/debounce/
4258 *
4259 * @template {(...args: any[]) => void} TFunc
4260 *
4261 * @param {TFunc} fn The function to debounce.
4262 * @param {number} [wait] The number of milliseconds to delay.
4263 * @param {import('lodash').DebounceSettings} [options] The options object.
4264 * @return {import('lodash').DebouncedFunc<TFunc>} Debounced function.
4265 */
4266
4267 function useDebounce(fn, wait, options) {
4268 /* eslint-enable jsdoc/valid-types */
4269 const debounced = useMemoOne(() => (0,external_lodash_namespaceObject.debounce)(fn, wait, options), [fn, wait, options]);
4270 (0,external_wp_element_namespaceObject.useEffect)(() => () => debounced.cancel(), [debounced]);
4271 return debounced;
4272 }
4273
4274 ;// CONCATENATED MODULE: ./packages/compose/build-module/hooks/use-throttle/index.js
4275 /**
4276 * External dependencies
4277 */
4278
4279
4280 /**
4281 * WordPress dependencies
4282 */
4283
4284
4285 /**
4286 * Throttles a function with Lodash's `throttle`. A new throttled function will
4287 * be returned and any scheduled calls cancelled if any of the arguments change,
4288 * including the function to throttle, so please wrap functions created on
4289 * render in components in `useCallback`.
4290 *
4291 * @see https://docs-lodash.com/v4/throttle/
4292 *
4293 * @template {(...args: any[]) => void} TFunc
4294 *
4295 * @param {TFunc} fn The function to throttle.
4296 * @param {number} [wait] The number of milliseconds to throttle invocations to.
4297 * @param {import('lodash').ThrottleSettings} [options] The options object. See linked documentation for details.
4298 * @return {import('lodash').DebouncedFunc<TFunc>} Throttled function.
4299 */
4300
4301 function useThrottle(fn, wait, options) {
4302 const throttled = useMemoOne(() => (0,external_lodash_namespaceObject.throttle)(fn, wait, options), [fn, wait, options]);
4303 (0,external_wp_element_namespaceObject.useEffect)(() => () => throttled.cancel(), [throttled]);
4304 return throttled;
4305 }
4306
4307 ;// CONCATENATED MODULE: ./packages/compose/build-module/hooks/use-drop-zone/index.js
4308 /**
4309 * WordPress dependencies
4310 */
4311
4312 /**
4313 * Internal dependencies
4314 */
4315
4316
4317 /* eslint-disable jsdoc/valid-types */
4318
4319 /**
4320 * @template T
4321 * @param {T} value
4322 * @return {import('react').MutableRefObject<T>} A ref with the value.
4323 */
4324
4325 function useFreshRef(value) {
4326 /* eslint-enable jsdoc/valid-types */
4327
4328 /* eslint-disable jsdoc/no-undefined-types */
4329
4330 /** @type {import('react').MutableRefObject<T>} */
4331
4332 /* eslint-enable jsdoc/no-undefined-types */
4333 // Disable reason: We're doing something pretty JavaScript-y here where the
4334 // ref will always have a current value that is not null or undefined but it
4335 // needs to start as undefined. We don't want to change the return type so
4336 // it's easier to just ts-ignore this specific line that's complaining about
4337 // undefined not being part of T.
4338 // @ts-ignore
4339 const ref = (0,external_wp_element_namespaceObject.useRef)();
4340 ref.current = value;
4341 return ref;
4342 }
4343 /**
4344 * A hook to facilitate drag and drop handling.
4345 *
4346 * @param {Object} props Named parameters.
4347 * @param {boolean} props.isDisabled Whether or not to disable the drop zone.
4348 * @param {(e: DragEvent) => void} props.onDragStart Called when dragging has started.
4349 * @param {(e: DragEvent) => void} props.onDragEnter Called when the zone is entered.
4350 * @param {(e: DragEvent) => void} props.onDragOver Called when the zone is moved within.
4351 * @param {(e: DragEvent) => void} props.onDragLeave Called when the zone is left.
4352 * @param {(e: MouseEvent) => void} props.onDragEnd Called when dragging has ended.
4353 * @param {(e: DragEvent) => void} props.onDrop Called when dropping in the zone.
4354 *
4355 * @return {import('react').RefCallback<HTMLElement>} Ref callback to be passed to the drop zone element.
4356 */
4357
4358
4359 function useDropZone(_ref) {
4360 let {
4361 isDisabled,
4362 onDrop: _onDrop,
4363 onDragStart: _onDragStart,
4364 onDragEnter: _onDragEnter,
4365 onDragLeave: _onDragLeave,
4366 onDragEnd: _onDragEnd,
4367 onDragOver: _onDragOver
4368 } = _ref;
4369 const onDropRef = useFreshRef(_onDrop);
4370 const onDragStartRef = useFreshRef(_onDragStart);
4371 const onDragEnterRef = useFreshRef(_onDragEnter);
4372 const onDragLeaveRef = useFreshRef(_onDragLeave);
4373 const onDragEndRef = useFreshRef(_onDragEnd);
4374 const onDragOverRef = useFreshRef(_onDragOver);
4375 return useRefEffect(element => {
4376 if (isDisabled) {
4377 return;
4378 }
4379
4380 let isDragging = false;
4381 const {
4382 ownerDocument
4383 } = element;
4384 /**
4385 * Checks if an element is in the drop zone.
4386 *
4387 * @param {EventTarget|null} targetToCheck
4388 *
4389 * @return {boolean} True if in drop zone, false if not.
4390 */
4391
4392 function isElementInZone(targetToCheck) {
4393 const {
4394 defaultView
4395 } = ownerDocument;
4396
4397 if (!targetToCheck || !defaultView || !(targetToCheck instanceof defaultView.HTMLElement) || !element.contains(targetToCheck)) {
4398 return false;
4399 }
4400 /** @type {HTMLElement|null} */
4401
4402
4403 let elementToCheck = targetToCheck;
4404
4405 do {
4406 if (elementToCheck.dataset.isDropZone) {
4407 return elementToCheck === element;
4408 }
4409 } while (elementToCheck = elementToCheck.parentElement);
4410
4411 return false;
4412 }
4413
4414 function maybeDragStart(
4415 /** @type {DragEvent} */
4416 event) {
4417 if (isDragging) {
4418 return;
4419 }
4420
4421 isDragging = true;
4422 ownerDocument.removeEventListener('dragenter', maybeDragStart); // Note that `dragend` doesn't fire consistently for file and
4423 // HTML drag events where the drag origin is outside the browser
4424 // window. In Firefox it may also not fire if the originating
4425 // node is removed.
4426
4427 ownerDocument.addEventListener('dragend', maybeDragEnd);
4428 ownerDocument.addEventListener('mousemove', maybeDragEnd);
4429
4430 if (onDragStartRef.current) {
4431 onDragStartRef.current(event);
4432 }
4433 }
4434
4435 function onDragEnter(
4436 /** @type {DragEvent} */
4437 event) {
4438 event.preventDefault(); // The `dragenter` event will also fire when entering child
4439 // elements, but we only want to call `onDragEnter` when
4440 // entering the drop zone, which means the `relatedTarget`
4441 // (element that has been left) should be outside the drop zone.
4442
4443 if (element.contains(
4444 /** @type {Node} */
4445 event.relatedTarget)) {
4446 return;
4447 }
4448
4449 if (onDragEnterRef.current) {
4450 onDragEnterRef.current(event);
4451 }
4452 }
4453
4454 function onDragOver(
4455 /** @type {DragEvent} */
4456 event) {
4457 // Only call onDragOver for the innermost hovered drop zones.
4458 if (!event.defaultPrevented && onDragOverRef.current) {
4459 onDragOverRef.current(event);
4460 } // Prevent the browser default while also signalling to parent
4461 // drop zones that `onDragOver` is already handled.
4462
4463
4464 event.preventDefault();
4465 }
4466
4467 function onDragLeave(
4468 /** @type {DragEvent} */
4469 event) {
4470 // The `dragleave` event will also fire when leaving child
4471 // elements, but we only want to call `onDragLeave` when
4472 // leaving the drop zone, which means the `relatedTarget`
4473 // (element that has been entered) should be outside the drop
4474 // zone.
4475 if (isElementInZone(event.relatedTarget)) {
4476 return;
4477 }
4478
4479 if (onDragLeaveRef.current) {
4480 onDragLeaveRef.current(event);
4481 }
4482 }
4483
4484 function onDrop(
4485 /** @type {DragEvent} */
4486 event) {
4487 // Don't handle drop if an inner drop zone already handled it.
4488 if (event.defaultPrevented) {
4489 return;
4490 } // Prevent the browser default while also signalling to parent
4491 // drop zones that `onDrop` is already handled.
4492
4493
4494 event.preventDefault(); // This seemingly useless line has been shown to resolve a
4495 // Safari issue where files dragged directly from the dock are
4496 // not recognized.
4497 // eslint-disable-next-line no-unused-expressions
4498
4499 event.dataTransfer && event.dataTransfer.files.length;
4500
4501 if (onDropRef.current) {
4502 onDropRef.current(event);
4503 }
4504
4505 maybeDragEnd(event);
4506 }
4507
4508 function maybeDragEnd(
4509 /** @type {MouseEvent} */
4510 event) {
4511 if (!isDragging) {
4512 return;
4513 }
4514
4515 isDragging = false;
4516 ownerDocument.addEventListener('dragenter', maybeDragStart);
4517 ownerDocument.removeEventListener('dragend', maybeDragEnd);
4518 ownerDocument.removeEventListener('mousemove', maybeDragEnd);
4519
4520 if (onDragEndRef.current) {
4521 onDragEndRef.current(event);
4522 }
4523 }
4524
4525 element.dataset.isDropZone = 'true';
4526 element.addEventListener('drop', onDrop);
4527 element.addEventListener('dragenter', onDragEnter);
4528 element.addEventListener('dragover', onDragOver);
4529 element.addEventListener('dragleave', onDragLeave); // The `dragstart` event doesn't fire if the drag started outside
4530 // the document.
4531
4532 ownerDocument.addEventListener('dragenter', maybeDragStart);
4533 return () => {
4534 delete element.dataset.isDropZone;
4535 element.removeEventListener('drop', onDrop);
4536 element.removeEventListener('dragenter', onDragEnter);
4537 element.removeEventListener('dragover', onDragOver);
4538 element.removeEventListener('dragleave', onDragLeave);
4539 ownerDocument.removeEventListener('dragend', maybeDragEnd);
4540 ownerDocument.removeEventListener('mousemove', maybeDragEnd);
4541 ownerDocument.addEventListener('dragenter', maybeDragStart);
4542 };
4543 }, [isDisabled]);
4544 }
4545
4546 ;// CONCATENATED MODULE: ./packages/compose/build-module/hooks/use-focusable-iframe/index.js
4547 /**
4548 * Internal dependencies
4549 */
4550
4551 /**
4552 * Dispatches a bubbling focus event when the iframe receives focus. Use
4553 * `onFocus` as usual on the iframe or a parent element.
4554 *
4555 * @return {Object} Ref to pass to the iframe.
4556 */
4557
4558 function useFocusableIframe() {
4559 return useRefEffect(element => {
4560 const {
4561 ownerDocument
4562 } = element;
4563 if (!ownerDocument) return;
4564 const {
4565 defaultView
4566 } = ownerDocument;
4567 if (!defaultView) return;
4568 /**
4569 * Checks whether the iframe is the activeElement, inferring that it has
4570 * then received focus, and dispatches a focus event.
4571 */
4572
4573 function checkFocus() {
4574 if (ownerDocument && ownerDocument.activeElement === element) {
4575 /** @type {HTMLElement} */
4576 element.focus();
4577 }
4578 }
4579
4580 defaultView.addEventListener('blur', checkFocus);
4581 return () => {
4582 defaultView.removeEventListener('blur', checkFocus);
4583 };
4584 }, []);
4585 }
4586
4587 ;// CONCATENATED MODULE: ./packages/compose/build-module/hooks/use-fixed-window-list/index.js
4588 /**
4589 * External dependencies
4590 */
4591
4592 /**
4593 * WordPress dependencies
4594 */
4595
4596
4597
4598
4599 const DEFAULT_INIT_WINDOW_SIZE = 30;
4600 /**
4601 * @typedef {Object} WPFixedWindowList
4602 *
4603 * @property {number} visibleItems Items visible in the current viewport
4604 * @property {number} start Start index of the window
4605 * @property {number} end End index of the window
4606 * @property {(index:number)=>boolean} itemInView Returns true if item is in the window
4607 */
4608
4609 /**
4610 * @typedef {Object} WPFixedWindowListOptions
4611 *
4612 * @property {number} [windowOverscan] Renders windowOverscan number of items before and after the calculated visible window.
4613 * @property {boolean} [useWindowing] When false avoids calculating the window size
4614 * @property {number} [initWindowSize] Initial window size to use on first render before we can calculate the window size.
4615 */
4616
4617 /**
4618 *
4619 * @param {import('react').RefObject<HTMLElement>} elementRef Used to find the closest scroll container that contains element.
4620 * @param { number } itemHeight Fixed item height in pixels
4621 * @param { number } totalItems Total items in list
4622 * @param { WPFixedWindowListOptions } [options] Options object
4623 * @return {[ WPFixedWindowList, setFixedListWindow:(nextWindow:WPFixedWindowList)=>void]} Array with the fixed window list and setter
4624 */
4625
4626 function useFixedWindowList(elementRef, itemHeight, totalItems, options) {
4627 var _options$initWindowSi, _options$useWindowing;
4628
4629 const initWindowSize = (_options$initWindowSi = options === null || options === void 0 ? void 0 : options.initWindowSize) !== null && _options$initWindowSi !== void 0 ? _options$initWindowSi : DEFAULT_INIT_WINDOW_SIZE;
4630 const useWindowing = (_options$useWindowing = options === null || options === void 0 ? void 0 : options.useWindowing) !== null && _options$useWindowing !== void 0 ? _options$useWindowing : true;
4631 const [fixedListWindow, setFixedListWindow] = (0,external_wp_element_namespaceObject.useState)({
4632 visibleItems: initWindowSize,
4633 start: 0,
4634 end: initWindowSize,
4635 itemInView: (
4636 /** @type {number} */
4637 index) => {
4638 return index >= 0 && index <= initWindowSize;
4639 }
4640 });
4641 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => {
4642 var _scrollContainer$owne, _scrollContainer$owne2, _scrollContainer$owne3, _scrollContainer$owne4;
4643
4644 if (!useWindowing) {
4645 return;
4646 }
4647
4648 const scrollContainer = (0,external_wp_dom_namespaceObject.getScrollContainer)(elementRef.current);
4649
4650 const measureWindow = (
4651 /** @type {boolean | undefined} */
4652 initRender) => {
4653 var _options$windowOversc;
4654
4655 if (!scrollContainer) {
4656 return;
4657 }
4658
4659 const visibleItems = Math.ceil(scrollContainer.clientHeight / itemHeight); // Aim to keep opening list view fast, afterward we can optimize for scrolling
4660
4661 const windowOverscan = initRender ? visibleItems : (_options$windowOversc = options === null || options === void 0 ? void 0 : options.windowOverscan) !== null && _options$windowOversc !== void 0 ? _options$windowOversc : visibleItems;
4662 const firstViewableIndex = Math.floor(scrollContainer.scrollTop / itemHeight);
4663 const start = Math.max(0, firstViewableIndex - windowOverscan);
4664 const end = Math.min(totalItems - 1, firstViewableIndex + visibleItems + windowOverscan);
4665 setFixedListWindow(lastWindow => {
4666 const nextWindow = {
4667 visibleItems,
4668 start,
4669 end,
4670 itemInView: (
4671 /** @type {number} */
4672 index) => {
4673 return start <= index && index <= end;
4674 }
4675 };
4676
4677 if (lastWindow.start !== nextWindow.start || lastWindow.end !== nextWindow.end || lastWindow.visibleItems !== nextWindow.visibleItems) {
4678 return nextWindow;
4679 }
4680
4681 return lastWindow;
4682 });
4683 };
4684
4685 measureWindow(true);
4686 const debounceMeasureList = (0,external_lodash_namespaceObject.debounce)(() => {
4687 measureWindow();
4688 }, 16);
4689 scrollContainer === null || scrollContainer === void 0 ? void 0 : scrollContainer.addEventListener('scroll', debounceMeasureList);
4690 scrollContainer === null || scrollContainer === void 0 ? void 0 : (_scrollContainer$owne = scrollContainer.ownerDocument) === null || _scrollContainer$owne === void 0 ? void 0 : (_scrollContainer$owne2 = _scrollContainer$owne.defaultView) === null || _scrollContainer$owne2 === void 0 ? void 0 : _scrollContainer$owne2.addEventListener('resize', debounceMeasureList);
4691 scrollContainer === null || scrollContainer === void 0 ? void 0 : (_scrollContainer$owne3 = scrollContainer.ownerDocument) === null || _scrollContainer$owne3 === void 0 ? void 0 : (_scrollContainer$owne4 = _scrollContainer$owne3.defaultView) === null || _scrollContainer$owne4 === void 0 ? void 0 : _scrollContainer$owne4.addEventListener('resize', debounceMeasureList);
4692 return () => {
4693 var _scrollContainer$owne5, _scrollContainer$owne6;
4694
4695 scrollContainer === null || scrollContainer === void 0 ? void 0 : scrollContainer.removeEventListener('scroll', debounceMeasureList);
4696 scrollContainer === null || scrollContainer === void 0 ? void 0 : (_scrollContainer$owne5 = scrollContainer.ownerDocument) === null || _scrollContainer$owne5 === void 0 ? void 0 : (_scrollContainer$owne6 = _scrollContainer$owne5.defaultView) === null || _scrollContainer$owne6 === void 0 ? void 0 : _scrollContainer$owne6.removeEventListener('resize', debounceMeasureList);
4697 };
4698 }, [itemHeight, elementRef, totalItems]);
4699 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => {
4700 var _scrollContainer$owne7, _scrollContainer$owne8;
4701
4702 if (!useWindowing) {
4703 return;
4704 }
4705
4706 const scrollContainer = (0,external_wp_dom_namespaceObject.getScrollContainer)(elementRef.current);
4707
4708 const handleKeyDown = (
4709 /** @type {KeyboardEvent} */
4710 event) => {
4711 switch (event.keyCode) {
4712 case external_wp_keycodes_namespaceObject.HOME:
4713 {
4714 return scrollContainer === null || scrollContainer === void 0 ? void 0 : scrollContainer.scrollTo({
4715 top: 0
4716 });
4717 }
4718
4719 case external_wp_keycodes_namespaceObject.END:
4720 {
4721 return scrollContainer === null || scrollContainer === void 0 ? void 0 : scrollContainer.scrollTo({
4722 top: totalItems * itemHeight
4723 });
4724 }
4725
4726 case external_wp_keycodes_namespaceObject.PAGEUP:
4727 {
4728 return scrollContainer === null || scrollContainer === void 0 ? void 0 : scrollContainer.scrollTo({
4729 top: scrollContainer.scrollTop - fixedListWindow.visibleItems * itemHeight
4730 });
4731 }
4732
4733 case external_wp_keycodes_namespaceObject.PAGEDOWN:
4734 {
4735 return scrollContainer === null || scrollContainer === void 0 ? void 0 : scrollContainer.scrollTo({
4736 top: scrollContainer.scrollTop + fixedListWindow.visibleItems * itemHeight
4737 });
4738 }
4739 }
4740 };
4741
4742 scrollContainer === null || scrollContainer === void 0 ? void 0 : (_scrollContainer$owne7 = scrollContainer.ownerDocument) === null || _scrollContainer$owne7 === void 0 ? void 0 : (_scrollContainer$owne8 = _scrollContainer$owne7.defaultView) === null || _scrollContainer$owne8 === void 0 ? void 0 : _scrollContainer$owne8.addEventListener('keydown', handleKeyDown);
4743 return () => {
4744 var _scrollContainer$owne9, _scrollContainer$owne10;
4745
4746 scrollContainer === null || scrollContainer === void 0 ? void 0 : (_scrollContainer$owne9 = scrollContainer.ownerDocument) === null || _scrollContainer$owne9 === void 0 ? void 0 : (_scrollContainer$owne10 = _scrollContainer$owne9.defaultView) === null || _scrollContainer$owne10 === void 0 ? void 0 : _scrollContainer$owne10.removeEventListener('keydown', handleKeyDown);
4747 };
4748 }, [totalItems, itemHeight, elementRef, fixedListWindow.visibleItems]);
4749 return [fixedListWindow, setFixedListWindow];
4750 }
4751
4752 ;// CONCATENATED MODULE: ./packages/compose/build-module/index.js
4753 // Utils
4754 // Compose helper (aliased flowRight from Lodash)
4755
4756 // Higher-order components
4757
4758
4759
4760
4761
4762
4763 // Hooks
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792 }();
4793 (window.wp = window.wp || {}).compose = __webpack_exports__;
4794 /******/ })()
4795 ;