[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 /******/ (() => { // webpackBootstrap 2 /******/ var __webpack_modules__ = ({ 3 4 /***/ 4306: 5 /***/ (function(module, exports) { 6 7 var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! 8 autosize 4.0.4 9 license: MIT 10 http://www.jacklmoore.com/autosize 11 */ 12 (function (global, factory) { 13 if (true) { 14 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [module, exports], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 15 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 16 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), 17 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 18 } else { var mod; } 19 })(this, function (module, exports) { 20 'use strict'; 21 22 var map = typeof Map === "function" ? new Map() : function () { 23 var keys = []; 24 var values = []; 25 26 return { 27 has: function has(key) { 28 return keys.indexOf(key) > -1; 29 }, 30 get: function get(key) { 31 return values[keys.indexOf(key)]; 32 }, 33 set: function set(key, value) { 34 if (keys.indexOf(key) === -1) { 35 keys.push(key); 36 values.push(value); 37 } 38 }, 39 delete: function _delete(key) { 40 var index = keys.indexOf(key); 41 if (index > -1) { 42 keys.splice(index, 1); 43 values.splice(index, 1); 44 } 45 } 46 }; 47 }(); 48 49 var createEvent = function createEvent(name) { 50 return new Event(name, { bubbles: true }); 51 }; 52 try { 53 new Event('test'); 54 } catch (e) { 55 // IE does not support `new Event()` 56 createEvent = function createEvent(name) { 57 var evt = document.createEvent('Event'); 58 evt.initEvent(name, true, false); 59 return evt; 60 }; 61 } 62 63 function assign(ta) { 64 if (!ta || !ta.nodeName || ta.nodeName !== 'TEXTAREA' || map.has(ta)) return; 65 66 var heightOffset = null; 67 var clientWidth = null; 68 var cachedHeight = null; 69 70 function init() { 71 var style = window.getComputedStyle(ta, null); 72 73 if (style.resize === 'vertical') { 74 ta.style.resize = 'none'; 75 } else if (style.resize === 'both') { 76 ta.style.resize = 'horizontal'; 77 } 78 79 if (style.boxSizing === 'content-box') { 80 heightOffset = -(parseFloat(style.paddingTop) + parseFloat(style.paddingBottom)); 81 } else { 82 heightOffset = parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth); 83 } 84 // Fix when a textarea is not on document body and heightOffset is Not a Number 85 if (isNaN(heightOffset)) { 86 heightOffset = 0; 87 } 88 89 update(); 90 } 91 92 function changeOverflow(value) { 93 { 94 // Chrome/Safari-specific fix: 95 // When the textarea y-overflow is hidden, Chrome/Safari do not reflow the text to account for the space 96 // made available by removing the scrollbar. The following forces the necessary text reflow. 97 var width = ta.style.width; 98 ta.style.width = '0px'; 99 // Force reflow: 100 /* jshint ignore:start */ 101 ta.offsetWidth; 102 /* jshint ignore:end */ 103 ta.style.width = width; 104 } 105 106 ta.style.overflowY = value; 107 } 108 109 function getParentOverflows(el) { 110 var arr = []; 111 112 while (el && el.parentNode && el.parentNode instanceof Element) { 113 if (el.parentNode.scrollTop) { 114 arr.push({ 115 node: el.parentNode, 116 scrollTop: el.parentNode.scrollTop 117 }); 118 } 119 el = el.parentNode; 120 } 121 122 return arr; 123 } 124 125 function resize() { 126 if (ta.scrollHeight === 0) { 127 // If the scrollHeight is 0, then the element probably has display:none or is detached from the DOM. 128 return; 129 } 130 131 var overflows = getParentOverflows(ta); 132 var docTop = document.documentElement && document.documentElement.scrollTop; // Needed for Mobile IE (ticket #240) 133 134 ta.style.height = ''; 135 ta.style.height = ta.scrollHeight + heightOffset + 'px'; 136 137 // used to check if an update is actually necessary on window.resize 138 clientWidth = ta.clientWidth; 139 140 // prevents scroll-position jumping 141 overflows.forEach(function (el) { 142 el.node.scrollTop = el.scrollTop; 143 }); 144 145 if (docTop) { 146 document.documentElement.scrollTop = docTop; 147 } 148 } 149 150 function update() { 151 resize(); 152 153 var styleHeight = Math.round(parseFloat(ta.style.height)); 154 var computed = window.getComputedStyle(ta, null); 155 156 // Using offsetHeight as a replacement for computed.height in IE, because IE does not account use of border-box 157 var actualHeight = computed.boxSizing === 'content-box' ? Math.round(parseFloat(computed.height)) : ta.offsetHeight; 158 159 // The actual height not matching the style height (set via the resize method) indicates that 160 // the max-height has been exceeded, in which case the overflow should be allowed. 161 if (actualHeight < styleHeight) { 162 if (computed.overflowY === 'hidden') { 163 changeOverflow('scroll'); 164 resize(); 165 actualHeight = computed.boxSizing === 'content-box' ? Math.round(parseFloat(window.getComputedStyle(ta, null).height)) : ta.offsetHeight; 166 } 167 } else { 168 // Normally keep overflow set to hidden, to avoid flash of scrollbar as the textarea expands. 169 if (computed.overflowY !== 'hidden') { 170 changeOverflow('hidden'); 171 resize(); 172 actualHeight = computed.boxSizing === 'content-box' ? Math.round(parseFloat(window.getComputedStyle(ta, null).height)) : ta.offsetHeight; 173 } 174 } 175 176 if (cachedHeight !== actualHeight) { 177 cachedHeight = actualHeight; 178 var evt = createEvent('autosize:resized'); 179 try { 180 ta.dispatchEvent(evt); 181 } catch (err) { 182 // Firefox will throw an error on dispatchEvent for a detached element 183 // https://bugzilla.mozilla.org/show_bug.cgi?id=889376 184 } 185 } 186 } 187 188 var pageResize = function pageResize() { 189 if (ta.clientWidth !== clientWidth) { 190 update(); 191 } 192 }; 193 194 var destroy = function (style) { 195 window.removeEventListener('resize', pageResize, false); 196 ta.removeEventListener('input', update, false); 197 ta.removeEventListener('keyup', update, false); 198 ta.removeEventListener('autosize:destroy', destroy, false); 199 ta.removeEventListener('autosize:update', update, false); 200 201 Object.keys(style).forEach(function (key) { 202 ta.style[key] = style[key]; 203 }); 204 205 map.delete(ta); 206 }.bind(ta, { 207 height: ta.style.height, 208 resize: ta.style.resize, 209 overflowY: ta.style.overflowY, 210 overflowX: ta.style.overflowX, 211 wordWrap: ta.style.wordWrap 212 }); 213 214 ta.addEventListener('autosize:destroy', destroy, false); 215 216 // IE9 does not fire onpropertychange or oninput for deletions, 217 // so binding to onkeyup to catch most of those events. 218 // There is no way that I know of to detect something like 'cut' in IE9. 219 if ('onpropertychange' in ta && 'oninput' in ta) { 220 ta.addEventListener('keyup', update, false); 221 } 222 223 window.addEventListener('resize', pageResize, false); 224 ta.addEventListener('input', update, false); 225 ta.addEventListener('autosize:update', update, false); 226 ta.style.overflowX = 'hidden'; 227 ta.style.wordWrap = 'break-word'; 228 229 map.set(ta, { 230 destroy: destroy, 231 update: update 232 }); 233 234 init(); 235 } 236 237 function destroy(ta) { 238 var methods = map.get(ta); 239 if (methods) { 240 methods.destroy(); 241 } 242 } 243 244 function update(ta) { 245 var methods = map.get(ta); 246 if (methods) { 247 methods.update(); 248 } 249 } 250 251 var autosize = null; 252 253 // Do nothing in Node.js environment and IE8 (or lower) 254 if (typeof window === 'undefined' || typeof window.getComputedStyle !== 'function') { 255 autosize = function autosize(el) { 256 return el; 257 }; 258 autosize.destroy = function (el) { 259 return el; 260 }; 261 autosize.update = function (el) { 262 return el; 263 }; 264 } else { 265 autosize = function autosize(el, options) { 266 if (el) { 267 Array.prototype.forEach.call(el.length ? el : [el], function (x) { 268 return assign(x, options); 269 }); 270 } 271 return el; 272 }; 273 autosize.destroy = function (el) { 274 if (el) { 275 Array.prototype.forEach.call(el.length ? el : [el], destroy); 276 } 277 return el; 278 }; 279 autosize.update = function (el) { 280 if (el) { 281 Array.prototype.forEach.call(el.length ? el : [el], update); 282 } 283 return el; 284 }; 285 } 286 287 exports.default = autosize; 288 module.exports = exports['default']; 289 }); 290 291 /***/ }), 292 293 /***/ 5755: 294 /***/ ((module, exports) => { 295 296 var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! 297 Copyright (c) 2018 Jed Watson. 298 Licensed under the MIT License (MIT), see 299 http://jedwatson.github.io/classnames 300 */ 301 /* global define */ 302 303 (function () { 304 'use strict'; 305 306 var hasOwn = {}.hasOwnProperty; 307 var nativeCodeString = '[native code]'; 308 309 function classNames() { 310 var classes = []; 311 312 for (var i = 0; i < arguments.length; i++) { 313 var arg = arguments[i]; 314 if (!arg) continue; 315 316 var argType = typeof arg; 317 318 if (argType === 'string' || argType === 'number') { 319 classes.push(arg); 320 } else if (Array.isArray(arg)) { 321 if (arg.length) { 322 var inner = classNames.apply(null, arg); 323 if (inner) { 324 classes.push(inner); 325 } 326 } 327 } else if (argType === 'object') { 328 if (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes('[native code]')) { 329 classes.push(arg.toString()); 330 continue; 331 } 332 333 for (var key in arg) { 334 if (hasOwn.call(arg, key) && arg[key]) { 335 classes.push(key); 336 } 337 } 338 } 339 } 340 341 return classes.join(' '); 342 } 343 344 if ( true && module.exports) { 345 classNames.default = classNames; 346 module.exports = classNames; 347 } else if (true) { 348 // register as 'classnames', consistent with npm package name 349 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function () { 350 return classNames; 351 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 352 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 353 } else {} 354 }()); 355 356 357 /***/ }), 358 359 /***/ 6109: 360 /***/ ((module) => { 361 362 // This code has been refactored for 140 bytes 363 // You can see the original here: https://github.com/twolfson/computedStyle/blob/04cd1da2e30fa45844f95f5cb1ac898e9b9ef050/lib/computedStyle.js 364 var computedStyle = function (el, prop, getComputedStyle) { 365 getComputedStyle = window.getComputedStyle; 366 367 // In one fell swoop 368 return ( 369 // If we have getComputedStyle 370 getComputedStyle ? 371 // Query it 372 // TODO: From CSS-Query notes, we might need (node, null) for FF 373 getComputedStyle(el) : 374 375 // Otherwise, we are in IE and use currentStyle 376 el.currentStyle 377 )[ 378 // Switch to camelCase for CSSOM 379 // DEV: Grabbed from jQuery 380 // https://github.com/jquery/jquery/blob/1.9-stable/src/css.js#L191-L194 381 // https://github.com/jquery/jquery/blob/1.9-stable/src/core.js#L593-L597 382 prop.replace(/-(\w)/gi, function (word, letter) { 383 return letter.toUpperCase(); 384 }) 385 ]; 386 }; 387 388 module.exports = computedStyle; 389 390 391 /***/ }), 392 393 /***/ 5417: 394 /***/ ((__unused_webpack_module, exports) => { 395 396 "use strict"; 397 /*istanbul ignore start*/ 398 399 400 Object.defineProperty(exports, "__esModule", ({ 401 value: true 402 })); 403 exports["default"] = Diff; 404 405 /*istanbul ignore end*/ 406 function Diff() {} 407 408 Diff.prototype = { 409 /*istanbul ignore start*/ 410 411 /*istanbul ignore end*/ 412 diff: function diff(oldString, newString) { 413 /*istanbul ignore start*/ 414 var 415 /*istanbul ignore end*/ 416 options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 417 var callback = options.callback; 418 419 if (typeof options === 'function') { 420 callback = options; 421 options = {}; 422 } 423 424 this.options = options; 425 var self = this; 426 427 function done(value) { 428 if (callback) { 429 setTimeout(function () { 430 callback(undefined, value); 431 }, 0); 432 return true; 433 } else { 434 return value; 435 } 436 } // Allow subclasses to massage the input prior to running 437 438 439 oldString = this.castInput(oldString); 440 newString = this.castInput(newString); 441 oldString = this.removeEmpty(this.tokenize(oldString)); 442 newString = this.removeEmpty(this.tokenize(newString)); 443 var newLen = newString.length, 444 oldLen = oldString.length; 445 var editLength = 1; 446 var maxEditLength = newLen + oldLen; 447 var bestPath = [{ 448 newPos: -1, 449 components: [] 450 }]; // Seed editLength = 0, i.e. the content starts with the same values 451 452 var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0); 453 454 if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) { 455 // Identity per the equality and tokenizer 456 return done([{ 457 value: this.join(newString), 458 count: newString.length 459 }]); 460 } // Main worker method. checks all permutations of a given edit length for acceptance. 461 462 463 function execEditLength() { 464 for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) { 465 var basePath = 466 /*istanbul ignore start*/ 467 void 0 468 /*istanbul ignore end*/ 469 ; 470 471 var addPath = bestPath[diagonalPath - 1], 472 removePath = bestPath[diagonalPath + 1], 473 _oldPos = (removePath ? removePath.newPos : 0) - diagonalPath; 474 475 if (addPath) { 476 // No one else is going to attempt to use this value, clear it 477 bestPath[diagonalPath - 1] = undefined; 478 } 479 480 var canAdd = addPath && addPath.newPos + 1 < newLen, 481 canRemove = removePath && 0 <= _oldPos && _oldPos < oldLen; 482 483 if (!canAdd && !canRemove) { 484 // If this path is a terminal then prune 485 bestPath[diagonalPath] = undefined; 486 continue; 487 } // Select the diagonal that we want to branch from. We select the prior 488 // path whose position in the new string is the farthest from the origin 489 // and does not pass the bounds of the diff graph 490 491 492 if (!canAdd || canRemove && addPath.newPos < removePath.newPos) { 493 basePath = clonePath(removePath); 494 self.pushComponent(basePath.components, undefined, true); 495 } else { 496 basePath = addPath; // No need to clone, we've pulled it from the list 497 498 basePath.newPos++; 499 self.pushComponent(basePath.components, true, undefined); 500 } 501 502 _oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath); // If we have hit the end of both strings, then we are done 503 504 if (basePath.newPos + 1 >= newLen && _oldPos + 1 >= oldLen) { 505 return done(buildValues(self, basePath.components, newString, oldString, self.useLongestToken)); 506 } else { 507 // Otherwise track this path as a potential candidate and continue. 508 bestPath[diagonalPath] = basePath; 509 } 510 } 511 512 editLength++; 513 } // Performs the length of edit iteration. Is a bit fugly as this has to support the 514 // sync and async mode which is never fun. Loops over execEditLength until a value 515 // is produced. 516 517 518 if (callback) { 519 (function exec() { 520 setTimeout(function () { 521 // This should not happen, but we want to be safe. 522 523 /* istanbul ignore next */ 524 if (editLength > maxEditLength) { 525 return callback(); 526 } 527 528 if (!execEditLength()) { 529 exec(); 530 } 531 }, 0); 532 })(); 533 } else { 534 while (editLength <= maxEditLength) { 535 var ret = execEditLength(); 536 537 if (ret) { 538 return ret; 539 } 540 } 541 } 542 }, 543 544 /*istanbul ignore start*/ 545 546 /*istanbul ignore end*/ 547 pushComponent: function pushComponent(components, added, removed) { 548 var last = components[components.length - 1]; 549 550 if (last && last.added === added && last.removed === removed) { 551 // We need to clone here as the component clone operation is just 552 // as shallow array clone 553 components[components.length - 1] = { 554 count: last.count + 1, 555 added: added, 556 removed: removed 557 }; 558 } else { 559 components.push({ 560 count: 1, 561 added: added, 562 removed: removed 563 }); 564 } 565 }, 566 567 /*istanbul ignore start*/ 568 569 /*istanbul ignore end*/ 570 extractCommon: function extractCommon(basePath, newString, oldString, diagonalPath) { 571 var newLen = newString.length, 572 oldLen = oldString.length, 573 newPos = basePath.newPos, 574 oldPos = newPos - diagonalPath, 575 commonCount = 0; 576 577 while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) { 578 newPos++; 579 oldPos++; 580 commonCount++; 581 } 582 583 if (commonCount) { 584 basePath.components.push({ 585 count: commonCount 586 }); 587 } 588 589 basePath.newPos = newPos; 590 return oldPos; 591 }, 592 593 /*istanbul ignore start*/ 594 595 /*istanbul ignore end*/ 596 equals: function equals(left, right) { 597 if (this.options.comparator) { 598 return this.options.comparator(left, right); 599 } else { 600 return left === right || this.options.ignoreCase && left.toLowerCase() === right.toLowerCase(); 601 } 602 }, 603 604 /*istanbul ignore start*/ 605 606 /*istanbul ignore end*/ 607 removeEmpty: function removeEmpty(array) { 608 var ret = []; 609 610 for (var i = 0; i < array.length; i++) { 611 if (array[i]) { 612 ret.push(array[i]); 613 } 614 } 615 616 return ret; 617 }, 618 619 /*istanbul ignore start*/ 620 621 /*istanbul ignore end*/ 622 castInput: function castInput(value) { 623 return value; 624 }, 625 626 /*istanbul ignore start*/ 627 628 /*istanbul ignore end*/ 629 tokenize: function tokenize(value) { 630 return value.split(''); 631 }, 632 633 /*istanbul ignore start*/ 634 635 /*istanbul ignore end*/ 636 join: function join(chars) { 637 return chars.join(''); 638 } 639 }; 640 641 function buildValues(diff, components, newString, oldString, useLongestToken) { 642 var componentPos = 0, 643 componentLen = components.length, 644 newPos = 0, 645 oldPos = 0; 646 647 for (; componentPos < componentLen; componentPos++) { 648 var component = components[componentPos]; 649 650 if (!component.removed) { 651 if (!component.added && useLongestToken) { 652 var value = newString.slice(newPos, newPos + component.count); 653 value = value.map(function (value, i) { 654 var oldValue = oldString[oldPos + i]; 655 return oldValue.length > value.length ? oldValue : value; 656 }); 657 component.value = diff.join(value); 658 } else { 659 component.value = diff.join(newString.slice(newPos, newPos + component.count)); 660 } 661 662 newPos += component.count; // Common case 663 664 if (!component.added) { 665 oldPos += component.count; 666 } 667 } else { 668 component.value = diff.join(oldString.slice(oldPos, oldPos + component.count)); 669 oldPos += component.count; // Reverse add and remove so removes are output first to match common convention 670 // The diffing algorithm is tied to add then remove output and this is the simplest 671 // route to get the desired output with minimal overhead. 672 673 if (componentPos && components[componentPos - 1].added) { 674 var tmp = components[componentPos - 1]; 675 components[componentPos - 1] = components[componentPos]; 676 components[componentPos] = tmp; 677 } 678 } 679 } // Special case handle for when one terminal is ignored (i.e. whitespace). 680 // For this case we merge the terminal into the prior string and drop the change. 681 // This is only available for string mode. 682 683 684 var lastComponent = components[componentLen - 1]; 685 686 if (componentLen > 1 && typeof lastComponent.value === 'string' && (lastComponent.added || lastComponent.removed) && diff.equals('', lastComponent.value)) { 687 components[componentLen - 2].value += lastComponent.value; 688 components.pop(); 689 } 690 691 return components; 692 } 693 694 function clonePath(path) { 695 return { 696 newPos: path.newPos, 697 components: path.components.slice(0) 698 }; 699 } 700 701 702 /***/ }), 703 704 /***/ 8021: 705 /***/ ((__unused_webpack_module, exports, __webpack_require__) => { 706 707 "use strict"; 708 var __webpack_unused_export__; 709 /*istanbul ignore start*/ 710 711 712 __webpack_unused_export__ = ({ 713 value: true 714 }); 715 exports.JJ = diffChars; 716 __webpack_unused_export__ = void 0; 717 718 /*istanbul ignore end*/ 719 var 720 /*istanbul ignore start*/ 721 _base = _interopRequireDefault(__webpack_require__(5417)) 722 /*istanbul ignore end*/ 723 ; 724 725 /*istanbul ignore start*/ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 726 727 /*istanbul ignore end*/ 728 var characterDiff = new 729 /*istanbul ignore start*/ 730 _base 731 /*istanbul ignore end*/ 732 . 733 /*istanbul ignore start*/ 734 default 735 /*istanbul ignore end*/ 736 (); 737 738 /*istanbul ignore start*/ 739 __webpack_unused_export__ = characterDiff; 740 741 /*istanbul ignore end*/ 742 function diffChars(oldStr, newStr, options) { 743 return characterDiff.diff(oldStr, newStr, options); 744 } 745 746 747 /***/ }), 748 749 /***/ 1637: 750 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 751 752 "use strict"; 753 754 755 var util = __webpack_require__(3062); 756 757 function scrollIntoView(elem, container, config) { 758 config = config || {}; 759 // document 归一化到 window 760 if (container.nodeType === 9) { 761 container = util.getWindow(container); 762 } 763 764 var allowHorizontalScroll = config.allowHorizontalScroll; 765 var onlyScrollIfNeeded = config.onlyScrollIfNeeded; 766 var alignWithTop = config.alignWithTop; 767 var alignWithLeft = config.alignWithLeft; 768 var offsetTop = config.offsetTop || 0; 769 var offsetLeft = config.offsetLeft || 0; 770 var offsetBottom = config.offsetBottom || 0; 771 var offsetRight = config.offsetRight || 0; 772 773 allowHorizontalScroll = allowHorizontalScroll === undefined ? true : allowHorizontalScroll; 774 775 var isWin = util.isWindow(container); 776 var elemOffset = util.offset(elem); 777 var eh = util.outerHeight(elem); 778 var ew = util.outerWidth(elem); 779 var containerOffset = undefined; 780 var ch = undefined; 781 var cw = undefined; 782 var containerScroll = undefined; 783 var diffTop = undefined; 784 var diffBottom = undefined; 785 var win = undefined; 786 var winScroll = undefined; 787 var ww = undefined; 788 var wh = undefined; 789 790 if (isWin) { 791 win = container; 792 wh = util.height(win); 793 ww = util.width(win); 794 winScroll = { 795 left: util.scrollLeft(win), 796 top: util.scrollTop(win) 797 }; 798 // elem 相对 container 可视视窗的距离 799 diffTop = { 800 left: elemOffset.left - winScroll.left - offsetLeft, 801 top: elemOffset.top - winScroll.top - offsetTop 802 }; 803 diffBottom = { 804 left: elemOffset.left + ew - (winScroll.left + ww) + offsetRight, 805 top: elemOffset.top + eh - (winScroll.top + wh) + offsetBottom 806 }; 807 containerScroll = winScroll; 808 } else { 809 containerOffset = util.offset(container); 810 ch = container.clientHeight; 811 cw = container.clientWidth; 812 containerScroll = { 813 left: container.scrollLeft, 814 top: container.scrollTop 815 }; 816 // elem 相对 container 可视视窗的距离 817 // 注意边框, offset 是边框到根节点 818 diffTop = { 819 left: elemOffset.left - (containerOffset.left + (parseFloat(util.css(container, 'borderLeftWidth')) || 0)) - offsetLeft, 820 top: elemOffset.top - (containerOffset.top + (parseFloat(util.css(container, 'borderTopWidth')) || 0)) - offsetTop 821 }; 822 diffBottom = { 823 left: elemOffset.left + ew - (containerOffset.left + cw + (parseFloat(util.css(container, 'borderRightWidth')) || 0)) + offsetRight, 824 top: elemOffset.top + eh - (containerOffset.top + ch + (parseFloat(util.css(container, 'borderBottomWidth')) || 0)) + offsetBottom 825 }; 826 } 827 828 if (diffTop.top < 0 || diffBottom.top > 0) { 829 // 强制向上 830 if (alignWithTop === true) { 831 util.scrollTop(container, containerScroll.top + diffTop.top); 832 } else if (alignWithTop === false) { 833 util.scrollTop(container, containerScroll.top + diffBottom.top); 834 } else { 835 // 自动调整 836 if (diffTop.top < 0) { 837 util.scrollTop(container, containerScroll.top + diffTop.top); 838 } else { 839 util.scrollTop(container, containerScroll.top + diffBottom.top); 840 } 841 } 842 } else { 843 if (!onlyScrollIfNeeded) { 844 alignWithTop = alignWithTop === undefined ? true : !!alignWithTop; 845 if (alignWithTop) { 846 util.scrollTop(container, containerScroll.top + diffTop.top); 847 } else { 848 util.scrollTop(container, containerScroll.top + diffBottom.top); 849 } 850 } 851 } 852 853 if (allowHorizontalScroll) { 854 if (diffTop.left < 0 || diffBottom.left > 0) { 855 // 强制向上 856 if (alignWithLeft === true) { 857 util.scrollLeft(container, containerScroll.left + diffTop.left); 858 } else if (alignWithLeft === false) { 859 util.scrollLeft(container, containerScroll.left + diffBottom.left); 860 } else { 861 // 自动调整 862 if (diffTop.left < 0) { 863 util.scrollLeft(container, containerScroll.left + diffTop.left); 864 } else { 865 util.scrollLeft(container, containerScroll.left + diffBottom.left); 866 } 867 } 868 } else { 869 if (!onlyScrollIfNeeded) { 870 alignWithLeft = alignWithLeft === undefined ? true : !!alignWithLeft; 871 if (alignWithLeft) { 872 util.scrollLeft(container, containerScroll.left + diffTop.left); 873 } else { 874 util.scrollLeft(container, containerScroll.left + diffBottom.left); 875 } 876 } 877 } 878 } 879 } 880 881 module.exports = scrollIntoView; 882 883 /***/ }), 884 885 /***/ 5428: 886 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 887 888 "use strict"; 889 890 891 module.exports = __webpack_require__(1637); 892 893 /***/ }), 894 895 /***/ 3062: 896 /***/ ((module) => { 897 898 "use strict"; 899 900 901 var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; 902 903 var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; 904 905 var RE_NUM = /[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source; 906 907 function getClientPosition(elem) { 908 var box = undefined; 909 var x = undefined; 910 var y = undefined; 911 var doc = elem.ownerDocument; 912 var body = doc.body; 913 var docElem = doc && doc.documentElement; 914 // 根据 GBS 最新数据,A-Grade Browsers 都已支持 getBoundingClientRect 方法,不用再考虑传统的实现方式 915 box = elem.getBoundingClientRect(); 916 917 // 注:jQuery 还考虑减去 docElem.clientLeft/clientTop 918 // 但测试发现,这样反而会导致当 html 和 body 有边距/边框样式时,获取的值不正确 919 // 此外,ie6 会忽略 html 的 margin 值,幸运地是没有谁会去设置 html 的 margin 920 921 x = box.left; 922 y = box.top; 923 924 // In IE, most of the time, 2 extra pixels are added to the top and left 925 // due to the implicit 2-pixel inset border. In IE6/7 quirks mode and 926 // IE6 standards mode, this border can be overridden by setting the 927 // document element's border to zero -- thus, we cannot rely on the 928 // offset always being 2 pixels. 929 930 // In quirks mode, the offset can be determined by querying the body's 931 // clientLeft/clientTop, but in standards mode, it is found by querying 932 // the document element's clientLeft/clientTop. Since we already called 933 // getClientBoundingRect we have already forced a reflow, so it is not 934 // too expensive just to query them all. 935 936 // ie 下应该减去窗口的边框吧,毕竟默认 absolute 都是相对窗口定位的 937 // 窗口边框标准是设 documentElement ,quirks 时设置 body 938 // 最好禁止在 body 和 html 上边框 ,但 ie < 9 html 默认有 2px ,减去 939 // 但是非 ie 不可能设置窗口边框,body html 也不是窗口 ,ie 可以通过 html,body 设置 940 // 标准 ie 下 docElem.clientTop 就是 border-top 941 // ie7 html 即窗口边框改变不了。永远为 2 942 // 但标准 firefox/chrome/ie9 下 docElem.clientTop 是窗口边框,即使设了 border-top 也为 0 943 944 x -= docElem.clientLeft || body.clientLeft || 0; 945 y -= docElem.clientTop || body.clientTop || 0; 946 947 return { 948 left: x, 949 top: y 950 }; 951 } 952 953 function getScroll(w, top) { 954 var ret = w['page' + (top ? 'Y' : 'X') + 'Offset']; 955 var method = 'scroll' + (top ? 'Top' : 'Left'); 956 if (typeof ret !== 'number') { 957 var d = w.document; 958 // ie6,7,8 standard mode 959 ret = d.documentElement[method]; 960 if (typeof ret !== 'number') { 961 // quirks mode 962 ret = d.body[method]; 963 } 964 } 965 return ret; 966 } 967 968 function getScrollLeft(w) { 969 return getScroll(w); 970 } 971 972 function getScrollTop(w) { 973 return getScroll(w, true); 974 } 975 976 function getOffset(el) { 977 var pos = getClientPosition(el); 978 var doc = el.ownerDocument; 979 var w = doc.defaultView || doc.parentWindow; 980 pos.left += getScrollLeft(w); 981 pos.top += getScrollTop(w); 982 return pos; 983 } 984 function _getComputedStyle(elem, name, computedStyle_) { 985 var val = ''; 986 var d = elem.ownerDocument; 987 var computedStyle = computedStyle_ || d.defaultView.getComputedStyle(elem, null); 988 989 // https://github.com/kissyteam/kissy/issues/61 990 if (computedStyle) { 991 val = computedStyle.getPropertyValue(name) || computedStyle[name]; 992 } 993 994 return val; 995 } 996 997 var _RE_NUM_NO_PX = new RegExp('^(' + RE_NUM + ')(?!px)[a-z%]+$', 'i'); 998 var RE_POS = /^(top|right|bottom|left)$/; 999 var CURRENT_STYLE = 'currentStyle'; 1000 var RUNTIME_STYLE = 'runtimeStyle'; 1001 var LEFT = 'left'; 1002 var PX = 'px'; 1003 1004 function _getComputedStyleIE(elem, name) { 1005 // currentStyle maybe null 1006 // http://msdn.microsoft.com/en-us/library/ms535231.aspx 1007 var ret = elem[CURRENT_STYLE] && elem[CURRENT_STYLE][name]; 1008 1009 // 当 width/height 设置为百分比时,通过 pixelLeft 方式转换的 width/height 值 1010 // 一开始就处理了! CUSTOM_STYLE.height,CUSTOM_STYLE.width ,cssHook 解决@2011-08-19 1011 // 在 ie 下不对,需要直接用 offset 方式 1012 // borderWidth 等值也有问题,但考虑到 borderWidth 设为百分比的概率很小,这里就不考虑了 1013 1014 // From the awesome hack by Dean Edwards 1015 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 1016 // If we're not dealing with a regular pixel number 1017 // but a number that has a weird ending, we need to convert it to pixels 1018 // exclude left right for relativity 1019 if (_RE_NUM_NO_PX.test(ret) && !RE_POS.test(name)) { 1020 // Remember the original values 1021 var style = elem.style; 1022 var left = style[LEFT]; 1023 var rsLeft = elem[RUNTIME_STYLE][LEFT]; 1024 1025 // prevent flashing of content 1026 elem[RUNTIME_STYLE][LEFT] = elem[CURRENT_STYLE][LEFT]; 1027 1028 // Put in the new values to get a computed value out 1029 style[LEFT] = name === 'fontSize' ? '1em' : ret || 0; 1030 ret = style.pixelLeft + PX; 1031 1032 // Revert the changed values 1033 style[LEFT] = left; 1034 1035 elem[RUNTIME_STYLE][LEFT] = rsLeft; 1036 } 1037 return ret === '' ? 'auto' : ret; 1038 } 1039 1040 var getComputedStyleX = undefined; 1041 if (typeof window !== 'undefined') { 1042 getComputedStyleX = window.getComputedStyle ? _getComputedStyle : _getComputedStyleIE; 1043 } 1044 1045 function each(arr, fn) { 1046 for (var i = 0; i < arr.length; i++) { 1047 fn(arr[i]); 1048 } 1049 } 1050 1051 function isBorderBoxFn(elem) { 1052 return getComputedStyleX(elem, 'boxSizing') === 'border-box'; 1053 } 1054 1055 var BOX_MODELS = ['margin', 'border', 'padding']; 1056 var CONTENT_INDEX = -1; 1057 var PADDING_INDEX = 2; 1058 var BORDER_INDEX = 1; 1059 var MARGIN_INDEX = 0; 1060 1061 function swap(elem, options, callback) { 1062 var old = {}; 1063 var style = elem.style; 1064 var name = undefined; 1065 1066 // Remember the old values, and insert the new ones 1067 for (name in options) { 1068 if (options.hasOwnProperty(name)) { 1069 old[name] = style[name]; 1070 style[name] = options[name]; 1071 } 1072 } 1073 1074 callback.call(elem); 1075 1076 // Revert the old values 1077 for (name in options) { 1078 if (options.hasOwnProperty(name)) { 1079 style[name] = old[name]; 1080 } 1081 } 1082 } 1083 1084 function getPBMWidth(elem, props, which) { 1085 var value = 0; 1086 var prop = undefined; 1087 var j = undefined; 1088 var i = undefined; 1089 for (j = 0; j < props.length; j++) { 1090 prop = props[j]; 1091 if (prop) { 1092 for (i = 0; i < which.length; i++) { 1093 var cssProp = undefined; 1094 if (prop === 'border') { 1095 cssProp = prop + which[i] + 'Width'; 1096 } else { 1097 cssProp = prop + which[i]; 1098 } 1099 value += parseFloat(getComputedStyleX(elem, cssProp)) || 0; 1100 } 1101 } 1102 } 1103 return value; 1104 } 1105 1106 /** 1107 * A crude way of determining if an object is a window 1108 * @member util 1109 */ 1110 function isWindow(obj) { 1111 // must use == for ie8 1112 /* eslint eqeqeq:0 */ 1113 return obj != null && obj == obj.window; 1114 } 1115 1116 var domUtils = {}; 1117 1118 each(['Width', 'Height'], function (name) { 1119 domUtils['doc' + name] = function (refWin) { 1120 var d = refWin.document; 1121 return Math.max( 1122 // firefox chrome documentElement.scrollHeight< body.scrollHeight 1123 // ie standard mode : documentElement.scrollHeight> body.scrollHeight 1124 d.documentElement['scroll' + name], 1125 // quirks : documentElement.scrollHeight 最大等于可视窗口多一点? 1126 d.body['scroll' + name], domUtils['viewport' + name](d)); 1127 }; 1128 1129 domUtils['viewport' + name] = function (win) { 1130 // pc browser includes scrollbar in window.innerWidth 1131 var prop = 'client' + name; 1132 var doc = win.document; 1133 var body = doc.body; 1134 var documentElement = doc.documentElement; 1135 var documentElementProp = documentElement[prop]; 1136 // 标准模式取 documentElement 1137 // backcompat 取 body 1138 return doc.compatMode === 'CSS1Compat' && documentElementProp || body && body[prop] || documentElementProp; 1139 }; 1140 }); 1141 1142 /* 1143 得到元素的大小信息 1144 @param elem 1145 @param name 1146 @param {String} [extra] 'padding' : (css width) + padding 1147 'border' : (css width) + padding + border 1148 'margin' : (css width) + padding + border + margin 1149 */ 1150 function getWH(elem, name, extra) { 1151 if (isWindow(elem)) { 1152 return name === 'width' ? domUtils.viewportWidth(elem) : domUtils.viewportHeight(elem); 1153 } else if (elem.nodeType === 9) { 1154 return name === 'width' ? domUtils.docWidth(elem) : domUtils.docHeight(elem); 1155 } 1156 var which = name === 'width' ? ['Left', 'Right'] : ['Top', 'Bottom']; 1157 var borderBoxValue = name === 'width' ? elem.offsetWidth : elem.offsetHeight; 1158 var computedStyle = getComputedStyleX(elem); 1159 var isBorderBox = isBorderBoxFn(elem, computedStyle); 1160 var cssBoxValue = 0; 1161 if (borderBoxValue == null || borderBoxValue <= 0) { 1162 borderBoxValue = undefined; 1163 // Fall back to computed then un computed css if necessary 1164 cssBoxValue = getComputedStyleX(elem, name); 1165 if (cssBoxValue == null || Number(cssBoxValue) < 0) { 1166 cssBoxValue = elem.style[name] || 0; 1167 } 1168 // Normalize '', auto, and prepare for extra 1169 cssBoxValue = parseFloat(cssBoxValue) || 0; 1170 } 1171 if (extra === undefined) { 1172 extra = isBorderBox ? BORDER_INDEX : CONTENT_INDEX; 1173 } 1174 var borderBoxValueOrIsBorderBox = borderBoxValue !== undefined || isBorderBox; 1175 var val = borderBoxValue || cssBoxValue; 1176 if (extra === CONTENT_INDEX) { 1177 if (borderBoxValueOrIsBorderBox) { 1178 return val - getPBMWidth(elem, ['border', 'padding'], which, computedStyle); 1179 } 1180 return cssBoxValue; 1181 } 1182 if (borderBoxValueOrIsBorderBox) { 1183 var padding = extra === PADDING_INDEX ? -getPBMWidth(elem, ['border'], which, computedStyle) : getPBMWidth(elem, ['margin'], which, computedStyle); 1184 return val + (extra === BORDER_INDEX ? 0 : padding); 1185 } 1186 return cssBoxValue + getPBMWidth(elem, BOX_MODELS.slice(extra), which, computedStyle); 1187 } 1188 1189 var cssShow = { 1190 position: 'absolute', 1191 visibility: 'hidden', 1192 display: 'block' 1193 }; 1194 1195 // fix #119 : https://github.com/kissyteam/kissy/issues/119 1196 function getWHIgnoreDisplay(elem) { 1197 var val = undefined; 1198 var args = arguments; 1199 // in case elem is window 1200 // elem.offsetWidth === undefined 1201 if (elem.offsetWidth !== 0) { 1202 val = getWH.apply(undefined, args); 1203 } else { 1204 swap(elem, cssShow, function () { 1205 val = getWH.apply(undefined, args); 1206 }); 1207 } 1208 return val; 1209 } 1210 1211 function css(el, name, v) { 1212 var value = v; 1213 if ((typeof name === 'undefined' ? 'undefined' : _typeof(name)) === 'object') { 1214 for (var i in name) { 1215 if (name.hasOwnProperty(i)) { 1216 css(el, i, name[i]); 1217 } 1218 } 1219 return undefined; 1220 } 1221 if (typeof value !== 'undefined') { 1222 if (typeof value === 'number') { 1223 value += 'px'; 1224 } 1225 el.style[name] = value; 1226 return undefined; 1227 } 1228 return getComputedStyleX(el, name); 1229 } 1230 1231 each(['width', 'height'], function (name) { 1232 var first = name.charAt(0).toUpperCase() + name.slice(1); 1233 domUtils['outer' + first] = function (el, includeMargin) { 1234 return el && getWHIgnoreDisplay(el, name, includeMargin ? MARGIN_INDEX : BORDER_INDEX); 1235 }; 1236 var which = name === 'width' ? ['Left', 'Right'] : ['Top', 'Bottom']; 1237 1238 domUtils[name] = function (elem, val) { 1239 if (val !== undefined) { 1240 if (elem) { 1241 var computedStyle = getComputedStyleX(elem); 1242 var isBorderBox = isBorderBoxFn(elem); 1243 if (isBorderBox) { 1244 val += getPBMWidth(elem, ['padding', 'border'], which, computedStyle); 1245 } 1246 return css(elem, name, val); 1247 } 1248 return undefined; 1249 } 1250 return elem && getWHIgnoreDisplay(elem, name, CONTENT_INDEX); 1251 }; 1252 }); 1253 1254 // 设置 elem 相对 elem.ownerDocument 的坐标 1255 function setOffset(elem, offset) { 1256 // set position first, in-case top/left are set even on static elem 1257 if (css(elem, 'position') === 'static') { 1258 elem.style.position = 'relative'; 1259 } 1260 1261 var old = getOffset(elem); 1262 var ret = {}; 1263 var current = undefined; 1264 var key = undefined; 1265 1266 for (key in offset) { 1267 if (offset.hasOwnProperty(key)) { 1268 current = parseFloat(css(elem, key)) || 0; 1269 ret[key] = current + offset[key] - old[key]; 1270 } 1271 } 1272 css(elem, ret); 1273 } 1274 1275 module.exports = _extends({ 1276 getWindow: function getWindow(node) { 1277 var doc = node.ownerDocument || node; 1278 return doc.defaultView || doc.parentWindow; 1279 }, 1280 offset: function offset(el, value) { 1281 if (typeof value !== 'undefined') { 1282 setOffset(el, value); 1283 } else { 1284 return getOffset(el); 1285 } 1286 }, 1287 1288 isWindow: isWindow, 1289 each: each, 1290 css: css, 1291 clone: function clone(obj) { 1292 var ret = {}; 1293 for (var i in obj) { 1294 if (obj.hasOwnProperty(i)) { 1295 ret[i] = obj[i]; 1296 } 1297 } 1298 var overflow = obj.overflow; 1299 if (overflow) { 1300 for (var i in obj) { 1301 if (obj.hasOwnProperty(i)) { 1302 ret.overflow[i] = obj.overflow[i]; 1303 } 1304 } 1305 } 1306 return ret; 1307 }, 1308 scrollLeft: function scrollLeft(w, v) { 1309 if (isWindow(w)) { 1310 if (v === undefined) { 1311 return getScrollLeft(w); 1312 } 1313 window.scrollTo(v, getScrollTop(w)); 1314 } else { 1315 if (v === undefined) { 1316 return w.scrollLeft; 1317 } 1318 w.scrollLeft = v; 1319 } 1320 }, 1321 scrollTop: function scrollTop(w, v) { 1322 if (isWindow(w)) { 1323 if (v === undefined) { 1324 return getScrollTop(w); 1325 } 1326 window.scrollTo(getScrollLeft(w), v); 1327 } else { 1328 if (v === undefined) { 1329 return w.scrollTop; 1330 } 1331 w.scrollTop = v; 1332 } 1333 }, 1334 1335 viewportWidth: 0, 1336 viewportHeight: 0 1337 }, domUtils); 1338 1339 /***/ }), 1340 1341 /***/ 7734: 1342 /***/ ((module) => { 1343 1344 "use strict"; 1345 1346 1347 // do not edit .js files directly - edit src/index.jst 1348 1349 1350 var envHasBigInt64Array = typeof BigInt64Array !== 'undefined'; 1351 1352 1353 module.exports = function equal(a, b) { 1354 if (a === b) return true; 1355 1356 if (a && b && typeof a == 'object' && typeof b == 'object') { 1357 if (a.constructor !== b.constructor) return false; 1358 1359 var length, i, keys; 1360 if (Array.isArray(a)) { 1361 length = a.length; 1362 if (length != b.length) return false; 1363 for (i = length; i-- !== 0;) 1364 if (!equal(a[i], b[i])) return false; 1365 return true; 1366 } 1367 1368 1369 if ((a instanceof Map) && (b instanceof Map)) { 1370 if (a.size !== b.size) return false; 1371 for (i of a.entries()) 1372 if (!b.has(i[0])) return false; 1373 for (i of a.entries()) 1374 if (!equal(i[1], b.get(i[0]))) return false; 1375 return true; 1376 } 1377 1378 if ((a instanceof Set) && (b instanceof Set)) { 1379 if (a.size !== b.size) return false; 1380 for (i of a.entries()) 1381 if (!b.has(i[0])) return false; 1382 return true; 1383 } 1384 1385 if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) { 1386 length = a.length; 1387 if (length != b.length) return false; 1388 for (i = length; i-- !== 0;) 1389 if (a[i] !== b[i]) return false; 1390 return true; 1391 } 1392 1393 1394 if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; 1395 if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); 1396 if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); 1397 1398 keys = Object.keys(a); 1399 length = keys.length; 1400 if (length !== Object.keys(b).length) return false; 1401 1402 for (i = length; i-- !== 0;) 1403 if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; 1404 1405 for (i = length; i-- !== 0;) { 1406 var key = keys[i]; 1407 1408 if (!equal(a[key], b[key])) return false; 1409 } 1410 1411 return true; 1412 } 1413 1414 // true if both NaN, false otherwise 1415 return a!==a && b!==b; 1416 }; 1417 1418 1419 /***/ }), 1420 1421 /***/ 5215: 1422 /***/ ((module) => { 1423 1424 "use strict"; 1425 1426 1427 // do not edit .js files directly - edit src/index.jst 1428 1429 1430 1431 module.exports = function equal(a, b) { 1432 if (a === b) return true; 1433 1434 if (a && b && typeof a == 'object' && typeof b == 'object') { 1435 if (a.constructor !== b.constructor) return false; 1436 1437 var length, i, keys; 1438 if (Array.isArray(a)) { 1439 length = a.length; 1440 if (length != b.length) return false; 1441 for (i = length; i-- !== 0;) 1442 if (!equal(a[i], b[i])) return false; 1443 return true; 1444 } 1445 1446 1447 1448 if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; 1449 if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); 1450 if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); 1451 1452 keys = Object.keys(a); 1453 length = keys.length; 1454 if (length !== Object.keys(b).length) return false; 1455 1456 for (i = length; i-- !== 0;) 1457 if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; 1458 1459 for (i = length; i-- !== 0;) { 1460 var key = keys[i]; 1461 1462 if (!equal(a[key], b[key])) return false; 1463 } 1464 1465 return true; 1466 } 1467 1468 // true if both NaN, false otherwise 1469 return a!==a && b!==b; 1470 }; 1471 1472 1473 /***/ }), 1474 1475 /***/ 461: 1476 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 1477 1478 // Load in dependencies 1479 var computedStyle = __webpack_require__(6109); 1480 1481 /** 1482 * Calculate the `line-height` of a given node 1483 * @param {HTMLElement} node Element to calculate line height of. Must be in the DOM. 1484 * @returns {Number} `line-height` of the element in pixels 1485 */ 1486 function lineHeight(node) { 1487 // Grab the line-height via style 1488 var lnHeightStr = computedStyle(node, 'line-height'); 1489 var lnHeight = parseFloat(lnHeightStr, 10); 1490 1491 // If the lineHeight did not contain a unit (i.e. it was numeric), convert it to ems (e.g. '2.3' === '2.3em') 1492 if (lnHeightStr === lnHeight + '') { 1493 // Save the old lineHeight style and update the em unit to the element 1494 var _lnHeightStyle = node.style.lineHeight; 1495 node.style.lineHeight = lnHeightStr + 'em'; 1496 1497 // Calculate the em based height 1498 lnHeightStr = computedStyle(node, 'line-height'); 1499 lnHeight = parseFloat(lnHeightStr, 10); 1500 1501 // Revert the lineHeight style 1502 if (_lnHeightStyle) { 1503 node.style.lineHeight = _lnHeightStyle; 1504 } else { 1505 delete node.style.lineHeight; 1506 } 1507 } 1508 1509 // If the lineHeight is in `pt`, convert it to pixels (4px for 3pt) 1510 // DEV: `em` units are converted to `pt` in IE6 1511 // Conversion ratio from https://developer.mozilla.org/en-US/docs/Web/CSS/length 1512 if (lnHeightStr.indexOf('pt') !== -1) { 1513 lnHeight *= 4; 1514 lnHeight /= 3; 1515 // Otherwise, if the lineHeight is in `mm`, convert it to pixels (96px for 25.4mm) 1516 } else if (lnHeightStr.indexOf('mm') !== -1) { 1517 lnHeight *= 96; 1518 lnHeight /= 25.4; 1519 // Otherwise, if the lineHeight is in `cm`, convert it to pixels (96px for 2.54cm) 1520 } else if (lnHeightStr.indexOf('cm') !== -1) { 1521 lnHeight *= 96; 1522 lnHeight /= 2.54; 1523 // Otherwise, if the lineHeight is in `in`, convert it to pixels (96px for 1in) 1524 } else if (lnHeightStr.indexOf('in') !== -1) { 1525 lnHeight *= 96; 1526 // Otherwise, if the lineHeight is in `pc`, convert it to pixels (12pt for 1pc) 1527 } else if (lnHeightStr.indexOf('pc') !== -1) { 1528 lnHeight *= 16; 1529 } 1530 1531 // Continue our computation 1532 lnHeight = Math.round(lnHeight); 1533 1534 // If the line-height is "normal", calculate by font-size 1535 if (lnHeightStr === 'normal') { 1536 // Create a temporary node 1537 var nodeName = node.nodeName; 1538 var _node = document.createElement(nodeName); 1539 _node.innerHTML = ' '; 1540 1541 // If we have a text area, reset it to only 1 row 1542 // https://github.com/twolfson/line-height/issues/4 1543 if (nodeName.toUpperCase() === 'TEXTAREA') { 1544 _node.setAttribute('rows', '1'); 1545 } 1546 1547 // Set the font-size of the element 1548 var fontSizeStr = computedStyle(node, 'font-size'); 1549 _node.style.fontSize = fontSizeStr; 1550 1551 // Remove default padding/border which can affect offset height 1552 // https://github.com/twolfson/line-height/issues/4 1553 // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetHeight 1554 _node.style.padding = '0px'; 1555 _node.style.border = '0px'; 1556 1557 // Append it to the body 1558 var body = document.body; 1559 body.appendChild(_node); 1560 1561 // Assume the line height of the element is the height 1562 var height = _node.offsetHeight; 1563 lnHeight = height; 1564 1565 // Remove our child from the DOM 1566 body.removeChild(_node); 1567 } 1568 1569 // Return the calculated height 1570 return lnHeight; 1571 } 1572 1573 // Export lineHeight 1574 module.exports = lineHeight; 1575 1576 1577 /***/ }), 1578 1579 /***/ 7520: 1580 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 1581 1582 module.exports = __webpack_require__(7191); 1583 1584 1585 /***/ }), 1586 1587 /***/ 8202: 1588 /***/ ((module) => { 1589 1590 "use strict"; 1591 /** 1592 * Copyright (c) 2015, Facebook, Inc. 1593 * All rights reserved. 1594 * 1595 * This source code is licensed under the BSD-style license found in the 1596 * LICENSE file in the root directory of this source tree. An additional grant 1597 * of patent rights can be found in the PATENTS file in the same directory. 1598 * 1599 * @providesModule ExecutionEnvironment 1600 */ 1601 1602 /*jslint evil: true */ 1603 1604 1605 1606 var canUseDOM = !!( 1607 typeof window !== 'undefined' && 1608 window.document && 1609 window.document.createElement 1610 ); 1611 1612 /** 1613 * Simple, lightweight module assisting with the detection and context of 1614 * Worker. Helps avoid circular dependencies and allows code to reason about 1615 * whether or not they are in a Worker, even if they never include the main 1616 * `ReactWorker` dependency. 1617 */ 1618 var ExecutionEnvironment = { 1619 1620 canUseDOM: canUseDOM, 1621 1622 canUseWorkers: typeof Worker !== 'undefined', 1623 1624 canUseEventListeners: 1625 canUseDOM && !!(window.addEventListener || window.attachEvent), 1626 1627 canUseViewport: canUseDOM && !!window.screen, 1628 1629 isInWorker: !canUseDOM // For now, this is true - might change in the future. 1630 1631 }; 1632 1633 module.exports = ExecutionEnvironment; 1634 1635 1636 /***/ }), 1637 1638 /***/ 2213: 1639 /***/ ((module) => { 1640 1641 /** 1642 * Copyright 2004-present Facebook. All Rights Reserved. 1643 * 1644 * @providesModule UserAgent_DEPRECATED 1645 */ 1646 1647 /** 1648 * Provides entirely client-side User Agent and OS detection. You should prefer 1649 * the non-deprecated UserAgent module when possible, which exposes our 1650 * authoritative server-side PHP-based detection to the client. 1651 * 1652 * Usage is straightforward: 1653 * 1654 * if (UserAgent_DEPRECATED.ie()) { 1655 * // IE 1656 * } 1657 * 1658 * You can also do version checks: 1659 * 1660 * if (UserAgent_DEPRECATED.ie() >= 7) { 1661 * // IE7 or better 1662 * } 1663 * 1664 * The browser functions will return NaN if the browser does not match, so 1665 * you can also do version compares the other way: 1666 * 1667 * if (UserAgent_DEPRECATED.ie() < 7) { 1668 * // IE6 or worse 1669 * } 1670 * 1671 * Note that the version is a float and may include a minor version number, 1672 * so you should always use range operators to perform comparisons, not 1673 * strict equality. 1674 * 1675 * **Note:** You should **strongly** prefer capability detection to browser 1676 * version detection where it's reasonable: 1677 * 1678 * http://www.quirksmode.org/js/support.html 1679 * 1680 * Further, we have a large number of mature wrapper functions and classes 1681 * which abstract away many browser irregularities. Check the documentation, 1682 * grep for things, or ask on javascript@lists.facebook.com before writing yet 1683 * another copy of "event || window.event". 1684 * 1685 */ 1686 1687 var _populated = false; 1688 1689 // Browsers 1690 var _ie, _firefox, _opera, _webkit, _chrome; 1691 1692 // Actual IE browser for compatibility mode 1693 var _ie_real_version; 1694 1695 // Platforms 1696 var _osx, _windows, _linux, _android; 1697 1698 // Architectures 1699 var _win64; 1700 1701 // Devices 1702 var _iphone, _ipad, _native; 1703 1704 var _mobile; 1705 1706 function _populate() { 1707 if (_populated) { 1708 return; 1709 } 1710 1711 _populated = true; 1712 1713 // To work around buggy JS libraries that can't handle multi-digit 1714 // version numbers, Opera 10's user agent string claims it's Opera 1715 // 9, then later includes a Version/X.Y field: 1716 // 1717 // Opera/9.80 (foo) Presto/2.2.15 Version/10.10 1718 var uas = navigator.userAgent; 1719 var agent = /(?:MSIE.(\d+\.\d+))|(?:(?:Firefox|GranParadiso|Iceweasel).(\d+\.\d+))|(?:Opera(?:.+Version.|.)(\d+\.\d+))|(?:AppleWebKit.(\d+(?:\.\d+)?))|(?:Trident\/\d+\.\d+.*rv:(\d+\.\d+))/.exec(uas); 1720 var os = /(Mac OS X)|(Windows)|(Linux)/.exec(uas); 1721 1722 _iphone = /\b(iPhone|iP[ao]d)/.exec(uas); 1723 _ipad = /\b(iP[ao]d)/.exec(uas); 1724 _android = /Android/i.exec(uas); 1725 _native = /FBAN\/\w+;/i.exec(uas); 1726 _mobile = /Mobile/i.exec(uas); 1727 1728 // Note that the IE team blog would have you believe you should be checking 1729 // for 'Win64; x64'. But MSDN then reveals that you can actually be coming 1730 // from either x64 or ia64; so ultimately, you should just check for Win64 1731 // as in indicator of whether you're in 64-bit IE. 32-bit IE on 64-bit 1732 // Windows will send 'WOW64' instead. 1733 _win64 = !!(/Win64/.exec(uas)); 1734 1735 if (agent) { 1736 _ie = agent[1] ? parseFloat(agent[1]) : ( 1737 agent[5] ? parseFloat(agent[5]) : NaN); 1738 // IE compatibility mode 1739 if (_ie && document && document.documentMode) { 1740 _ie = document.documentMode; 1741 } 1742 // grab the "true" ie version from the trident token if available 1743 var trident = /(?:Trident\/(\d+.\d+))/.exec(uas); 1744 _ie_real_version = trident ? parseFloat(trident[1]) + 4 : _ie; 1745 1746 _firefox = agent[2] ? parseFloat(agent[2]) : NaN; 1747 _opera = agent[3] ? parseFloat(agent[3]) : NaN; 1748 _webkit = agent[4] ? parseFloat(agent[4]) : NaN; 1749 if (_webkit) { 1750 // We do not add the regexp to the above test, because it will always 1751 // match 'safari' only since 'AppleWebKit' appears before 'Chrome' in 1752 // the userAgent string. 1753 agent = /(?:Chrome\/(\d+\.\d+))/.exec(uas); 1754 _chrome = agent && agent[1] ? parseFloat(agent[1]) : NaN; 1755 } else { 1756 _chrome = NaN; 1757 } 1758 } else { 1759 _ie = _firefox = _opera = _chrome = _webkit = NaN; 1760 } 1761 1762 if (os) { 1763 if (os[1]) { 1764 // Detect OS X version. If no version number matches, set _osx to true. 1765 // Version examples: 10, 10_6_1, 10.7 1766 // Parses version number as a float, taking only first two sets of 1767 // digits. If only one set of digits is found, returns just the major 1768 // version number. 1769 var ver = /(?:Mac OS X (\d+(?:[._]\d+)?))/.exec(uas); 1770 1771 _osx = ver ? parseFloat(ver[1].replace('_', '.')) : true; 1772 } else { 1773 _osx = false; 1774 } 1775 _windows = !!os[2]; 1776 _linux = !!os[3]; 1777 } else { 1778 _osx = _windows = _linux = false; 1779 } 1780 } 1781 1782 var UserAgent_DEPRECATED = { 1783 1784 /** 1785 * Check if the UA is Internet Explorer. 1786 * 1787 * 1788 * @return float|NaN Version number (if match) or NaN. 1789 */ 1790 ie: function() { 1791 return _populate() || _ie; 1792 }, 1793 1794 /** 1795 * Check if we're in Internet Explorer compatibility mode. 1796 * 1797 * @return bool true if in compatibility mode, false if 1798 * not compatibility mode or not ie 1799 */ 1800 ieCompatibilityMode: function() { 1801 return _populate() || (_ie_real_version > _ie); 1802 }, 1803 1804 1805 /** 1806 * Whether the browser is 64-bit IE. Really, this is kind of weak sauce; we 1807 * only need this because Skype can't handle 64-bit IE yet. We need to remove 1808 * this when we don't need it -- tracked by #601957. 1809 */ 1810 ie64: function() { 1811 return UserAgent_DEPRECATED.ie() && _win64; 1812 }, 1813 1814 /** 1815 * Check if the UA is Firefox. 1816 * 1817 * 1818 * @return float|NaN Version number (if match) or NaN. 1819 */ 1820 firefox: function() { 1821 return _populate() || _firefox; 1822 }, 1823 1824 1825 /** 1826 * Check if the UA is Opera. 1827 * 1828 * 1829 * @return float|NaN Version number (if match) or NaN. 1830 */ 1831 opera: function() { 1832 return _populate() || _opera; 1833 }, 1834 1835 1836 /** 1837 * Check if the UA is WebKit. 1838 * 1839 * 1840 * @return float|NaN Version number (if match) or NaN. 1841 */ 1842 webkit: function() { 1843 return _populate() || _webkit; 1844 }, 1845 1846 /** 1847 * For Push 1848 * WILL BE REMOVED VERY SOON. Use UserAgent_DEPRECATED.webkit 1849 */ 1850 safari: function() { 1851 return UserAgent_DEPRECATED.webkit(); 1852 }, 1853 1854 /** 1855 * Check if the UA is a Chrome browser. 1856 * 1857 * 1858 * @return float|NaN Version number (if match) or NaN. 1859 */ 1860 chrome : function() { 1861 return _populate() || _chrome; 1862 }, 1863 1864 1865 /** 1866 * Check if the user is running Windows. 1867 * 1868 * @return bool `true' if the user's OS is Windows. 1869 */ 1870 windows: function() { 1871 return _populate() || _windows; 1872 }, 1873 1874 1875 /** 1876 * Check if the user is running Mac OS X. 1877 * 1878 * @return float|bool Returns a float if a version number is detected, 1879 * otherwise true/false. 1880 */ 1881 osx: function() { 1882 return _populate() || _osx; 1883 }, 1884 1885 /** 1886 * Check if the user is running Linux. 1887 * 1888 * @return bool `true' if the user's OS is some flavor of Linux. 1889 */ 1890 linux: function() { 1891 return _populate() || _linux; 1892 }, 1893 1894 /** 1895 * Check if the user is running on an iPhone or iPod platform. 1896 * 1897 * @return bool `true' if the user is running some flavor of the 1898 * iPhone OS. 1899 */ 1900 iphone: function() { 1901 return _populate() || _iphone; 1902 }, 1903 1904 mobile: function() { 1905 return _populate() || (_iphone || _ipad || _android || _mobile); 1906 }, 1907 1908 nativeApp: function() { 1909 // webviews inside of the native apps 1910 return _populate() || _native; 1911 }, 1912 1913 android: function() { 1914 return _populate() || _android; 1915 }, 1916 1917 ipad: function() { 1918 return _populate() || _ipad; 1919 } 1920 }; 1921 1922 module.exports = UserAgent_DEPRECATED; 1923 1924 1925 /***/ }), 1926 1927 /***/ 1087: 1928 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 1929 1930 "use strict"; 1931 /** 1932 * Copyright 2013-2015, Facebook, Inc. 1933 * All rights reserved. 1934 * 1935 * This source code is licensed under the BSD-style license found in the 1936 * LICENSE file in the root directory of this source tree. An additional grant 1937 * of patent rights can be found in the PATENTS file in the same directory. 1938 * 1939 * @providesModule isEventSupported 1940 */ 1941 1942 1943 1944 var ExecutionEnvironment = __webpack_require__(8202); 1945 1946 var useHasFeature; 1947 if (ExecutionEnvironment.canUseDOM) { 1948 useHasFeature = 1949 document.implementation && 1950 document.implementation.hasFeature && 1951 // always returns true in newer browsers as per the standard. 1952 // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature 1953 document.implementation.hasFeature('', '') !== true; 1954 } 1955 1956 /** 1957 * Checks if an event is supported in the current execution environment. 1958 * 1959 * NOTE: This will not work correctly for non-generic events such as `change`, 1960 * `reset`, `load`, `error`, and `select`. 1961 * 1962 * Borrows from Modernizr. 1963 * 1964 * @param {string} eventNameSuffix Event name, e.g. "click". 1965 * @param {?boolean} capture Check if the capture phase is supported. 1966 * @return {boolean} True if the event is supported. 1967 * @internal 1968 * @license Modernizr 3.0.0pre (Custom Build) | MIT 1969 */ 1970 function isEventSupported(eventNameSuffix, capture) { 1971 if (!ExecutionEnvironment.canUseDOM || 1972 capture && !('addEventListener' in document)) { 1973 return false; 1974 } 1975 1976 var eventName = 'on' + eventNameSuffix; 1977 var isSupported = eventName in document; 1978 1979 if (!isSupported) { 1980 var element = document.createElement('div'); 1981 element.setAttribute(eventName, 'return;'); 1982 isSupported = typeof element[eventName] === 'function'; 1983 } 1984 1985 if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') { 1986 // This is the only way to test support for the `wheel` event in IE9+. 1987 isSupported = document.implementation.hasFeature('Events.wheel', '3.0'); 1988 } 1989 1990 return isSupported; 1991 } 1992 1993 module.exports = isEventSupported; 1994 1995 1996 /***/ }), 1997 1998 /***/ 7191: 1999 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 2000 2001 "use strict"; 2002 /** 2003 * Copyright (c) 2015, Facebook, Inc. 2004 * All rights reserved. 2005 * 2006 * This source code is licensed under the BSD-style license found in the 2007 * LICENSE file in the root directory of this source tree. An additional grant 2008 * of patent rights can be found in the PATENTS file in the same directory. 2009 * 2010 * @providesModule normalizeWheel 2011 * @typechecks 2012 */ 2013 2014 2015 2016 var UserAgent_DEPRECATED = __webpack_require__(2213); 2017 2018 var isEventSupported = __webpack_require__(1087); 2019 2020 2021 // Reasonable defaults 2022 var PIXEL_STEP = 10; 2023 var LINE_HEIGHT = 40; 2024 var PAGE_HEIGHT = 800; 2025 2026 /** 2027 * Mouse wheel (and 2-finger trackpad) support on the web sucks. It is 2028 * complicated, thus this doc is long and (hopefully) detailed enough to answer 2029 * your questions. 2030 * 2031 * If you need to react to the mouse wheel in a predictable way, this code is 2032 * like your bestest friend. * hugs * 2033 * 2034 * As of today, there are 4 DOM event types you can listen to: 2035 * 2036 * 'wheel' -- Chrome(31+), FF(17+), IE(9+) 2037 * 'mousewheel' -- Chrome, IE(6+), Opera, Safari 2038 * 'MozMousePixelScroll' -- FF(3.5 only!) (2010-2013) -- don't bother! 2039 * 'DOMMouseScroll' -- FF(0.9.7+) since 2003 2040 * 2041 * So what to do? The is the best: 2042 * 2043 * normalizeWheel.getEventType(); 2044 * 2045 * In your event callback, use this code to get sane interpretation of the 2046 * deltas. This code will return an object with properties: 2047 * 2048 * spinX -- normalized spin speed (use for zoom) - x plane 2049 * spinY -- " - y plane 2050 * pixelX -- normalized distance (to pixels) - x plane 2051 * pixelY -- " - y plane 2052 * 2053 * Wheel values are provided by the browser assuming you are using the wheel to 2054 * scroll a web page by a number of lines or pixels (or pages). Values can vary 2055 * significantly on different platforms and browsers, forgetting that you can 2056 * scroll at different speeds. Some devices (like trackpads) emit more events 2057 * at smaller increments with fine granularity, and some emit massive jumps with 2058 * linear speed or acceleration. 2059 * 2060 * This code does its best to normalize the deltas for you: 2061 * 2062 * - spin is trying to normalize how far the wheel was spun (or trackpad 2063 * dragged). This is super useful for zoom support where you want to 2064 * throw away the chunky scroll steps on the PC and make those equal to 2065 * the slow and smooth tiny steps on the Mac. Key data: This code tries to 2066 * resolve a single slow step on a wheel to 1. 2067 * 2068 * - pixel is normalizing the desired scroll delta in pixel units. You'll 2069 * get the crazy differences between browsers, but at least it'll be in 2070 * pixels! 2071 * 2072 * - positive value indicates scrolling DOWN/RIGHT, negative UP/LEFT. This 2073 * should translate to positive value zooming IN, negative zooming OUT. 2074 * This matches the newer 'wheel' event. 2075 * 2076 * Why are there spinX, spinY (or pixels)? 2077 * 2078 * - spinX is a 2-finger side drag on the trackpad, and a shift + wheel turn 2079 * with a mouse. It results in side-scrolling in the browser by default. 2080 * 2081 * - spinY is what you expect -- it's the classic axis of a mouse wheel. 2082 * 2083 * - I dropped spinZ/pixelZ. It is supported by the DOM 3 'wheel' event and 2084 * probably is by browsers in conjunction with fancy 3D controllers .. but 2085 * you know. 2086 * 2087 * Implementation info: 2088 * 2089 * Examples of 'wheel' event if you scroll slowly (down) by one step with an 2090 * average mouse: 2091 * 2092 * OS X + Chrome (mouse) - 4 pixel delta (wheelDelta -120) 2093 * OS X + Safari (mouse) - N/A pixel delta (wheelDelta -12) 2094 * OS X + Firefox (mouse) - 0.1 line delta (wheelDelta N/A) 2095 * Win8 + Chrome (mouse) - 100 pixel delta (wheelDelta -120) 2096 * Win8 + Firefox (mouse) - 3 line delta (wheelDelta -120) 2097 * 2098 * On the trackpad: 2099 * 2100 * OS X + Chrome (trackpad) - 2 pixel delta (wheelDelta -6) 2101 * OS X + Firefox (trackpad) - 1 pixel delta (wheelDelta N/A) 2102 * 2103 * On other/older browsers.. it's more complicated as there can be multiple and 2104 * also missing delta values. 2105 * 2106 * The 'wheel' event is more standard: 2107 * 2108 * http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents 2109 * 2110 * The basics is that it includes a unit, deltaMode (pixels, lines, pages), and 2111 * deltaX, deltaY and deltaZ. Some browsers provide other values to maintain 2112 * backward compatibility with older events. Those other values help us 2113 * better normalize spin speed. Example of what the browsers provide: 2114 * 2115 * | event.wheelDelta | event.detail 2116 * ------------------+------------------+-------------- 2117 * Safari v5/OS X | -120 | 0 2118 * Safari v5/Win7 | -120 | 0 2119 * Chrome v17/OS X | -120 | 0 2120 * Chrome v17/Win7 | -120 | 0 2121 * IE9/Win7 | -120 | undefined 2122 * Firefox v4/OS X | undefined | 1 2123 * Firefox v4/Win7 | undefined | 3 2124 * 2125 */ 2126 function normalizeWheel(/*object*/ event) /*object*/ { 2127 var sX = 0, sY = 0, // spinX, spinY 2128 pX = 0, pY = 0; // pixelX, pixelY 2129 2130 // Legacy 2131 if ('detail' in event) { sY = event.detail; } 2132 if ('wheelDelta' in event) { sY = -event.wheelDelta / 120; } 2133 if ('wheelDeltaY' in event) { sY = -event.wheelDeltaY / 120; } 2134 if ('wheelDeltaX' in event) { sX = -event.wheelDeltaX / 120; } 2135 2136 // side scrolling on FF with DOMMouseScroll 2137 if ( 'axis' in event && event.axis === event.HORIZONTAL_AXIS ) { 2138 sX = sY; 2139 sY = 0; 2140 } 2141 2142 pX = sX * PIXEL_STEP; 2143 pY = sY * PIXEL_STEP; 2144 2145 if ('deltaY' in event) { pY = event.deltaY; } 2146 if ('deltaX' in event) { pX = event.deltaX; } 2147 2148 if ((pX || pY) && event.deltaMode) { 2149 if (event.deltaMode == 1) { // delta in LINE units 2150 pX *= LINE_HEIGHT; 2151 pY *= LINE_HEIGHT; 2152 } else { // delta in PAGE units 2153 pX *= PAGE_HEIGHT; 2154 pY *= PAGE_HEIGHT; 2155 } 2156 } 2157 2158 // Fall-back if spin cannot be determined 2159 if (pX && !sX) { sX = (pX < 1) ? -1 : 1; } 2160 if (pY && !sY) { sY = (pY < 1) ? -1 : 1; } 2161 2162 return { spinX : sX, 2163 spinY : sY, 2164 pixelX : pX, 2165 pixelY : pY }; 2166 } 2167 2168 2169 /** 2170 * The best combination if you prefer spinX + spinY normalization. It favors 2171 * the older DOMMouseScroll for Firefox, as FF does not include wheelDelta with 2172 * 'wheel' event, making spin speed determination impossible. 2173 */ 2174 normalizeWheel.getEventType = function() /*string*/ { 2175 return (UserAgent_DEPRECATED.firefox()) 2176 ? 'DOMMouseScroll' 2177 : (isEventSupported('wheel')) 2178 ? 'wheel' 2179 : 'mousewheel'; 2180 }; 2181 2182 module.exports = normalizeWheel; 2183 2184 2185 /***/ }), 2186 2187 /***/ 2775: 2188 /***/ ((module) => { 2189 2190 var x=String; 2191 var create=function() {return {isColorSupported:false,reset:x,bold:x,dim:x,italic:x,underline:x,inverse:x,hidden:x,strikethrough:x,black:x,red:x,green:x,yellow:x,blue:x,magenta:x,cyan:x,white:x,gray:x,bgBlack:x,bgRed:x,bgGreen:x,bgYellow:x,bgBlue:x,bgMagenta:x,bgCyan:x,bgWhite:x}}; 2192 module.exports=create(); 2193 module.exports.createColors = create; 2194 2195 2196 /***/ }), 2197 2198 /***/ 4465: 2199 /***/ ((__unused_webpack_module, exports) => { 2200 2201 "use strict"; 2202 2203 Object.defineProperty(exports, "__esModule", ({ value: true })); 2204 2205 2206 /***/ }), 2207 2208 /***/ 8036: 2209 /***/ (function(module, __unused_webpack_exports, __webpack_require__) { 2210 2211 "use strict"; 2212 2213 var __importDefault = (this && this.__importDefault) || function (mod) { 2214 return (mod && mod.__esModule) ? mod : { "default": mod }; 2215 }; 2216 __webpack_require__(4465); 2217 const postcss_1 = __importDefault(__webpack_require__(4529)); 2218 const PostCSSPlugin_1 = __importDefault(__webpack_require__(3576)); 2219 module.exports = (0, PostCSSPlugin_1.default)(postcss_1.default); 2220 2221 2222 /***/ }), 2223 2224 /***/ 5525: 2225 /***/ ((__unused_webpack_module, exports, __webpack_require__) => { 2226 2227 "use strict"; 2228 2229 Object.defineProperty(exports, "__esModule", ({ value: true })); 2230 exports.prefixWrapCSSSelector = exports.prefixWrapCSSRule = void 0; 2231 const CSSSelector_1 = __webpack_require__(3467); 2232 const prefixWrapCSSRule = (cssRule, nested, ignoredSelectors, prefixSelector, prefixRootTags) => { 2233 // Check each rule to see if it exactly matches our prefix selector, when 2234 // this happens, don't try to prefix that selector. 2235 const rules = cssRule.selector 2236 .split(",") 2237 .filter((selector) => !(0, CSSSelector_1.cssRuleMatchesPrefixSelector)({ selector: selector }, prefixSelector)); 2238 if (rules.length === 0) { 2239 return; 2240 } 2241 cssRule.selector = rules 2242 .map((cssSelector) => (0, exports.prefixWrapCSSSelector)(cssSelector, cssRule, nested, ignoredSelectors, prefixSelector, prefixRootTags)) 2243 .filter(CSSSelector_1.isValidCSSSelector) 2244 .join(", "); 2245 }; 2246 exports.prefixWrapCSSRule = prefixWrapCSSRule; 2247 const prefixWrapCSSSelector = (cssSelector, cssRule, nested, ignoredSelectors, prefixSelector, prefixRootTags) => { 2248 const cleanedSelector = (0, CSSSelector_1.cleanSelector)(cssSelector); 2249 if (cleanedSelector === "") { 2250 return null; 2251 } 2252 // Don't prefix nested selected. 2253 if (nested !== null && cleanedSelector.startsWith(nested, 0)) { 2254 return cleanedSelector; 2255 } 2256 // Do not prefix keyframes rules. 2257 if ((0, CSSSelector_1.isKeyframes)(cssRule)) { 2258 return cleanedSelector; 2259 } 2260 // Check for matching ignored selectors 2261 if (ignoredSelectors.some((currentValue) => cleanedSelector.match(currentValue))) { 2262 return cleanedSelector; 2263 } 2264 // Anything other than a root tag is always prefixed. 2265 if ((0, CSSSelector_1.isNotRootTag)(cleanedSelector)) { 2266 return prefixSelector + " " + cleanedSelector; 2267 } 2268 // Handle special case where root tags should be converted into classes 2269 // rather than being replaced. 2270 if (prefixRootTags) { 2271 return prefixSelector + " ." + cleanedSelector; 2272 } 2273 // HTML and Body elements cannot be contained within our container so lets 2274 // extract their styles. 2275 return cleanedSelector.replace(/^(body|html|:root)/, prefixSelector); 2276 }; 2277 exports.prefixWrapCSSSelector = prefixWrapCSSSelector; 2278 2279 2280 /***/ }), 2281 2282 /***/ 3467: 2283 /***/ ((__unused_webpack_module, exports) => { 2284 2285 "use strict"; 2286 2287 Object.defineProperty(exports, "__esModule", ({ value: true })); 2288 exports.cssRuleMatchesPrefixSelector = exports.isNotRootTag = exports.isKeyframes = exports.cleanSelector = exports.isValidCSSSelector = void 0; 2289 const ANY_WHITESPACE_AT_BEGINNING_OR_END = /(^\s*|\s*$)/g; 2290 const IS_ROOT_TAG = /^(body|html|:root).*$/; 2291 const isValidCSSSelector = (cssSelector) => { 2292 return cssSelector !== null; 2293 }; 2294 exports.isValidCSSSelector = isValidCSSSelector; 2295 const cleanSelector = (cssSelector) => { 2296 return cssSelector.replace(ANY_WHITESPACE_AT_BEGINNING_OR_END, ""); 2297 }; 2298 exports.cleanSelector = cleanSelector; 2299 const isKeyframes = (cssRule) => { 2300 const { parent } = cssRule; 2301 const parentReal = parent; 2302 // @see https://developer.mozilla.org/en-US/docs/Web/CSS/At-rule 2303 return (parent !== undefined && 2304 parentReal.type === "atrule" && 2305 parentReal.name !== undefined && 2306 parentReal.name.match(/keyframes$/) !== null); 2307 }; 2308 exports.isKeyframes = isKeyframes; 2309 const isNotRootTag = (cleanSelector) => { 2310 return !cleanSelector.match(IS_ROOT_TAG); 2311 }; 2312 exports.isNotRootTag = isNotRootTag; 2313 const cssRuleMatchesPrefixSelector = (cssRule, prefixSelector) => { 2314 const escapedPrefixSelector = prefixSelector.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); 2315 // eslint-disable-next-line security-node/non-literal-reg-expr 2316 const isPrefixSelector = new RegExp(`^$escapedPrefixSelector}$`); 2317 return isPrefixSelector.test(cssRule.selector); 2318 }; 2319 exports.cssRuleMatchesPrefixSelector = cssRuleMatchesPrefixSelector; 2320 2321 2322 /***/ }), 2323 2324 /***/ 9411: 2325 /***/ ((__unused_webpack_module, exports) => { 2326 2327 "use strict"; 2328 2329 Object.defineProperty(exports, "__esModule", ({ value: true })); 2330 exports.shouldIncludeFilePath = void 0; 2331 const shouldIncludeFilePath = (filePath, whitelist, blacklist) => { 2332 // If whitelist exists, check if rule is contained within it. 2333 if (whitelist.length > 0) { 2334 return (filePath != undefined && 2335 whitelist.some((currentValue) => filePath.match(currentValue))); 2336 } 2337 // If blacklist exists, check if rule is not contained within it. 2338 if (blacklist.length > 0) { 2339 return !(filePath != undefined && 2340 blacklist.some((currentValue) => filePath.match(currentValue))); 2341 } 2342 // In all other cases, presume rule should be prefixed. 2343 return true; 2344 }; 2345 exports.shouldIncludeFilePath = shouldIncludeFilePath; 2346 2347 2348 /***/ }), 2349 2350 /***/ 8061: 2351 /***/ (function(__unused_webpack_module, exports, __webpack_require__) { 2352 2353 "use strict"; 2354 2355 var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 2356 if (k2 === undefined) k2 = k; 2357 var desc = Object.getOwnPropertyDescriptor(m, k); 2358 if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 2359 desc = { enumerable: true, get: function() { return m[k]; } }; 2360 } 2361 Object.defineProperty(o, k2, desc); 2362 }) : (function(o, m, k, k2) { 2363 if (k2 === undefined) k2 = k; 2364 o[k2] = m[k]; 2365 })); 2366 var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 2367 Object.defineProperty(o, "default", { enumerable: true, value: v }); 2368 }) : function(o, v) { 2369 o["default"] = v; 2370 }); 2371 var __importStar = (this && this.__importStar) || function (mod) { 2372 if (mod && mod.__esModule) return mod; 2373 var result = {}; 2374 if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 2375 __setModuleDefault(result, mod); 2376 return result; 2377 }; 2378 Object.defineProperty(exports, "__esModule", ({ value: true })); 2379 exports.asPostCSSv7PluginGenerator = void 0; 2380 const PostCSSPrefixWrap_1 = __importStar(__webpack_require__(1311)); 2381 const asPostCSSv7PluginGenerator = (postcss) => { 2382 return postcss.plugin(PostCSSPrefixWrap_1.PLUGIN_NAME, (prefixSelector, options) => { 2383 return new PostCSSPrefixWrap_1.default(prefixSelector, options).prefix(); 2384 }); 2385 }; 2386 exports.asPostCSSv7PluginGenerator = asPostCSSv7PluginGenerator; 2387 2388 2389 /***/ }), 2390 2391 /***/ 2888: 2392 /***/ (function(__unused_webpack_module, exports, __webpack_require__) { 2393 2394 "use strict"; 2395 2396 var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 2397 if (k2 === undefined) k2 = k; 2398 var desc = Object.getOwnPropertyDescriptor(m, k); 2399 if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 2400 desc = { enumerable: true, get: function() { return m[k]; } }; 2401 } 2402 Object.defineProperty(o, k2, desc); 2403 }) : (function(o, m, k, k2) { 2404 if (k2 === undefined) k2 = k; 2405 o[k2] = m[k]; 2406 })); 2407 var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 2408 Object.defineProperty(o, "default", { enumerable: true, value: v }); 2409 }) : function(o, v) { 2410 o["default"] = v; 2411 }); 2412 var __importStar = (this && this.__importStar) || function (mod) { 2413 if (mod && mod.__esModule) return mod; 2414 var result = {}; 2415 if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 2416 __setModuleDefault(result, mod); 2417 return result; 2418 }; 2419 Object.defineProperty(exports, "__esModule", ({ value: true })); 2420 exports.asPostCSSv8PluginGenerator = exports.isPostCSSv8 = void 0; 2421 const PostCSSPrefixWrap_1 = __importStar(__webpack_require__(1311)); 2422 const isPostCSSv8 = (postcss) => postcss.Root !== undefined; 2423 exports.isPostCSSv8 = isPostCSSv8; 2424 const asPostCSSv8PluginGenerator = () => { 2425 return (prefixSelector, options) => { 2426 const plugin = new PostCSSPrefixWrap_1.default(prefixSelector, options); 2427 return { 2428 postcssPlugin: PostCSSPrefixWrap_1.PLUGIN_NAME, 2429 Once(root) { 2430 plugin.prefixRoot(root); 2431 }, 2432 }; 2433 }; 2434 }; 2435 exports.asPostCSSv8PluginGenerator = asPostCSSv8PluginGenerator; 2436 2437 2438 /***/ }), 2439 2440 /***/ 3576: 2441 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 2442 2443 "use strict"; 2444 2445 const PostCSS8Plugin_1 = __webpack_require__(2888); 2446 const PostCSS7Plugin_1 = __webpack_require__(8061); 2447 module.exports = (postcss) => { 2448 if ((0, PostCSS8Plugin_1.isPostCSSv8)(postcss)) { 2449 return (0, PostCSS8Plugin_1.asPostCSSv8PluginGenerator)(); 2450 } 2451 else { 2452 return (0, PostCSS7Plugin_1.asPostCSSv7PluginGenerator)(postcss); 2453 } 2454 }; 2455 2456 2457 /***/ }), 2458 2459 /***/ 1311: 2460 /***/ ((__unused_webpack_module, exports, __webpack_require__) => { 2461 2462 "use strict"; 2463 2464 Object.defineProperty(exports, "__esModule", ({ value: true })); 2465 exports.PLUGIN_NAME = void 0; 2466 const CSSRuleWrapper_1 = __webpack_require__(5525); 2467 const FileIncludeList_1 = __webpack_require__(9411); 2468 exports.PLUGIN_NAME = "postcss-prefixwrap"; 2469 class PostCSSPrefixWrap { 2470 blacklist; 2471 ignoredSelectors; 2472 isPrefixSelector; 2473 prefixRootTags; 2474 prefixSelector; 2475 whitelist; 2476 nested; 2477 constructor(prefixSelector, options = {}) { 2478 this.blacklist = options.blacklist ?? []; 2479 this.ignoredSelectors = options.ignoredSelectors ?? []; 2480 this.isPrefixSelector = new RegExp( 2481 // eslint-disable-next-line security-node/non-literal-reg-expr 2482 `^$prefixSelector.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}$`); 2483 this.prefixRootTags = options.prefixRootTags ?? false; 2484 this.prefixSelector = prefixSelector; 2485 this.whitelist = options.whitelist ?? []; 2486 this.nested = options.nested ?? null; 2487 } 2488 prefixRoot(css) { 2489 if ((0, FileIncludeList_1.shouldIncludeFilePath)(css.source?.input?.file, this.whitelist, this.blacklist)) { 2490 css.walkRules((cssRule) => { 2491 (0, CSSRuleWrapper_1.prefixWrapCSSRule)(cssRule, this.nested, this.ignoredSelectors, this.prefixSelector, this.prefixRootTags); 2492 }); 2493 } 2494 } 2495 prefix() { 2496 return (css) => { 2497 this.prefixRoot(css); 2498 }; 2499 } 2500 } 2501 exports["default"] = PostCSSPrefixWrap; 2502 2503 2504 /***/ }), 2505 2506 /***/ 5404: 2507 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 2508 2509 const CSSValueParser = __webpack_require__(1544) 2510 2511 /** 2512 * @type {import('postcss').PluginCreator} 2513 */ 2514 module.exports = (opts) => { 2515 2516 const DEFAULTS = { 2517 skipHostRelativeUrls: true, 2518 } 2519 const config = Object.assign(DEFAULTS, opts) 2520 2521 return { 2522 postcssPlugin: 'rebaseUrl', 2523 2524 Declaration(decl) { 2525 // The faster way to find Declaration node 2526 const parsedValue = CSSValueParser(decl.value) 2527 2528 let valueChanged = false 2529 parsedValue.walk(node => { 2530 if (node.type !== 'function' || node.value !== 'url') { 2531 return 2532 } 2533 2534 const urlVal = node.nodes[0].value 2535 2536 // bases relative URLs with rootUrl 2537 const basedUrl = new URL(urlVal, opts.rootUrl) 2538 2539 // skip host-relative, already normalized URLs (e.g. `/images/image.jpg`, without `..`s) 2540 if ((basedUrl.pathname === urlVal) && config.skipHostRelativeUrls) { 2541 return false // skip this value 2542 } 2543 2544 node.nodes[0].value = basedUrl.toString() 2545 valueChanged = true 2546 2547 return false // do not walk deeper 2548 }) 2549 2550 if (valueChanged) { 2551 decl.value = CSSValueParser.stringify(parsedValue) 2552 } 2553 2554 } 2555 } 2556 } 2557 2558 module.exports.postcss = true 2559 2560 2561 /***/ }), 2562 2563 /***/ 1544: 2564 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 2565 2566 var parse = __webpack_require__(8491); 2567 var walk = __webpack_require__(3815); 2568 var stringify = __webpack_require__(4725); 2569 2570 function ValueParser(value) { 2571 if (this instanceof ValueParser) { 2572 this.nodes = parse(value); 2573 return this; 2574 } 2575 return new ValueParser(value); 2576 } 2577 2578 ValueParser.prototype.toString = function() { 2579 return Array.isArray(this.nodes) ? stringify(this.nodes) : ""; 2580 }; 2581 2582 ValueParser.prototype.walk = function(cb, bubble) { 2583 walk(this.nodes, cb, bubble); 2584 return this; 2585 }; 2586 2587 ValueParser.unit = __webpack_require__(1524); 2588 2589 ValueParser.walk = walk; 2590 2591 ValueParser.stringify = stringify; 2592 2593 module.exports = ValueParser; 2594 2595 2596 /***/ }), 2597 2598 /***/ 8491: 2599 /***/ ((module) => { 2600 2601 var openParentheses = "(".charCodeAt(0); 2602 var closeParentheses = ")".charCodeAt(0); 2603 var singleQuote = "'".charCodeAt(0); 2604 var doubleQuote = '"'.charCodeAt(0); 2605 var backslash = "\\".charCodeAt(0); 2606 var slash = "/".charCodeAt(0); 2607 var comma = ",".charCodeAt(0); 2608 var colon = ":".charCodeAt(0); 2609 var star = "*".charCodeAt(0); 2610 var uLower = "u".charCodeAt(0); 2611 var uUpper = "U".charCodeAt(0); 2612 var plus = "+".charCodeAt(0); 2613 var isUnicodeRange = /^[a-f0-9?-]+$/i; 2614 2615 module.exports = function(input) { 2616 var tokens = []; 2617 var value = input; 2618 2619 var next, 2620 quote, 2621 prev, 2622 token, 2623 escape, 2624 escapePos, 2625 whitespacePos, 2626 parenthesesOpenPos; 2627 var pos = 0; 2628 var code = value.charCodeAt(pos); 2629 var max = value.length; 2630 var stack = [{ nodes: tokens }]; 2631 var balanced = 0; 2632 var parent; 2633 2634 var name = ""; 2635 var before = ""; 2636 var after = ""; 2637 2638 while (pos < max) { 2639 // Whitespaces 2640 if (code <= 32) { 2641 next = pos; 2642 do { 2643 next += 1; 2644 code = value.charCodeAt(next); 2645 } while (code <= 32); 2646 token = value.slice(pos, next); 2647 2648 prev = tokens[tokens.length - 1]; 2649 if (code === closeParentheses && balanced) { 2650 after = token; 2651 } else if (prev && prev.type === "div") { 2652 prev.after = token; 2653 prev.sourceEndIndex += token.length; 2654 } else if ( 2655 code === comma || 2656 code === colon || 2657 (code === slash && 2658 value.charCodeAt(next + 1) !== star && 2659 (!parent || 2660 (parent && parent.type === "function" && parent.value !== "calc"))) 2661 ) { 2662 before = token; 2663 } else { 2664 tokens.push({ 2665 type: "space", 2666 sourceIndex: pos, 2667 sourceEndIndex: next, 2668 value: token 2669 }); 2670 } 2671 2672 pos = next; 2673 2674 // Quotes 2675 } else if (code === singleQuote || code === doubleQuote) { 2676 next = pos; 2677 quote = code === singleQuote ? "'" : '"'; 2678 token = { 2679 type: "string", 2680 sourceIndex: pos, 2681 quote: quote 2682 }; 2683 do { 2684 escape = false; 2685 next = value.indexOf(quote, next + 1); 2686 if (~next) { 2687 escapePos = next; 2688 while (value.charCodeAt(escapePos - 1) === backslash) { 2689 escapePos -= 1; 2690 escape = !escape; 2691 } 2692 } else { 2693 value += quote; 2694 next = value.length - 1; 2695 token.unclosed = true; 2696 } 2697 } while (escape); 2698 token.value = value.slice(pos + 1, next); 2699 token.sourceEndIndex = token.unclosed ? next : next + 1; 2700 tokens.push(token); 2701 pos = next + 1; 2702 code = value.charCodeAt(pos); 2703 2704 // Comments 2705 } else if (code === slash && value.charCodeAt(pos + 1) === star) { 2706 next = value.indexOf("*/", pos); 2707 2708 token = { 2709 type: "comment", 2710 sourceIndex: pos, 2711 sourceEndIndex: next + 2 2712 }; 2713 2714 if (next === -1) { 2715 token.unclosed = true; 2716 next = value.length; 2717 token.sourceEndIndex = next; 2718 } 2719 2720 token.value = value.slice(pos + 2, next); 2721 tokens.push(token); 2722 2723 pos = next + 2; 2724 code = value.charCodeAt(pos); 2725 2726 // Operation within calc 2727 } else if ( 2728 (code === slash || code === star) && 2729 parent && 2730 parent.type === "function" && 2731 parent.value === "calc" 2732 ) { 2733 token = value[pos]; 2734 tokens.push({ 2735 type: "word", 2736 sourceIndex: pos - before.length, 2737 sourceEndIndex: pos + token.length, 2738 value: token 2739 }); 2740 pos += 1; 2741 code = value.charCodeAt(pos); 2742 2743 // Dividers 2744 } else if (code === slash || code === comma || code === colon) { 2745 token = value[pos]; 2746 2747 tokens.push({ 2748 type: "div", 2749 sourceIndex: pos - before.length, 2750 sourceEndIndex: pos + token.length, 2751 value: token, 2752 before: before, 2753 after: "" 2754 }); 2755 before = ""; 2756 2757 pos += 1; 2758 code = value.charCodeAt(pos); 2759 2760 // Open parentheses 2761 } else if (openParentheses === code) { 2762 // Whitespaces after open parentheses 2763 next = pos; 2764 do { 2765 next += 1; 2766 code = value.charCodeAt(next); 2767 } while (code <= 32); 2768 parenthesesOpenPos = pos; 2769 token = { 2770 type: "function", 2771 sourceIndex: pos - name.length, 2772 value: name, 2773 before: value.slice(parenthesesOpenPos + 1, next) 2774 }; 2775 pos = next; 2776 2777 if (name === "url" && code !== singleQuote && code !== doubleQuote) { 2778 next -= 1; 2779 do { 2780 escape = false; 2781 next = value.indexOf(")", next + 1); 2782 if (~next) { 2783 escapePos = next; 2784 while (value.charCodeAt(escapePos - 1) === backslash) { 2785 escapePos -= 1; 2786 escape = !escape; 2787 } 2788 } else { 2789 value += ")"; 2790 next = value.length - 1; 2791 token.unclosed = true; 2792 } 2793 } while (escape); 2794 // Whitespaces before closed 2795 whitespacePos = next; 2796 do { 2797 whitespacePos -= 1; 2798 code = value.charCodeAt(whitespacePos); 2799 } while (code <= 32); 2800 if (parenthesesOpenPos < whitespacePos) { 2801 if (pos !== whitespacePos + 1) { 2802 token.nodes = [ 2803 { 2804 type: "word", 2805 sourceIndex: pos, 2806 sourceEndIndex: whitespacePos + 1, 2807 value: value.slice(pos, whitespacePos + 1) 2808 } 2809 ]; 2810 } else { 2811 token.nodes = []; 2812 } 2813 if (token.unclosed && whitespacePos + 1 !== next) { 2814 token.after = ""; 2815 token.nodes.push({ 2816 type: "space", 2817 sourceIndex: whitespacePos + 1, 2818 sourceEndIndex: next, 2819 value: value.slice(whitespacePos + 1, next) 2820 }); 2821 } else { 2822 token.after = value.slice(whitespacePos + 1, next); 2823 token.sourceEndIndex = next; 2824 } 2825 } else { 2826 token.after = ""; 2827 token.nodes = []; 2828 } 2829 pos = next + 1; 2830 token.sourceEndIndex = token.unclosed ? next : pos; 2831 code = value.charCodeAt(pos); 2832 tokens.push(token); 2833 } else { 2834 balanced += 1; 2835 token.after = ""; 2836 token.sourceEndIndex = pos + 1; 2837 tokens.push(token); 2838 stack.push(token); 2839 tokens = token.nodes = []; 2840 parent = token; 2841 } 2842 name = ""; 2843 2844 // Close parentheses 2845 } else if (closeParentheses === code && balanced) { 2846 pos += 1; 2847 code = value.charCodeAt(pos); 2848 2849 parent.after = after; 2850 parent.sourceEndIndex += after.length; 2851 after = ""; 2852 balanced -= 1; 2853 stack[stack.length - 1].sourceEndIndex = pos; 2854 stack.pop(); 2855 parent = stack[balanced]; 2856 tokens = parent.nodes; 2857 2858 // Words 2859 } else { 2860 next = pos; 2861 do { 2862 if (code === backslash) { 2863 next += 1; 2864 } 2865 next += 1; 2866 code = value.charCodeAt(next); 2867 } while ( 2868 next < max && 2869 !( 2870 code <= 32 || 2871 code === singleQuote || 2872 code === doubleQuote || 2873 code === comma || 2874 code === colon || 2875 code === slash || 2876 code === openParentheses || 2877 (code === star && 2878 parent && 2879 parent.type === "function" && 2880 parent.value === "calc") || 2881 (code === slash && 2882 parent.type === "function" && 2883 parent.value === "calc") || 2884 (code === closeParentheses && balanced) 2885 ) 2886 ); 2887 token = value.slice(pos, next); 2888 2889 if (openParentheses === code) { 2890 name = token; 2891 } else if ( 2892 (uLower === token.charCodeAt(0) || uUpper === token.charCodeAt(0)) && 2893 plus === token.charCodeAt(1) && 2894 isUnicodeRange.test(token.slice(2)) 2895 ) { 2896 tokens.push({ 2897 type: "unicode-range", 2898 sourceIndex: pos, 2899 sourceEndIndex: next, 2900 value: token 2901 }); 2902 } else { 2903 tokens.push({ 2904 type: "word", 2905 sourceIndex: pos, 2906 sourceEndIndex: next, 2907 value: token 2908 }); 2909 } 2910 2911 pos = next; 2912 } 2913 } 2914 2915 for (pos = stack.length - 1; pos; pos -= 1) { 2916 stack[pos].unclosed = true; 2917 stack[pos].sourceEndIndex = value.length; 2918 } 2919 2920 return stack[0].nodes; 2921 }; 2922 2923 2924 /***/ }), 2925 2926 /***/ 4725: 2927 /***/ ((module) => { 2928 2929 function stringifyNode(node, custom) { 2930 var type = node.type; 2931 var value = node.value; 2932 var buf; 2933 var customResult; 2934 2935 if (custom && (customResult = custom(node)) !== undefined) { 2936 return customResult; 2937 } else if (type === "word" || type === "space") { 2938 return value; 2939 } else if (type === "string") { 2940 buf = node.quote || ""; 2941 return buf + value + (node.unclosed ? "" : buf); 2942 } else if (type === "comment") { 2943 return "/*" + value + (node.unclosed ? "" : "*/"); 2944 } else if (type === "div") { 2945 return (node.before || "") + value + (node.after || ""); 2946 } else if (Array.isArray(node.nodes)) { 2947 buf = stringify(node.nodes, custom); 2948 if (type !== "function") { 2949 return buf; 2950 } 2951 return ( 2952 value + 2953 "(" + 2954 (node.before || "") + 2955 buf + 2956 (node.after || "") + 2957 (node.unclosed ? "" : ")") 2958 ); 2959 } 2960 return value; 2961 } 2962 2963 function stringify(nodes, custom) { 2964 var result, i; 2965 2966 if (Array.isArray(nodes)) { 2967 result = ""; 2968 for (i = nodes.length - 1; ~i; i -= 1) { 2969 result = stringifyNode(nodes[i], custom) + result; 2970 } 2971 return result; 2972 } 2973 return stringifyNode(nodes, custom); 2974 } 2975 2976 module.exports = stringify; 2977 2978 2979 /***/ }), 2980 2981 /***/ 1524: 2982 /***/ ((module) => { 2983 2984 var minus = "-".charCodeAt(0); 2985 var plus = "+".charCodeAt(0); 2986 var dot = ".".charCodeAt(0); 2987 var exp = "e".charCodeAt(0); 2988 var EXP = "E".charCodeAt(0); 2989 2990 // Check if three code points would start a number 2991 // https://www.w3.org/TR/css-syntax-3/#starts-with-a-number 2992 function likeNumber(value) { 2993 var code = value.charCodeAt(0); 2994 var nextCode; 2995 2996 if (code === plus || code === minus) { 2997 nextCode = value.charCodeAt(1); 2998 2999 if (nextCode >= 48 && nextCode <= 57) { 3000 return true; 3001 } 3002 3003 var nextNextCode = value.charCodeAt(2); 3004 3005 if (nextCode === dot && nextNextCode >= 48 && nextNextCode <= 57) { 3006 return true; 3007 } 3008 3009 return false; 3010 } 3011 3012 if (code === dot) { 3013 nextCode = value.charCodeAt(1); 3014 3015 if (nextCode >= 48 && nextCode <= 57) { 3016 return true; 3017 } 3018 3019 return false; 3020 } 3021 3022 if (code >= 48 && code <= 57) { 3023 return true; 3024 } 3025 3026 return false; 3027 } 3028 3029 // Consume a number 3030 // https://www.w3.org/TR/css-syntax-3/#consume-number 3031 module.exports = function(value) { 3032 var pos = 0; 3033 var length = value.length; 3034 var code; 3035 var nextCode; 3036 var nextNextCode; 3037 3038 if (length === 0 || !likeNumber(value)) { 3039 return false; 3040 } 3041 3042 code = value.charCodeAt(pos); 3043 3044 if (code === plus || code === minus) { 3045 pos++; 3046 } 3047 3048 while (pos < length) { 3049 code = value.charCodeAt(pos); 3050 3051 if (code < 48 || code > 57) { 3052 break; 3053 } 3054 3055 pos += 1; 3056 } 3057 3058 code = value.charCodeAt(pos); 3059 nextCode = value.charCodeAt(pos + 1); 3060 3061 if (code === dot && nextCode >= 48 && nextCode <= 57) { 3062 pos += 2; 3063 3064 while (pos < length) { 3065 code = value.charCodeAt(pos); 3066 3067 if (code < 48 || code > 57) { 3068 break; 3069 } 3070 3071 pos += 1; 3072 } 3073 } 3074 3075 code = value.charCodeAt(pos); 3076 nextCode = value.charCodeAt(pos + 1); 3077 nextNextCode = value.charCodeAt(pos + 2); 3078 3079 if ( 3080 (code === exp || code === EXP) && 3081 ((nextCode >= 48 && nextCode <= 57) || 3082 ((nextCode === plus || nextCode === minus) && 3083 nextNextCode >= 48 && 3084 nextNextCode <= 57)) 3085 ) { 3086 pos += nextCode === plus || nextCode === minus ? 3 : 2; 3087 3088 while (pos < length) { 3089 code = value.charCodeAt(pos); 3090 3091 if (code < 48 || code > 57) { 3092 break; 3093 } 3094 3095 pos += 1; 3096 } 3097 } 3098 3099 return { 3100 number: value.slice(0, pos), 3101 unit: value.slice(pos) 3102 }; 3103 }; 3104 3105 3106 /***/ }), 3107 3108 /***/ 3815: 3109 /***/ ((module) => { 3110 3111 module.exports = function walk(nodes, cb, bubble) { 3112 var i, max, node, result; 3113 3114 for (i = 0, max = nodes.length; i < max; i += 1) { 3115 node = nodes[i]; 3116 if (!bubble) { 3117 result = cb(node, i, nodes); 3118 } 3119 3120 if ( 3121 result !== false && 3122 node.type === "function" && 3123 Array.isArray(node.nodes) 3124 ) { 3125 walk(node.nodes, cb, bubble); 3126 } 3127 3128 if (bubble) { 3129 cb(node, i, nodes); 3130 } 3131 } 3132 }; 3133 3134 3135 /***/ }), 3136 3137 /***/ 1326: 3138 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 3139 3140 "use strict"; 3141 3142 3143 let Container = __webpack_require__(683) 3144 3145 class AtRule extends Container { 3146 constructor(defaults) { 3147 super(defaults) 3148 this.type = 'atrule' 3149 } 3150 3151 append(...children) { 3152 if (!this.proxyOf.nodes) this.nodes = [] 3153 return super.append(...children) 3154 } 3155 3156 prepend(...children) { 3157 if (!this.proxyOf.nodes) this.nodes = [] 3158 return super.prepend(...children) 3159 } 3160 } 3161 3162 module.exports = AtRule 3163 AtRule.default = AtRule 3164 3165 Container.registerAtRule(AtRule) 3166 3167 3168 /***/ }), 3169 3170 /***/ 6589: 3171 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 3172 3173 "use strict"; 3174 3175 3176 let Node = __webpack_require__(7490) 3177 3178 class Comment extends Node { 3179 constructor(defaults) { 3180 super(defaults) 3181 this.type = 'comment' 3182 } 3183 } 3184 3185 module.exports = Comment 3186 Comment.default = Comment 3187 3188 3189 /***/ }), 3190 3191 /***/ 683: 3192 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 3193 3194 "use strict"; 3195 3196 3197 let { isClean, my } = __webpack_require__(1381) 3198 let Declaration = __webpack_require__(1516) 3199 let Comment = __webpack_require__(6589) 3200 let Node = __webpack_require__(7490) 3201 3202 let parse, Rule, AtRule, Root 3203 3204 function cleanSource(nodes) { 3205 return nodes.map(i => { 3206 if (i.nodes) i.nodes = cleanSource(i.nodes) 3207 delete i.source 3208 return i 3209 }) 3210 } 3211 3212 function markDirtyUp(node) { 3213 node[isClean] = false 3214 if (node.proxyOf.nodes) { 3215 for (let i of node.proxyOf.nodes) { 3216 markDirtyUp(i) 3217 } 3218 } 3219 } 3220 3221 class Container extends Node { 3222 append(...children) { 3223 for (let child of children) { 3224 let nodes = this.normalize(child, this.last) 3225 for (let node of nodes) this.proxyOf.nodes.push(node) 3226 } 3227 3228 this.markDirty() 3229 3230 return this 3231 } 3232 3233 cleanRaws(keepBetween) { 3234 super.cleanRaws(keepBetween) 3235 if (this.nodes) { 3236 for (let node of this.nodes) node.cleanRaws(keepBetween) 3237 } 3238 } 3239 3240 each(callback) { 3241 if (!this.proxyOf.nodes) return undefined 3242 let iterator = this.getIterator() 3243 3244 let index, result 3245 while (this.indexes[iterator] < this.proxyOf.nodes.length) { 3246 index = this.indexes[iterator] 3247 result = callback(this.proxyOf.nodes[index], index) 3248 if (result === false) break 3249 3250 this.indexes[iterator] += 1 3251 } 3252 3253 delete this.indexes[iterator] 3254 return result 3255 } 3256 3257 every(condition) { 3258 return this.nodes.every(condition) 3259 } 3260 3261 getIterator() { 3262 if (!this.lastEach) this.lastEach = 0 3263 if (!this.indexes) this.indexes = {} 3264 3265 this.lastEach += 1 3266 let iterator = this.lastEach 3267 this.indexes[iterator] = 0 3268 3269 return iterator 3270 } 3271 3272 getProxyProcessor() { 3273 return { 3274 get(node, prop) { 3275 if (prop === 'proxyOf') { 3276 return node 3277 } else if (!node[prop]) { 3278 return node[prop] 3279 } else if ( 3280 prop === 'each' || 3281 (typeof prop === 'string' && prop.startsWith('walk')) 3282 ) { 3283 return (...args) => { 3284 return node[prop]( 3285 ...args.map(i => { 3286 if (typeof i === 'function') { 3287 return (child, index) => i(child.toProxy(), index) 3288 } else { 3289 return i 3290 } 3291 }) 3292 ) 3293 } 3294 } else if (prop === 'every' || prop === 'some') { 3295 return cb => { 3296 return node[prop]((child, ...other) => 3297 cb(child.toProxy(), ...other) 3298 ) 3299 } 3300 } else if (prop === 'root') { 3301 return () => node.root().toProxy() 3302 } else if (prop === 'nodes') { 3303 return node.nodes.map(i => i.toProxy()) 3304 } else if (prop === 'first' || prop === 'last') { 3305 return node[prop].toProxy() 3306 } else { 3307 return node[prop] 3308 } 3309 }, 3310 3311 set(node, prop, value) { 3312 if (node[prop] === value) return true 3313 node[prop] = value 3314 if (prop === 'name' || prop === 'params' || prop === 'selector') { 3315 node.markDirty() 3316 } 3317 return true 3318 } 3319 } 3320 } 3321 3322 index(child) { 3323 if (typeof child === 'number') return child 3324 if (child.proxyOf) child = child.proxyOf 3325 return this.proxyOf.nodes.indexOf(child) 3326 } 3327 3328 insertAfter(exist, add) { 3329 let existIndex = this.index(exist) 3330 let nodes = this.normalize(add, this.proxyOf.nodes[existIndex]).reverse() 3331 existIndex = this.index(exist) 3332 for (let node of nodes) this.proxyOf.nodes.splice(existIndex + 1, 0, node) 3333 3334 let index 3335 for (let id in this.indexes) { 3336 index = this.indexes[id] 3337 if (existIndex < index) { 3338 this.indexes[id] = index + nodes.length 3339 } 3340 } 3341 3342 this.markDirty() 3343 3344 return this 3345 } 3346 3347 insertBefore(exist, add) { 3348 let existIndex = this.index(exist) 3349 let type = existIndex === 0 ? 'prepend' : false 3350 let nodes = this.normalize(add, this.proxyOf.nodes[existIndex], type).reverse() 3351 existIndex = this.index(exist) 3352 for (let node of nodes) this.proxyOf.nodes.splice(existIndex, 0, node) 3353 3354 let index 3355 for (let id in this.indexes) { 3356 index = this.indexes[id] 3357 if (existIndex <= index) { 3358 this.indexes[id] = index + nodes.length 3359 } 3360 } 3361 3362 this.markDirty() 3363 3364 return this 3365 } 3366 3367 normalize(nodes, sample) { 3368 if (typeof nodes === 'string') { 3369 nodes = cleanSource(parse(nodes).nodes) 3370 } else if (typeof nodes === 'undefined') { 3371 nodes = [] 3372 } else if (Array.isArray(nodes)) { 3373 nodes = nodes.slice(0) 3374 for (let i of nodes) { 3375 if (i.parent) i.parent.removeChild(i, 'ignore') 3376 } 3377 } else if (nodes.type === 'root' && this.type !== 'document') { 3378 nodes = nodes.nodes.slice(0) 3379 for (let i of nodes) { 3380 if (i.parent) i.parent.removeChild(i, 'ignore') 3381 } 3382 } else if (nodes.type) { 3383 nodes = [nodes] 3384 } else if (nodes.prop) { 3385 if (typeof nodes.value === 'undefined') { 3386 throw new Error('Value field is missed in node creation') 3387 } else if (typeof nodes.value !== 'string') { 3388 nodes.value = String(nodes.value) 3389 } 3390 nodes = [new Declaration(nodes)] 3391 } else if (nodes.selector) { 3392 nodes = [new Rule(nodes)] 3393 } else if (nodes.name) { 3394 nodes = [new AtRule(nodes)] 3395 } else if (nodes.text) { 3396 nodes = [new Comment(nodes)] 3397 } else { 3398 throw new Error('Unknown node type in node creation') 3399 } 3400 3401 let processed = nodes.map(i => { 3402 /* c8 ignore next */ 3403 if (!i[my]) Container.rebuild(i) 3404 i = i.proxyOf 3405 if (i.parent) i.parent.removeChild(i) 3406 if (i[isClean]) markDirtyUp(i) 3407 if (typeof i.raws.before === 'undefined') { 3408 if (sample && typeof sample.raws.before !== 'undefined') { 3409 i.raws.before = sample.raws.before.replace(/\S/g, '') 3410 } 3411 } 3412 i.parent = this.proxyOf 3413 return i 3414 }) 3415 3416 return processed 3417 } 3418 3419 prepend(...children) { 3420 children = children.reverse() 3421 for (let child of children) { 3422 let nodes = this.normalize(child, this.first, 'prepend').reverse() 3423 for (let node of nodes) this.proxyOf.nodes.unshift(node) 3424 for (let id in this.indexes) { 3425 this.indexes[id] = this.indexes[id] + nodes.length 3426 } 3427 } 3428 3429 this.markDirty() 3430 3431 return this 3432 } 3433 3434 push(child) { 3435 child.parent = this 3436 this.proxyOf.nodes.push(child) 3437 return this 3438 } 3439 3440 removeAll() { 3441 for (let node of this.proxyOf.nodes) node.parent = undefined 3442 this.proxyOf.nodes = [] 3443 3444 this.markDirty() 3445 3446 return this 3447 } 3448 3449 removeChild(child) { 3450 child = this.index(child) 3451 this.proxyOf.nodes[child].parent = undefined 3452 this.proxyOf.nodes.splice(child, 1) 3453 3454 let index 3455 for (let id in this.indexes) { 3456 index = this.indexes[id] 3457 if (index >= child) { 3458 this.indexes[id] = index - 1 3459 } 3460 } 3461 3462 this.markDirty() 3463 3464 return this 3465 } 3466 3467 replaceValues(pattern, opts, callback) { 3468 if (!callback) { 3469 callback = opts 3470 opts = {} 3471 } 3472 3473 this.walkDecls(decl => { 3474 if (opts.props && !opts.props.includes(decl.prop)) return 3475 if (opts.fast && !decl.value.includes(opts.fast)) return 3476 3477 decl.value = decl.value.replace(pattern, callback) 3478 }) 3479 3480 this.markDirty() 3481 3482 return this 3483 } 3484 3485 some(condition) { 3486 return this.nodes.some(condition) 3487 } 3488 3489 walk(callback) { 3490 return this.each((child, i) => { 3491 let result 3492 try { 3493 result = callback(child, i) 3494 } catch (e) { 3495 throw child.addToError(e) 3496 } 3497 if (result !== false && child.walk) { 3498 result = child.walk(callback) 3499 } 3500 3501 return result 3502 }) 3503 } 3504 3505 walkAtRules(name, callback) { 3506 if (!callback) { 3507 callback = name 3508 return this.walk((child, i) => { 3509 if (child.type === 'atrule') { 3510 return callback(child, i) 3511 } 3512 }) 3513 } 3514 if (name instanceof RegExp) { 3515 return this.walk((child, i) => { 3516 if (child.type === 'atrule' && name.test(child.name)) { 3517 return callback(child, i) 3518 } 3519 }) 3520 } 3521 return this.walk((child, i) => { 3522 if (child.type === 'atrule' && child.name === name) { 3523 return callback(child, i) 3524 } 3525 }) 3526 } 3527 3528 walkComments(callback) { 3529 return this.walk((child, i) => { 3530 if (child.type === 'comment') { 3531 return callback(child, i) 3532 } 3533 }) 3534 } 3535 3536 walkDecls(prop, callback) { 3537 if (!callback) { 3538 callback = prop 3539 return this.walk((child, i) => { 3540 if (child.type === 'decl') { 3541 return callback(child, i) 3542 } 3543 }) 3544 } 3545 if (prop instanceof RegExp) { 3546 return this.walk((child, i) => { 3547 if (child.type === 'decl' && prop.test(child.prop)) { 3548 return callback(child, i) 3549 } 3550 }) 3551 } 3552 return this.walk((child, i) => { 3553 if (child.type === 'decl' && child.prop === prop) { 3554 return callback(child, i) 3555 } 3556 }) 3557 } 3558 3559 walkRules(selector, callback) { 3560 if (!callback) { 3561 callback = selector 3562 3563 return this.walk((child, i) => { 3564 if (child.type === 'rule') { 3565 return callback(child, i) 3566 } 3567 }) 3568 } 3569 if (selector instanceof RegExp) { 3570 return this.walk((child, i) => { 3571 if (child.type === 'rule' && selector.test(child.selector)) { 3572 return callback(child, i) 3573 } 3574 }) 3575 } 3576 return this.walk((child, i) => { 3577 if (child.type === 'rule' && child.selector === selector) { 3578 return callback(child, i) 3579 } 3580 }) 3581 } 3582 3583 get first() { 3584 if (!this.proxyOf.nodes) return undefined 3585 return this.proxyOf.nodes[0] 3586 } 3587 3588 get last() { 3589 if (!this.proxyOf.nodes) return undefined 3590 return this.proxyOf.nodes[this.proxyOf.nodes.length - 1] 3591 } 3592 } 3593 3594 Container.registerParse = dependant => { 3595 parse = dependant 3596 } 3597 3598 Container.registerRule = dependant => { 3599 Rule = dependant 3600 } 3601 3602 Container.registerAtRule = dependant => { 3603 AtRule = dependant 3604 } 3605 3606 Container.registerRoot = dependant => { 3607 Root = dependant 3608 } 3609 3610 module.exports = Container 3611 Container.default = Container 3612 3613 /* c8 ignore start */ 3614 Container.rebuild = node => { 3615 if (node.type === 'atrule') { 3616 Object.setPrototypeOf(node, AtRule.prototype) 3617 } else if (node.type === 'rule') { 3618 Object.setPrototypeOf(node, Rule.prototype) 3619 } else if (node.type === 'decl') { 3620 Object.setPrototypeOf(node, Declaration.prototype) 3621 } else if (node.type === 'comment') { 3622 Object.setPrototypeOf(node, Comment.prototype) 3623 } else if (node.type === 'root') { 3624 Object.setPrototypeOf(node, Root.prototype) 3625 } 3626 3627 node[my] = true 3628 3629 if (node.nodes) { 3630 node.nodes.forEach(child => { 3631 Container.rebuild(child) 3632 }) 3633 } 3634 } 3635 /* c8 ignore stop */ 3636 3637 3638 /***/ }), 3639 3640 /***/ 356: 3641 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 3642 3643 "use strict"; 3644 3645 3646 let pico = __webpack_require__(2775) 3647 3648 let terminalHighlight = __webpack_require__(9746) 3649 3650 class CssSyntaxError extends Error { 3651 constructor(message, line, column, source, file, plugin) { 3652 super(message) 3653 this.name = 'CssSyntaxError' 3654 this.reason = message 3655 3656 if (file) { 3657 this.file = file 3658 } 3659 if (source) { 3660 this.source = source 3661 } 3662 if (plugin) { 3663 this.plugin = plugin 3664 } 3665 if (typeof line !== 'undefined' && typeof column !== 'undefined') { 3666 if (typeof line === 'number') { 3667 this.line = line 3668 this.column = column 3669 } else { 3670 this.line = line.line 3671 this.column = line.column 3672 this.endLine = column.line 3673 this.endColumn = column.column 3674 } 3675 } 3676 3677 this.setMessage() 3678 3679 if (Error.captureStackTrace) { 3680 Error.captureStackTrace(this, CssSyntaxError) 3681 } 3682 } 3683 3684 setMessage() { 3685 this.message = this.plugin ? this.plugin + ': ' : '' 3686 this.message += this.file ? this.file : '<css input>' 3687 if (typeof this.line !== 'undefined') { 3688 this.message += ':' + this.line + ':' + this.column 3689 } 3690 this.message += ': ' + this.reason 3691 } 3692 3693 showSourceCode(color) { 3694 if (!this.source) return '' 3695 3696 let css = this.source 3697 if (color == null) color = pico.isColorSupported 3698 if (terminalHighlight) { 3699 if (color) css = terminalHighlight(css) 3700 } 3701 3702 let lines = css.split(/\r?\n/) 3703 let start = Math.max(this.line - 3, 0) 3704 let end = Math.min(this.line + 2, lines.length) 3705 3706 let maxWidth = String(end).length 3707 3708 let mark, aside 3709 if (color) { 3710 let { bold, gray, red } = pico.createColors(true) 3711 mark = text => bold(red(text)) 3712 aside = text => gray(text) 3713 } else { 3714 mark = aside = str => str 3715 } 3716 3717 return lines 3718 .slice(start, end) 3719 .map((line, index) => { 3720 let number = start + 1 + index 3721 let gutter = ' ' + (' ' + number).slice(-maxWidth) + ' | ' 3722 if (number === this.line) { 3723 let spacing = 3724 aside(gutter.replace(/\d/g, ' ')) + 3725 line.slice(0, this.column - 1).replace(/[^\t]/g, ' ') 3726 return mark('>') + aside(gutter) + line + '\n ' + spacing + mark('^') 3727 } 3728 return ' ' + aside(gutter) + line 3729 }) 3730 .join('\n') 3731 } 3732 3733 toString() { 3734 let code = this.showSourceCode() 3735 if (code) { 3736 code = '\n\n' + code + '\n' 3737 } 3738 return this.name + ': ' + this.message + code 3739 } 3740 } 3741 3742 module.exports = CssSyntaxError 3743 CssSyntaxError.default = CssSyntaxError 3744 3745 3746 /***/ }), 3747 3748 /***/ 1516: 3749 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 3750 3751 "use strict"; 3752 3753 3754 let Node = __webpack_require__(7490) 3755 3756 class Declaration extends Node { 3757 constructor(defaults) { 3758 if ( 3759 defaults && 3760 typeof defaults.value !== 'undefined' && 3761 typeof defaults.value !== 'string' 3762 ) { 3763 defaults = { ...defaults, value: String(defaults.value) } 3764 } 3765 super(defaults) 3766 this.type = 'decl' 3767 } 3768 3769 get variable() { 3770 return this.prop.startsWith('--') || this.prop[0] === '$' 3771 } 3772 } 3773 3774 module.exports = Declaration 3775 Declaration.default = Declaration 3776 3777 3778 /***/ }), 3779 3780 /***/ 271: 3781 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 3782 3783 "use strict"; 3784 3785 3786 let Container = __webpack_require__(683) 3787 3788 let LazyResult, Processor 3789 3790 class Document extends Container { 3791 constructor(defaults) { 3792 // type needs to be passed to super, otherwise child roots won't be normalized correctly 3793 super({ type: 'document', ...defaults }) 3794 3795 if (!this.nodes) { 3796 this.nodes = [] 3797 } 3798 } 3799 3800 toResult(opts = {}) { 3801 let lazy = new LazyResult(new Processor(), this, opts) 3802 3803 return lazy.stringify() 3804 } 3805 } 3806 3807 Document.registerLazyResult = dependant => { 3808 LazyResult = dependant 3809 } 3810 3811 Document.registerProcessor = dependant => { 3812 Processor = dependant 3813 } 3814 3815 module.exports = Document 3816 Document.default = Document 3817 3818 3819 /***/ }), 3820 3821 /***/ 8940: 3822 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 3823 3824 "use strict"; 3825 3826 3827 let Declaration = __webpack_require__(1516) 3828 let PreviousMap = __webpack_require__(5696) 3829 let Comment = __webpack_require__(6589) 3830 let AtRule = __webpack_require__(1326) 3831 let Input = __webpack_require__(5380) 3832 let Root = __webpack_require__(9434) 3833 let Rule = __webpack_require__(4092) 3834 3835 function fromJSON(json, inputs) { 3836 if (Array.isArray(json)) return json.map(n => fromJSON(n)) 3837 3838 let { inputs: ownInputs, ...defaults } = json 3839 if (ownInputs) { 3840 inputs = [] 3841 for (let input of ownInputs) { 3842 let inputHydrated = { ...input, __proto__: Input.prototype } 3843 if (inputHydrated.map) { 3844 inputHydrated.map = { 3845 ...inputHydrated.map, 3846 __proto__: PreviousMap.prototype 3847 } 3848 } 3849 inputs.push(inputHydrated) 3850 } 3851 } 3852 if (defaults.nodes) { 3853 defaults.nodes = json.nodes.map(n => fromJSON(n, inputs)) 3854 } 3855 if (defaults.source) { 3856 let { inputId, ...source } = defaults.source 3857 defaults.source = source 3858 if (inputId != null) { 3859 defaults.source.input = inputs[inputId] 3860 } 3861 } 3862 if (defaults.type === 'root') { 3863 return new Root(defaults) 3864 } else if (defaults.type === 'decl') { 3865 return new Declaration(defaults) 3866 } else if (defaults.type === 'rule') { 3867 return new Rule(defaults) 3868 } else if (defaults.type === 'comment') { 3869 return new Comment(defaults) 3870 } else if (defaults.type === 'atrule') { 3871 return new AtRule(defaults) 3872 } else { 3873 throw new Error('Unknown node type: ' + json.type) 3874 } 3875 } 3876 3877 module.exports = fromJSON 3878 fromJSON.default = fromJSON 3879 3880 3881 /***/ }), 3882 3883 /***/ 5380: 3884 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 3885 3886 "use strict"; 3887 3888 3889 let { SourceMapConsumer, SourceMapGenerator } = __webpack_require__(1866) 3890 let { fileURLToPath, pathToFileURL } = __webpack_require__(2739) 3891 let { isAbsolute, resolve } = __webpack_require__(197) 3892 let { nanoid } = __webpack_require__(5042) 3893 3894 let terminalHighlight = __webpack_require__(9746) 3895 let CssSyntaxError = __webpack_require__(356) 3896 let PreviousMap = __webpack_require__(5696) 3897 3898 let fromOffsetCache = Symbol('fromOffsetCache') 3899 3900 let sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator) 3901 let pathAvailable = Boolean(resolve && isAbsolute) 3902 3903 class Input { 3904 constructor(css, opts = {}) { 3905 if ( 3906 css === null || 3907 typeof css === 'undefined' || 3908 (typeof css === 'object' && !css.toString) 3909 ) { 3910 throw new Error(`PostCSS received $css} instead of CSS string`) 3911 } 3912 3913 this.css = css.toString() 3914 3915 if (this.css[0] === '\uFEFF' || this.css[0] === '\uFFFE') { 3916 this.hasBOM = true 3917 this.css = this.css.slice(1) 3918 } else { 3919 this.hasBOM = false 3920 } 3921 3922 if (opts.from) { 3923 if ( 3924 !pathAvailable || 3925 /^\w+:\/\//.test(opts.from) || 3926 isAbsolute(opts.from) 3927 ) { 3928 this.file = opts.from 3929 } else { 3930 this.file = resolve(opts.from) 3931 } 3932 } 3933 3934 if (pathAvailable && sourceMapAvailable) { 3935 let map = new PreviousMap(this.css, opts) 3936 if (map.text) { 3937 this.map = map 3938 let file = map.consumer().file 3939 if (!this.file && file) this.file = this.mapResolve(file) 3940 } 3941 } 3942 3943 if (!this.file) { 3944 this.id = '<input css ' + nanoid(6) + '>' 3945 } 3946 if (this.map) this.map.file = this.from 3947 } 3948 3949 error(message, line, column, opts = {}) { 3950 let result, endLine, endColumn 3951 3952 if (line && typeof line === 'object') { 3953 let start = line 3954 let end = column 3955 if (typeof start.offset === 'number') { 3956 let pos = this.fromOffset(start.offset) 3957 line = pos.line 3958 column = pos.col 3959 } else { 3960 line = start.line 3961 column = start.column 3962 } 3963 if (typeof end.offset === 'number') { 3964 let pos = this.fromOffset(end.offset) 3965 endLine = pos.line 3966 endColumn = pos.col 3967 } else { 3968 endLine = end.line 3969 endColumn = end.column 3970 } 3971 } else if (!column) { 3972 let pos = this.fromOffset(line) 3973 line = pos.line 3974 column = pos.col 3975 } 3976 3977 let origin = this.origin(line, column, endLine, endColumn) 3978 if (origin) { 3979 result = new CssSyntaxError( 3980 message, 3981 origin.endLine === undefined 3982 ? origin.line 3983 : { column: origin.column, line: origin.line }, 3984 origin.endLine === undefined 3985 ? origin.column 3986 : { column: origin.endColumn, line: origin.endLine }, 3987 origin.source, 3988 origin.file, 3989 opts.plugin 3990 ) 3991 } else { 3992 result = new CssSyntaxError( 3993 message, 3994 endLine === undefined ? line : { column, line }, 3995 endLine === undefined ? column : { column: endColumn, line: endLine }, 3996 this.css, 3997 this.file, 3998 opts.plugin 3999 ) 4000 } 4001 4002 result.input = { column, endColumn, endLine, line, source: this.css } 4003 if (this.file) { 4004 if (pathToFileURL) { 4005 result.input.url = pathToFileURL(this.file).toString() 4006 } 4007 result.input.file = this.file 4008 } 4009 4010 return result 4011 } 4012 4013 fromOffset(offset) { 4014 let lastLine, lineToIndex 4015 if (!this[fromOffsetCache]) { 4016 let lines = this.css.split('\n') 4017 lineToIndex = new Array(lines.length) 4018 let prevIndex = 0 4019 4020 for (let i = 0, l = lines.length; i < l; i++) { 4021 lineToIndex[i] = prevIndex 4022 prevIndex += lines[i].length + 1 4023 } 4024 4025 this[fromOffsetCache] = lineToIndex 4026 } else { 4027 lineToIndex = this[fromOffsetCache] 4028 } 4029 lastLine = lineToIndex[lineToIndex.length - 1] 4030 4031 let min = 0 4032 if (offset >= lastLine) { 4033 min = lineToIndex.length - 1 4034 } else { 4035 let max = lineToIndex.length - 2 4036 let mid 4037 while (min < max) { 4038 mid = min + ((max - min) >> 1) 4039 if (offset < lineToIndex[mid]) { 4040 max = mid - 1 4041 } else if (offset >= lineToIndex[mid + 1]) { 4042 min = mid + 1 4043 } else { 4044 min = mid 4045 break 4046 } 4047 } 4048 } 4049 return { 4050 col: offset - lineToIndex[min] + 1, 4051 line: min + 1 4052 } 4053 } 4054 4055 mapResolve(file) { 4056 if (/^\w+:\/\//.test(file)) { 4057 return file 4058 } 4059 return resolve(this.map.consumer().sourceRoot || this.map.root || '.', file) 4060 } 4061 4062 origin(line, column, endLine, endColumn) { 4063 if (!this.map) return false 4064 let consumer = this.map.consumer() 4065 4066 let from = consumer.originalPositionFor({ column, line }) 4067 if (!from.source) return false 4068 4069 let to 4070 if (typeof endLine === 'number') { 4071 to = consumer.originalPositionFor({ column: endColumn, line: endLine }) 4072 } 4073 4074 let fromUrl 4075 4076 if (isAbsolute(from.source)) { 4077 fromUrl = pathToFileURL(from.source) 4078 } else { 4079 fromUrl = new URL( 4080 from.source, 4081 this.map.consumer().sourceRoot || pathToFileURL(this.map.mapFile) 4082 ) 4083 } 4084 4085 let result = { 4086 column: from.column, 4087 endColumn: to && to.column, 4088 endLine: to && to.line, 4089 line: from.line, 4090 url: fromUrl.toString() 4091 } 4092 4093 if (fromUrl.protocol === 'file:') { 4094 if (fileURLToPath) { 4095 result.file = fileURLToPath(fromUrl) 4096 } else { 4097 /* c8 ignore next 2 */ 4098 throw new Error(`file: protocol is not available in this PostCSS build`) 4099 } 4100 } 4101 4102 let source = consumer.sourceContentFor(from.source) 4103 if (source) result.source = source 4104 4105 return result 4106 } 4107 4108 toJSON() { 4109 let json = {} 4110 for (let name of ['hasBOM', 'css', 'file', 'id']) { 4111 if (this[name] != null) { 4112 json[name] = this[name] 4113 } 4114 } 4115 if (this.map) { 4116 json.map = { ...this.map } 4117 if (json.map.consumerCache) { 4118 json.map.consumerCache = undefined 4119 } 4120 } 4121 return json 4122 } 4123 4124 get from() { 4125 return this.file || this.id 4126 } 4127 } 4128 4129 module.exports = Input 4130 Input.default = Input 4131 4132 if (terminalHighlight && terminalHighlight.registerInput) { 4133 terminalHighlight.registerInput(Input) 4134 } 4135 4136 4137 /***/ }), 4138 4139 /***/ 448: 4140 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 4141 4142 "use strict"; 4143 4144 4145 let { isClean, my } = __webpack_require__(1381) 4146 let MapGenerator = __webpack_require__(1670) 4147 let stringify = __webpack_require__(633) 4148 let Container = __webpack_require__(683) 4149 let Document = __webpack_require__(271) 4150 let warnOnce = __webpack_require__(3122) 4151 let Result = __webpack_require__(9055) 4152 let parse = __webpack_require__(4295) 4153 let Root = __webpack_require__(9434) 4154 4155 const TYPE_TO_CLASS_NAME = { 4156 atrule: 'AtRule', 4157 comment: 'Comment', 4158 decl: 'Declaration', 4159 document: 'Document', 4160 root: 'Root', 4161 rule: 'Rule' 4162 } 4163 4164 const PLUGIN_PROPS = { 4165 AtRule: true, 4166 AtRuleExit: true, 4167 Comment: true, 4168 CommentExit: true, 4169 Declaration: true, 4170 DeclarationExit: true, 4171 Document: true, 4172 DocumentExit: true, 4173 Once: true, 4174 OnceExit: true, 4175 postcssPlugin: true, 4176 prepare: true, 4177 Root: true, 4178 RootExit: true, 4179 Rule: true, 4180 RuleExit: true 4181 } 4182 4183 const NOT_VISITORS = { 4184 Once: true, 4185 postcssPlugin: true, 4186 prepare: true 4187 } 4188 4189 const CHILDREN = 0 4190 4191 function isPromise(obj) { 4192 return typeof obj === 'object' && typeof obj.then === 'function' 4193 } 4194 4195 function getEvents(node) { 4196 let key = false 4197 let type = TYPE_TO_CLASS_NAME[node.type] 4198 if (node.type === 'decl') { 4199 key = node.prop.toLowerCase() 4200 } else if (node.type === 'atrule') { 4201 key = node.name.toLowerCase() 4202 } 4203 4204 if (key && node.append) { 4205 return [ 4206 type, 4207 type + '-' + key, 4208 CHILDREN, 4209 type + 'Exit', 4210 type + 'Exit-' + key 4211 ] 4212 } else if (key) { 4213 return [type, type + '-' + key, type + 'Exit', type + 'Exit-' + key] 4214 } else if (node.append) { 4215 return [type, CHILDREN, type + 'Exit'] 4216 } else { 4217 return [type, type + 'Exit'] 4218 } 4219 } 4220 4221 function toStack(node) { 4222 let events 4223 if (node.type === 'document') { 4224 events = ['Document', CHILDREN, 'DocumentExit'] 4225 } else if (node.type === 'root') { 4226 events = ['Root', CHILDREN, 'RootExit'] 4227 } else { 4228 events = getEvents(node) 4229 } 4230 4231 return { 4232 eventIndex: 0, 4233 events, 4234 iterator: 0, 4235 node, 4236 visitorIndex: 0, 4237 visitors: [] 4238 } 4239 } 4240 4241 function cleanMarks(node) { 4242 node[isClean] = false 4243 if (node.nodes) node.nodes.forEach(i => cleanMarks(i)) 4244 return node 4245 } 4246 4247 let postcss = {} 4248 4249 class LazyResult { 4250 constructor(processor, css, opts) { 4251 this.stringified = false 4252 this.processed = false 4253 4254 let root 4255 if ( 4256 typeof css === 'object' && 4257 css !== null && 4258 (css.type === 'root' || css.type === 'document') 4259 ) { 4260 root = cleanMarks(css) 4261 } else if (css instanceof LazyResult || css instanceof Result) { 4262 root = cleanMarks(css.root) 4263 if (css.map) { 4264 if (typeof opts.map === 'undefined') opts.map = {} 4265 if (!opts.map.inline) opts.map.inline = false 4266 opts.map.prev = css.map 4267 } 4268 } else { 4269 let parser = parse 4270 if (opts.syntax) parser = opts.syntax.parse 4271 if (opts.parser) parser = opts.parser 4272 if (parser.parse) parser = parser.parse 4273 4274 try { 4275 root = parser(css, opts) 4276 } catch (error) { 4277 this.processed = true 4278 this.error = error 4279 } 4280 4281 if (root && !root[my]) { 4282 /* c8 ignore next 2 */ 4283 Container.rebuild(root) 4284 } 4285 } 4286 4287 this.result = new Result(processor, root, opts) 4288 this.helpers = { ...postcss, postcss, result: this.result } 4289 this.plugins = this.processor.plugins.map(plugin => { 4290 if (typeof plugin === 'object' && plugin.prepare) { 4291 return { ...plugin, ...plugin.prepare(this.result) } 4292 } else { 4293 return plugin 4294 } 4295 }) 4296 } 4297 4298 async() { 4299 if (this.error) return Promise.reject(this.error) 4300 if (this.processed) return Promise.resolve(this.result) 4301 if (!this.processing) { 4302 this.processing = this.runAsync() 4303 } 4304 return this.processing 4305 } 4306 4307 catch(onRejected) { 4308 return this.async().catch(onRejected) 4309 } 4310 4311 finally(onFinally) { 4312 return this.async().then(onFinally, onFinally) 4313 } 4314 4315 getAsyncError() { 4316 throw new Error('Use process(css).then(cb) to work with async plugins') 4317 } 4318 4319 handleError(error, node) { 4320 let plugin = this.result.lastPlugin 4321 try { 4322 if (node) node.addToError(error) 4323 this.error = error 4324 if (error.name === 'CssSyntaxError' && !error.plugin) { 4325 error.plugin = plugin.postcssPlugin 4326 error.setMessage() 4327 } else if (plugin.postcssVersion) { 4328 if (false) {} 4329 } 4330 } catch (err) { 4331 /* c8 ignore next 3 */ 4332 // eslint-disable-next-line no-console 4333 if (console && console.error) console.error(err) 4334 } 4335 return error 4336 } 4337 4338 prepareVisitors() { 4339 this.listeners = {} 4340 let add = (plugin, type, cb) => { 4341 if (!this.listeners[type]) this.listeners[type] = [] 4342 this.listeners[type].push([plugin, cb]) 4343 } 4344 for (let plugin of this.plugins) { 4345 if (typeof plugin === 'object') { 4346 for (let event in plugin) { 4347 if (!PLUGIN_PROPS[event] && /^[A-Z]/.test(event)) { 4348 throw new Error( 4349 `Unknown event $event} in $plugin.postcssPlugin}. ` + 4350 `Try to update PostCSS ($this.processor.version} now).` 4351 ) 4352 } 4353 if (!NOT_VISITORS[event]) { 4354 if (typeof plugin[event] === 'object') { 4355 for (let filter in plugin[event]) { 4356 if (filter === '*') { 4357 add(plugin, event, plugin[event][filter]) 4358 } else { 4359 add( 4360 plugin, 4361 event + '-' + filter.toLowerCase(), 4362 plugin[event][filter] 4363 ) 4364 } 4365 } 4366 } else if (typeof plugin[event] === 'function') { 4367 add(plugin, event, plugin[event]) 4368 } 4369 } 4370 } 4371 } 4372 } 4373 this.hasListener = Object.keys(this.listeners).length > 0 4374 } 4375 4376 async runAsync() { 4377 this.plugin = 0 4378 for (let i = 0; i < this.plugins.length; i++) { 4379 let plugin = this.plugins[i] 4380 let promise = this.runOnRoot(plugin) 4381 if (isPromise(promise)) { 4382 try { 4383 await promise 4384 } catch (error) { 4385 throw this.handleError(error) 4386 } 4387 } 4388 } 4389 4390 this.prepareVisitors() 4391 if (this.hasListener) { 4392 let root = this.result.root 4393 while (!root[isClean]) { 4394 root[isClean] = true 4395 let stack = [toStack(root)] 4396 while (stack.length > 0) { 4397 let promise = this.visitTick(stack) 4398 if (isPromise(promise)) { 4399 try { 4400 await promise 4401 } catch (e) { 4402 let node = stack[stack.length - 1].node 4403 throw this.handleError(e, node) 4404 } 4405 } 4406 } 4407 } 4408 4409 if (this.listeners.OnceExit) { 4410 for (let [plugin, visitor] of this.listeners.OnceExit) { 4411 this.result.lastPlugin = plugin 4412 try { 4413 if (root.type === 'document') { 4414 let roots = root.nodes.map(subRoot => 4415 visitor(subRoot, this.helpers) 4416 ) 4417 4418 await Promise.all(roots) 4419 } else { 4420 await visitor(root, this.helpers) 4421 } 4422 } catch (e) { 4423 throw this.handleError(e) 4424 } 4425 } 4426 } 4427 } 4428 4429 this.processed = true 4430 return this.stringify() 4431 } 4432 4433 runOnRoot(plugin) { 4434 this.result.lastPlugin = plugin 4435 try { 4436 if (typeof plugin === 'object' && plugin.Once) { 4437 if (this.result.root.type === 'document') { 4438 let roots = this.result.root.nodes.map(root => 4439 plugin.Once(root, this.helpers) 4440 ) 4441 4442 if (isPromise(roots[0])) { 4443 return Promise.all(roots) 4444 } 4445 4446 return roots 4447 } 4448 4449 return plugin.Once(this.result.root, this.helpers) 4450 } else if (typeof plugin === 'function') { 4451 return plugin(this.result.root, this.result) 4452 } 4453 } catch (error) { 4454 throw this.handleError(error) 4455 } 4456 } 4457 4458 stringify() { 4459 if (this.error) throw this.error 4460 if (this.stringified) return this.result 4461 this.stringified = true 4462 4463 this.sync() 4464 4465 let opts = this.result.opts 4466 let str = stringify 4467 if (opts.syntax) str = opts.syntax.stringify 4468 if (opts.stringifier) str = opts.stringifier 4469 if (str.stringify) str = str.stringify 4470 4471 let map = new MapGenerator(str, this.result.root, this.result.opts) 4472 let data = map.generate() 4473 this.result.css = data[0] 4474 this.result.map = data[1] 4475 4476 return this.result 4477 } 4478 4479 sync() { 4480 if (this.error) throw this.error 4481 if (this.processed) return this.result 4482 this.processed = true 4483 4484 if (this.processing) { 4485 throw this.getAsyncError() 4486 } 4487 4488 for (let plugin of this.plugins) { 4489 let promise = this.runOnRoot(plugin) 4490 if (isPromise(promise)) { 4491 throw this.getAsyncError() 4492 } 4493 } 4494 4495 this.prepareVisitors() 4496 if (this.hasListener) { 4497 let root = this.result.root 4498 while (!root[isClean]) { 4499 root[isClean] = true 4500 this.walkSync(root) 4501 } 4502 if (this.listeners.OnceExit) { 4503 if (root.type === 'document') { 4504 for (let subRoot of root.nodes) { 4505 this.visitSync(this.listeners.OnceExit, subRoot) 4506 } 4507 } else { 4508 this.visitSync(this.listeners.OnceExit, root) 4509 } 4510 } 4511 } 4512 4513 return this.result 4514 } 4515 4516 then(onFulfilled, onRejected) { 4517 if (false) {} 4518 return this.async().then(onFulfilled, onRejected) 4519 } 4520 4521 toString() { 4522 return this.css 4523 } 4524 4525 visitSync(visitors, node) { 4526 for (let [plugin, visitor] of visitors) { 4527 this.result.lastPlugin = plugin 4528 let promise 4529 try { 4530 promise = visitor(node, this.helpers) 4531 } catch (e) { 4532 throw this.handleError(e, node.proxyOf) 4533 } 4534 if (node.type !== 'root' && node.type !== 'document' && !node.parent) { 4535 return true 4536 } 4537 if (isPromise(promise)) { 4538 throw this.getAsyncError() 4539 } 4540 } 4541 } 4542 4543 visitTick(stack) { 4544 let visit = stack[stack.length - 1] 4545 let { node, visitors } = visit 4546 4547 if (node.type !== 'root' && node.type !== 'document' && !node.parent) { 4548 stack.pop() 4549 return 4550 } 4551 4552 if (visitors.length > 0 && visit.visitorIndex < visitors.length) { 4553 let [plugin, visitor] = visitors[visit.visitorIndex] 4554 visit.visitorIndex += 1 4555 if (visit.visitorIndex === visitors.length) { 4556 visit.visitors = [] 4557 visit.visitorIndex = 0 4558 } 4559 this.result.lastPlugin = plugin 4560 try { 4561 return visitor(node.toProxy(), this.helpers) 4562 } catch (e) { 4563 throw this.handleError(e, node) 4564 } 4565 } 4566 4567 if (visit.iterator !== 0) { 4568 let iterator = visit.iterator 4569 let child 4570 while ((child = node.nodes[node.indexes[iterator]])) { 4571 node.indexes[iterator] += 1 4572 if (!child[isClean]) { 4573 child[isClean] = true 4574 stack.push(toStack(child)) 4575 return 4576 } 4577 } 4578 visit.iterator = 0 4579 delete node.indexes[iterator] 4580 } 4581 4582 let events = visit.events 4583 while (visit.eventIndex < events.length) { 4584 let event = events[visit.eventIndex] 4585 visit.eventIndex += 1 4586 if (event === CHILDREN) { 4587 if (node.nodes && node.nodes.length) { 4588 node[isClean] = true 4589 visit.iterator = node.getIterator() 4590 } 4591 return 4592 } else if (this.listeners[event]) { 4593 visit.visitors = this.listeners[event] 4594 return 4595 } 4596 } 4597 stack.pop() 4598 } 4599 4600 walkSync(node) { 4601 node[isClean] = true 4602 let events = getEvents(node) 4603 for (let event of events) { 4604 if (event === CHILDREN) { 4605 if (node.nodes) { 4606 node.each(child => { 4607 if (!child[isClean]) this.walkSync(child) 4608 }) 4609 } 4610 } else { 4611 let visitors = this.listeners[event] 4612 if (visitors) { 4613 if (this.visitSync(visitors, node.toProxy())) return 4614 } 4615 } 4616 } 4617 } 4618 4619 warnings() { 4620 return this.sync().warnings() 4621 } 4622 4623 get content() { 4624 return this.stringify().content 4625 } 4626 4627 get css() { 4628 return this.stringify().css 4629 } 4630 4631 get map() { 4632 return this.stringify().map 4633 } 4634 4635 get messages() { 4636 return this.sync().messages 4637 } 4638 4639 get opts() { 4640 return this.result.opts 4641 } 4642 4643 get processor() { 4644 return this.result.processor 4645 } 4646 4647 get root() { 4648 return this.sync().root 4649 } 4650 4651 get [Symbol.toStringTag]() { 4652 return 'LazyResult' 4653 } 4654 } 4655 4656 LazyResult.registerPostcss = dependant => { 4657 postcss = dependant 4658 } 4659 4660 module.exports = LazyResult 4661 LazyResult.default = LazyResult 4662 4663 Root.registerLazyResult(LazyResult) 4664 Document.registerLazyResult(LazyResult) 4665 4666 4667 /***/ }), 4668 4669 /***/ 7374: 4670 /***/ ((module) => { 4671 4672 "use strict"; 4673 4674 4675 let list = { 4676 comma(string) { 4677 return list.split(string, [','], true) 4678 }, 4679 4680 space(string) { 4681 let spaces = [' ', '\n', '\t'] 4682 return list.split(string, spaces) 4683 }, 4684 4685 split(string, separators, last) { 4686 let array = [] 4687 let current = '' 4688 let split = false 4689 4690 let func = 0 4691 let inQuote = false 4692 let prevQuote = '' 4693 let escape = false 4694 4695 for (let letter of string) { 4696 if (escape) { 4697 escape = false 4698 } else if (letter === '\\') { 4699 escape = true 4700 } else if (inQuote) { 4701 if (letter === prevQuote) { 4702 inQuote = false 4703 } 4704 } else if (letter === '"' || letter === "'") { 4705 inQuote = true 4706 prevQuote = letter 4707 } else if (letter === '(') { 4708 func += 1 4709 } else if (letter === ')') { 4710 if (func > 0) func -= 1 4711 } else if (func === 0) { 4712 if (separators.includes(letter)) split = true 4713 } 4714 4715 if (split) { 4716 if (current !== '') array.push(current.trim()) 4717 current = '' 4718 split = false 4719 } else { 4720 current += letter 4721 } 4722 } 4723 4724 if (last || current !== '') array.push(current.trim()) 4725 return array 4726 } 4727 } 4728 4729 module.exports = list 4730 list.default = list 4731 4732 4733 /***/ }), 4734 4735 /***/ 1670: 4736 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 4737 4738 "use strict"; 4739 4740 4741 let { SourceMapConsumer, SourceMapGenerator } = __webpack_require__(1866) 4742 let { dirname, relative, resolve, sep } = __webpack_require__(197) 4743 let { pathToFileURL } = __webpack_require__(2739) 4744 4745 let Input = __webpack_require__(5380) 4746 4747 let sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator) 4748 let pathAvailable = Boolean(dirname && resolve && relative && sep) 4749 4750 class MapGenerator { 4751 constructor(stringify, root, opts, cssString) { 4752 this.stringify = stringify 4753 this.mapOpts = opts.map || {} 4754 this.root = root 4755 this.opts = opts 4756 this.css = cssString 4757 this.originalCSS = cssString 4758 this.usesFileUrls = !this.mapOpts.from && this.mapOpts.absolute 4759 4760 this.memoizedFileURLs = new Map() 4761 this.memoizedPaths = new Map() 4762 this.memoizedURLs = new Map() 4763 } 4764 4765 addAnnotation() { 4766 let content 4767 4768 if (this.isInline()) { 4769 content = 4770 'data:application/json;base64,' + this.toBase64(this.map.toString()) 4771 } else if (typeof this.mapOpts.annotation === 'string') { 4772 content = this.mapOpts.annotation 4773 } else if (typeof this.mapOpts.annotation === 'function') { 4774 content = this.mapOpts.annotation(this.opts.to, this.root) 4775 } else { 4776 content = this.outputFile() + '.map' 4777 } 4778 let eol = '\n' 4779 if (this.css.includes('\r\n')) eol = '\r\n' 4780 4781 this.css += eol + '/*# sourceMappingURL=' + content + ' */' 4782 } 4783 4784 applyPrevMaps() { 4785 for (let prev of this.previous()) { 4786 let from = this.toUrl(this.path(prev.file)) 4787 let root = prev.root || dirname(prev.file) 4788 let map 4789 4790 if (this.mapOpts.sourcesContent === false) { 4791 map = new SourceMapConsumer(prev.text) 4792 if (map.sourcesContent) { 4793 map.sourcesContent = null 4794 } 4795 } else { 4796 map = prev.consumer() 4797 } 4798 4799 this.map.applySourceMap(map, from, this.toUrl(this.path(root))) 4800 } 4801 } 4802 4803 clearAnnotation() { 4804 if (this.mapOpts.annotation === false) return 4805 4806 if (this.root) { 4807 let node 4808 for (let i = this.root.nodes.length - 1; i >= 0; i--) { 4809 node = this.root.nodes[i] 4810 if (node.type !== 'comment') continue 4811 if (node.text.indexOf('# sourceMappingURL=') === 0) { 4812 this.root.removeChild(i) 4813 } 4814 } 4815 } else if (this.css) { 4816 this.css = this.css.replace(/\n*?\/\*#[\S\s]*?\*\/$/gm, '') 4817 } 4818 } 4819 4820 generate() { 4821 this.clearAnnotation() 4822 if (pathAvailable && sourceMapAvailable && this.isMap()) { 4823 return this.generateMap() 4824 } else { 4825 let result = '' 4826 this.stringify(this.root, i => { 4827 result += i 4828 }) 4829 return [result] 4830 } 4831 } 4832 4833 generateMap() { 4834 if (this.root) { 4835 this.generateString() 4836 } else if (this.previous().length === 1) { 4837 let prev = this.previous()[0].consumer() 4838 prev.file = this.outputFile() 4839 this.map = SourceMapGenerator.fromSourceMap(prev) 4840 } else { 4841 this.map = new SourceMapGenerator({ file: this.outputFile() }) 4842 this.map.addMapping({ 4843 generated: { column: 0, line: 1 }, 4844 original: { column: 0, line: 1 }, 4845 source: this.opts.from 4846 ? this.toUrl(this.path(this.opts.from)) 4847 : '<no source>' 4848 }) 4849 } 4850 4851 if (this.isSourcesContent()) this.setSourcesContent() 4852 if (this.root && this.previous().length > 0) this.applyPrevMaps() 4853 if (this.isAnnotation()) this.addAnnotation() 4854 4855 if (this.isInline()) { 4856 return [this.css] 4857 } else { 4858 return [this.css, this.map] 4859 } 4860 } 4861 4862 generateString() { 4863 this.css = '' 4864 this.map = new SourceMapGenerator({ file: this.outputFile() }) 4865 4866 let line = 1 4867 let column = 1 4868 4869 let noSource = '<no source>' 4870 let mapping = { 4871 generated: { column: 0, line: 0 }, 4872 original: { column: 0, line: 0 }, 4873 source: '' 4874 } 4875 4876 let lines, last 4877 this.stringify(this.root, (str, node, type) => { 4878 this.css += str 4879 4880 if (node && type !== 'end') { 4881 mapping.generated.line = line 4882 mapping.generated.column = column - 1 4883 if (node.source && node.source.start) { 4884 mapping.source = this.sourcePath(node) 4885 mapping.original.line = node.source.start.line 4886 mapping.original.column = node.source.start.column - 1 4887 this.map.addMapping(mapping) 4888 } else { 4889 mapping.source = noSource 4890 mapping.original.line = 1 4891 mapping.original.column = 0 4892 this.map.addMapping(mapping) 4893 } 4894 } 4895 4896 lines = str.match(/\n/g) 4897 if (lines) { 4898 line += lines.length 4899 last = str.lastIndexOf('\n') 4900 column = str.length - last 4901 } else { 4902 column += str.length 4903 } 4904 4905 if (node && type !== 'start') { 4906 let p = node.parent || { raws: {} } 4907 let childless = 4908 node.type === 'decl' || (node.type === 'atrule' && !node.nodes) 4909 if (!childless || node !== p.last || p.raws.semicolon) { 4910 if (node.source && node.source.end) { 4911 mapping.source = this.sourcePath(node) 4912 mapping.original.line = node.source.end.line 4913 mapping.original.column = node.source.end.column - 1 4914 mapping.generated.line = line 4915 mapping.generated.column = column - 2 4916 this.map.addMapping(mapping) 4917 } else { 4918 mapping.source = noSource 4919 mapping.original.line = 1 4920 mapping.original.column = 0 4921 mapping.generated.line = line 4922 mapping.generated.column = column - 1 4923 this.map.addMapping(mapping) 4924 } 4925 } 4926 } 4927 }) 4928 } 4929 4930 isAnnotation() { 4931 if (this.isInline()) { 4932 return true 4933 } 4934 if (typeof this.mapOpts.annotation !== 'undefined') { 4935 return this.mapOpts.annotation 4936 } 4937 if (this.previous().length) { 4938 return this.previous().some(i => i.annotation) 4939 } 4940 return true 4941 } 4942 4943 isInline() { 4944 if (typeof this.mapOpts.inline !== 'undefined') { 4945 return this.mapOpts.inline 4946 } 4947 4948 let annotation = this.mapOpts.annotation 4949 if (typeof annotation !== 'undefined' && annotation !== true) { 4950 return false 4951 } 4952 4953 if (this.previous().length) { 4954 return this.previous().some(i => i.inline) 4955 } 4956 return true 4957 } 4958 4959 isMap() { 4960 if (typeof this.opts.map !== 'undefined') { 4961 return !!this.opts.map 4962 } 4963 return this.previous().length > 0 4964 } 4965 4966 isSourcesContent() { 4967 if (typeof this.mapOpts.sourcesContent !== 'undefined') { 4968 return this.mapOpts.sourcesContent 4969 } 4970 if (this.previous().length) { 4971 return this.previous().some(i => i.withContent()) 4972 } 4973 return true 4974 } 4975 4976 outputFile() { 4977 if (this.opts.to) { 4978 return this.path(this.opts.to) 4979 } else if (this.opts.from) { 4980 return this.path(this.opts.from) 4981 } else { 4982 return 'to.css' 4983 } 4984 } 4985 4986 path(file) { 4987 if (this.mapOpts.absolute) return file 4988 if (file.charCodeAt(0) === 60 /* `<` */) return file 4989 if (/^\w+:\/\//.test(file)) return file 4990 let cached = this.memoizedPaths.get(file) 4991 if (cached) return cached 4992 4993 let from = this.opts.to ? dirname(this.opts.to) : '.' 4994 4995 if (typeof this.mapOpts.annotation === 'string') { 4996 from = dirname(resolve(from, this.mapOpts.annotation)) 4997 } 4998 4999 let path = relative(from, file) 5000 this.memoizedPaths.set(file, path) 5001 5002 return path 5003 } 5004 5005 previous() { 5006 if (!this.previousMaps) { 5007 this.previousMaps = [] 5008 if (this.root) { 5009 this.root.walk(node => { 5010 if (node.source && node.source.input.map) { 5011 let map = node.source.input.map 5012 if (!this.previousMaps.includes(map)) { 5013 this.previousMaps.push(map) 5014 } 5015 } 5016 }) 5017 } else { 5018 let input = new Input(this.originalCSS, this.opts) 5019 if (input.map) this.previousMaps.push(input.map) 5020 } 5021 } 5022 5023 return this.previousMaps 5024 } 5025 5026 setSourcesContent() { 5027 let already = {} 5028 if (this.root) { 5029 this.root.walk(node => { 5030 if (node.source) { 5031 let from = node.source.input.from 5032 if (from && !already[from]) { 5033 already[from] = true 5034 let fromUrl = this.usesFileUrls 5035 ? this.toFileUrl(from) 5036 : this.toUrl(this.path(from)) 5037 this.map.setSourceContent(fromUrl, node.source.input.css) 5038 } 5039 } 5040 }) 5041 } else if (this.css) { 5042 let from = this.opts.from 5043 ? this.toUrl(this.path(this.opts.from)) 5044 : '<no source>' 5045 this.map.setSourceContent(from, this.css) 5046 } 5047 } 5048 5049 sourcePath(node) { 5050 if (this.mapOpts.from) { 5051 return this.toUrl(this.mapOpts.from) 5052 } else if (this.usesFileUrls) { 5053 return this.toFileUrl(node.source.input.from) 5054 } else { 5055 return this.toUrl(this.path(node.source.input.from)) 5056 } 5057 } 5058 5059 toBase64(str) { 5060 if (Buffer) { 5061 return Buffer.from(str).toString('base64') 5062 } else { 5063 return window.btoa(unescape(encodeURIComponent(str))) 5064 } 5065 } 5066 5067 toFileUrl(path) { 5068 let cached = this.memoizedFileURLs.get(path) 5069 if (cached) return cached 5070 5071 if (pathToFileURL) { 5072 let fileURL = pathToFileURL(path).toString() 5073 this.memoizedFileURLs.set(path, fileURL) 5074 5075 return fileURL 5076 } else { 5077 throw new Error( 5078 '`map.absolute` option is not available in this PostCSS build' 5079 ) 5080 } 5081 } 5082 5083 toUrl(path) { 5084 let cached = this.memoizedURLs.get(path) 5085 if (cached) return cached 5086 5087 if (sep === '\\') { 5088 path = path.replace(/\\/g, '/') 5089 } 5090 5091 let url = encodeURI(path).replace(/[#?]/g, encodeURIComponent) 5092 this.memoizedURLs.set(path, url) 5093 5094 return url 5095 } 5096 } 5097 5098 module.exports = MapGenerator 5099 5100 5101 /***/ }), 5102 5103 /***/ 7661: 5104 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 5105 5106 "use strict"; 5107 5108 5109 let MapGenerator = __webpack_require__(1670) 5110 let stringify = __webpack_require__(633) 5111 let warnOnce = __webpack_require__(3122) 5112 let parse = __webpack_require__(4295) 5113 const Result = __webpack_require__(9055) 5114 5115 class NoWorkResult { 5116 constructor(processor, css, opts) { 5117 css = css.toString() 5118 this.stringified = false 5119 5120 this._processor = processor 5121 this._css = css 5122 this._opts = opts 5123 this._map = undefined 5124 let root 5125 5126 let str = stringify 5127 this.result = new Result(this._processor, root, this._opts) 5128 this.result.css = css 5129 5130 let self = this 5131 Object.defineProperty(this.result, 'root', { 5132 get() { 5133 return self.root 5134 } 5135 }) 5136 5137 let map = new MapGenerator(str, root, this._opts, css) 5138 if (map.isMap()) { 5139 let [generatedCSS, generatedMap] = map.generate() 5140 if (generatedCSS) { 5141 this.result.css = generatedCSS 5142 } 5143 if (generatedMap) { 5144 this.result.map = generatedMap 5145 } 5146 } else { 5147 map.clearAnnotation() 5148 this.result.css = map.css 5149 } 5150 } 5151 5152 async() { 5153 if (this.error) return Promise.reject(this.error) 5154 return Promise.resolve(this.result) 5155 } 5156 5157 catch(onRejected) { 5158 return this.async().catch(onRejected) 5159 } 5160 5161 finally(onFinally) { 5162 return this.async().then(onFinally, onFinally) 5163 } 5164 5165 sync() { 5166 if (this.error) throw this.error 5167 return this.result 5168 } 5169 5170 then(onFulfilled, onRejected) { 5171 if (false) {} 5172 5173 return this.async().then(onFulfilled, onRejected) 5174 } 5175 5176 toString() { 5177 return this._css 5178 } 5179 5180 warnings() { 5181 return [] 5182 } 5183 5184 get content() { 5185 return this.result.css 5186 } 5187 5188 get css() { 5189 return this.result.css 5190 } 5191 5192 get map() { 5193 return this.result.map 5194 } 5195 5196 get messages() { 5197 return [] 5198 } 5199 5200 get opts() { 5201 return this.result.opts 5202 } 5203 5204 get processor() { 5205 return this.result.processor 5206 } 5207 5208 get root() { 5209 if (this._root) { 5210 return this._root 5211 } 5212 5213 let root 5214 let parser = parse 5215 5216 try { 5217 root = parser(this._css, this._opts) 5218 } catch (error) { 5219 this.error = error 5220 } 5221 5222 if (this.error) { 5223 throw this.error 5224 } else { 5225 this._root = root 5226 return root 5227 } 5228 } 5229 5230 get [Symbol.toStringTag]() { 5231 return 'NoWorkResult' 5232 } 5233 } 5234 5235 module.exports = NoWorkResult 5236 NoWorkResult.default = NoWorkResult 5237 5238 5239 /***/ }), 5240 5241 /***/ 7490: 5242 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 5243 5244 "use strict"; 5245 5246 5247 let { isClean, my } = __webpack_require__(1381) 5248 let CssSyntaxError = __webpack_require__(356) 5249 let Stringifier = __webpack_require__(346) 5250 let stringify = __webpack_require__(633) 5251 5252 function cloneNode(obj, parent) { 5253 let cloned = new obj.constructor() 5254 5255 for (let i in obj) { 5256 if (!Object.prototype.hasOwnProperty.call(obj, i)) { 5257 /* c8 ignore next 2 */ 5258 continue 5259 } 5260 if (i === 'proxyCache') continue 5261 let value = obj[i] 5262 let type = typeof value 5263 5264 if (i === 'parent' && type === 'object') { 5265 if (parent) cloned[i] = parent 5266 } else if (i === 'source') { 5267 cloned[i] = value 5268 } else if (Array.isArray(value)) { 5269 cloned[i] = value.map(j => cloneNode(j, cloned)) 5270 } else { 5271 if (type === 'object' && value !== null) value = cloneNode(value) 5272 cloned[i] = value 5273 } 5274 } 5275 5276 return cloned 5277 } 5278 5279 class Node { 5280 constructor(defaults = {}) { 5281 this.raws = {} 5282 this[isClean] = false 5283 this[my] = true 5284 5285 for (let name in defaults) { 5286 if (name === 'nodes') { 5287 this.nodes = [] 5288 for (let node of defaults[name]) { 5289 if (typeof node.clone === 'function') { 5290 this.append(node.clone()) 5291 } else { 5292 this.append(node) 5293 } 5294 } 5295 } else { 5296 this[name] = defaults[name] 5297 } 5298 } 5299 } 5300 5301 addToError(error) { 5302 error.postcssNode = this 5303 if (error.stack && this.source && /\n\s{4}at /.test(error.stack)) { 5304 let s = this.source 5305 error.stack = error.stack.replace( 5306 /\n\s{4}at /, 5307 `$&$s.input.from}:$s.start.line}:$s.start.column}$&` 5308 ) 5309 } 5310 return error 5311 } 5312 5313 after(add) { 5314 this.parent.insertAfter(this, add) 5315 return this 5316 } 5317 5318 assign(overrides = {}) { 5319 for (let name in overrides) { 5320 this[name] = overrides[name] 5321 } 5322 return this 5323 } 5324 5325 before(add) { 5326 this.parent.insertBefore(this, add) 5327 return this 5328 } 5329 5330 cleanRaws(keepBetween) { 5331 delete this.raws.before 5332 delete this.raws.after 5333 if (!keepBetween) delete this.raws.between 5334 } 5335 5336 clone(overrides = {}) { 5337 let cloned = cloneNode(this) 5338 for (let name in overrides) { 5339 cloned[name] = overrides[name] 5340 } 5341 return cloned 5342 } 5343 5344 cloneAfter(overrides = {}) { 5345 let cloned = this.clone(overrides) 5346 this.parent.insertAfter(this, cloned) 5347 return cloned 5348 } 5349 5350 cloneBefore(overrides = {}) { 5351 let cloned = this.clone(overrides) 5352 this.parent.insertBefore(this, cloned) 5353 return cloned 5354 } 5355 5356 error(message, opts = {}) { 5357 if (this.source) { 5358 let { end, start } = this.rangeBy(opts) 5359 return this.source.input.error( 5360 message, 5361 { column: start.column, line: start.line }, 5362 { column: end.column, line: end.line }, 5363 opts 5364 ) 5365 } 5366 return new CssSyntaxError(message) 5367 } 5368 5369 getProxyProcessor() { 5370 return { 5371 get(node, prop) { 5372 if (prop === 'proxyOf') { 5373 return node 5374 } else if (prop === 'root') { 5375 return () => node.root().toProxy() 5376 } else { 5377 return node[prop] 5378 } 5379 }, 5380 5381 set(node, prop, value) { 5382 if (node[prop] === value) return true 5383 node[prop] = value 5384 if ( 5385 prop === 'prop' || 5386 prop === 'value' || 5387 prop === 'name' || 5388 prop === 'params' || 5389 prop === 'important' || 5390 /* c8 ignore next */ 5391 prop === 'text' 5392 ) { 5393 node.markDirty() 5394 } 5395 return true 5396 } 5397 } 5398 } 5399 5400 markDirty() { 5401 if (this[isClean]) { 5402 this[isClean] = false 5403 let next = this 5404 while ((next = next.parent)) { 5405 next[isClean] = false 5406 } 5407 } 5408 } 5409 5410 next() { 5411 if (!this.parent) return undefined 5412 let index = this.parent.index(this) 5413 return this.parent.nodes[index + 1] 5414 } 5415 5416 positionBy(opts, stringRepresentation) { 5417 let pos = this.source.start 5418 if (opts.index) { 5419 pos = this.positionInside(opts.index, stringRepresentation) 5420 } else if (opts.word) { 5421 stringRepresentation = this.toString() 5422 let index = stringRepresentation.indexOf(opts.word) 5423 if (index !== -1) pos = this.positionInside(index, stringRepresentation) 5424 } 5425 return pos 5426 } 5427 5428 positionInside(index, stringRepresentation) { 5429 let string = stringRepresentation || this.toString() 5430 let column = this.source.start.column 5431 let line = this.source.start.line 5432 5433 for (let i = 0; i < index; i++) { 5434 if (string[i] === '\n') { 5435 column = 1 5436 line += 1 5437 } else { 5438 column += 1 5439 } 5440 } 5441 5442 return { column, line } 5443 } 5444 5445 prev() { 5446 if (!this.parent) return undefined 5447 let index = this.parent.index(this) 5448 return this.parent.nodes[index - 1] 5449 } 5450 5451 rangeBy(opts) { 5452 let start = { 5453 column: this.source.start.column, 5454 line: this.source.start.line 5455 } 5456 let end = this.source.end 5457 ? { 5458 column: this.source.end.column + 1, 5459 line: this.source.end.line 5460 } 5461 : { 5462 column: start.column + 1, 5463 line: start.line 5464 } 5465 5466 if (opts.word) { 5467 let stringRepresentation = this.toString() 5468 let index = stringRepresentation.indexOf(opts.word) 5469 if (index !== -1) { 5470 start = this.positionInside(index, stringRepresentation) 5471 end = this.positionInside(index + opts.word.length, stringRepresentation) 5472 } 5473 } else { 5474 if (opts.start) { 5475 start = { 5476 column: opts.start.column, 5477 line: opts.start.line 5478 } 5479 } else if (opts.index) { 5480 start = this.positionInside(opts.index) 5481 } 5482 5483 if (opts.end) { 5484 end = { 5485 column: opts.end.column, 5486 line: opts.end.line 5487 } 5488 } else if (opts.endIndex) { 5489 end = this.positionInside(opts.endIndex) 5490 } else if (opts.index) { 5491 end = this.positionInside(opts.index + 1) 5492 } 5493 } 5494 5495 if ( 5496 end.line < start.line || 5497 (end.line === start.line && end.column <= start.column) 5498 ) { 5499 end = { column: start.column + 1, line: start.line } 5500 } 5501 5502 return { end, start } 5503 } 5504 5505 raw(prop, defaultType) { 5506 let str = new Stringifier() 5507 return str.raw(this, prop, defaultType) 5508 } 5509 5510 remove() { 5511 if (this.parent) { 5512 this.parent.removeChild(this) 5513 } 5514 this.parent = undefined 5515 return this 5516 } 5517 5518 replaceWith(...nodes) { 5519 if (this.parent) { 5520 let bookmark = this 5521 let foundSelf = false 5522 for (let node of nodes) { 5523 if (node === this) { 5524 foundSelf = true 5525 } else if (foundSelf) { 5526 this.parent.insertAfter(bookmark, node) 5527 bookmark = node 5528 } else { 5529 this.parent.insertBefore(bookmark, node) 5530 } 5531 } 5532 5533 if (!foundSelf) { 5534 this.remove() 5535 } 5536 } 5537 5538 return this 5539 } 5540 5541 root() { 5542 let result = this 5543 while (result.parent && result.parent.type !== 'document') { 5544 result = result.parent 5545 } 5546 return result 5547 } 5548 5549 toJSON(_, inputs) { 5550 let fixed = {} 5551 let emitInputs = inputs == null 5552 inputs = inputs || new Map() 5553 let inputsNextIndex = 0 5554 5555 for (let name in this) { 5556 if (!Object.prototype.hasOwnProperty.call(this, name)) { 5557 /* c8 ignore next 2 */ 5558 continue 5559 } 5560 if (name === 'parent' || name === 'proxyCache') continue 5561 let value = this[name] 5562 5563 if (Array.isArray(value)) { 5564 fixed[name] = value.map(i => { 5565 if (typeof i === 'object' && i.toJSON) { 5566 return i.toJSON(null, inputs) 5567 } else { 5568 return i 5569 } 5570 }) 5571 } else if (typeof value === 'object' && value.toJSON) { 5572 fixed[name] = value.toJSON(null, inputs) 5573 } else if (name === 'source') { 5574 let inputId = inputs.get(value.input) 5575 if (inputId == null) { 5576 inputId = inputsNextIndex 5577 inputs.set(value.input, inputsNextIndex) 5578 inputsNextIndex++ 5579 } 5580 fixed[name] = { 5581 end: value.end, 5582 inputId, 5583 start: value.start 5584 } 5585 } else { 5586 fixed[name] = value 5587 } 5588 } 5589 5590 if (emitInputs) { 5591 fixed.inputs = [...inputs.keys()].map(input => input.toJSON()) 5592 } 5593 5594 return fixed 5595 } 5596 5597 toProxy() { 5598 if (!this.proxyCache) { 5599 this.proxyCache = new Proxy(this, this.getProxyProcessor()) 5600 } 5601 return this.proxyCache 5602 } 5603 5604 toString(stringifier = stringify) { 5605 if (stringifier.stringify) stringifier = stringifier.stringify 5606 let result = '' 5607 stringifier(this, i => { 5608 result += i 5609 }) 5610 return result 5611 } 5612 5613 warn(result, text, opts) { 5614 let data = { node: this } 5615 for (let i in opts) data[i] = opts[i] 5616 return result.warn(text, data) 5617 } 5618 5619 get proxyOf() { 5620 return this 5621 } 5622 } 5623 5624 module.exports = Node 5625 Node.default = Node 5626 5627 5628 /***/ }), 5629 5630 /***/ 4295: 5631 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 5632 5633 "use strict"; 5634 5635 5636 let Container = __webpack_require__(683) 5637 let Parser = __webpack_require__(3937) 5638 let Input = __webpack_require__(5380) 5639 5640 function parse(css, opts) { 5641 let input = new Input(css, opts) 5642 let parser = new Parser(input) 5643 try { 5644 parser.parse() 5645 } catch (e) { 5646 if (false) {} 5647 throw e 5648 } 5649 5650 return parser.root 5651 } 5652 5653 module.exports = parse 5654 parse.default = parse 5655 5656 Container.registerParse(parse) 5657 5658 5659 /***/ }), 5660 5661 /***/ 3937: 5662 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 5663 5664 "use strict"; 5665 5666 5667 let Declaration = __webpack_require__(1516) 5668 let tokenizer = __webpack_require__(2327) 5669 let Comment = __webpack_require__(6589) 5670 let AtRule = __webpack_require__(1326) 5671 let Root = __webpack_require__(9434) 5672 let Rule = __webpack_require__(4092) 5673 5674 const SAFE_COMMENT_NEIGHBOR = { 5675 empty: true, 5676 space: true 5677 } 5678 5679 function findLastWithPosition(tokens) { 5680 for (let i = tokens.length - 1; i >= 0; i--) { 5681 let token = tokens[i] 5682 let pos = token[3] || token[2] 5683 if (pos) return pos 5684 } 5685 } 5686 5687 class Parser { 5688 constructor(input) { 5689 this.input = input 5690 5691 this.root = new Root() 5692 this.current = this.root 5693 this.spaces = '' 5694 this.semicolon = false 5695 5696 this.createTokenizer() 5697 this.root.source = { input, start: { column: 1, line: 1, offset: 0 } } 5698 } 5699 5700 atrule(token) { 5701 let node = new AtRule() 5702 node.name = token[1].slice(1) 5703 if (node.name === '') { 5704 this.unnamedAtrule(node, token) 5705 } 5706 this.init(node, token[2]) 5707 5708 let type 5709 let prev 5710 let shift 5711 let last = false 5712 let open = false 5713 let params = [] 5714 let brackets = [] 5715 5716 while (!this.tokenizer.endOfFile()) { 5717 token = this.tokenizer.nextToken() 5718 type = token[0] 5719 5720 if (type === '(' || type === '[') { 5721 brackets.push(type === '(' ? ')' : ']') 5722 } else if (type === '{' && brackets.length > 0) { 5723 brackets.push('}') 5724 } else if (type === brackets[brackets.length - 1]) { 5725 brackets.pop() 5726 } 5727 5728 if (brackets.length === 0) { 5729 if (type === ';') { 5730 node.source.end = this.getPosition(token[2]) 5731 node.source.end.offset++ 5732 this.semicolon = true 5733 break 5734 } else if (type === '{') { 5735 open = true 5736 break 5737 } else if (type === '}') { 5738 if (params.length > 0) { 5739 shift = params.length - 1 5740 prev = params[shift] 5741 while (prev && prev[0] === 'space') { 5742 prev = params[--shift] 5743 } 5744 if (prev) { 5745 node.source.end = this.getPosition(prev[3] || prev[2]) 5746 node.source.end.offset++ 5747 } 5748 } 5749 this.end(token) 5750 break 5751 } else { 5752 params.push(token) 5753 } 5754 } else { 5755 params.push(token) 5756 } 5757 5758 if (this.tokenizer.endOfFile()) { 5759 last = true 5760 break 5761 } 5762 } 5763 5764 node.raws.between = this.spacesAndCommentsFromEnd(params) 5765 if (params.length) { 5766 node.raws.afterName = this.spacesAndCommentsFromStart(params) 5767 this.raw(node, 'params', params) 5768 if (last) { 5769 token = params[params.length - 1] 5770 node.source.end = this.getPosition(token[3] || token[2]) 5771 node.source.end.offset++ 5772 this.spaces = node.raws.between 5773 node.raws.between = '' 5774 } 5775 } else { 5776 node.raws.afterName = '' 5777 node.params = '' 5778 } 5779 5780 if (open) { 5781 node.nodes = [] 5782 this.current = node 5783 } 5784 } 5785 5786 checkMissedSemicolon(tokens) { 5787 let colon = this.colon(tokens) 5788 if (colon === false) return 5789 5790 let founded = 0 5791 let token 5792 for (let j = colon - 1; j >= 0; j--) { 5793 token = tokens[j] 5794 if (token[0] !== 'space') { 5795 founded += 1 5796 if (founded === 2) break 5797 } 5798 } 5799 // If the token is a word, e.g. `!important`, `red` or any other valid property's value. 5800 // Then we need to return the colon after that word token. [3] is the "end" colon of that word. 5801 // And because we need it after that one we do +1 to get the next one. 5802 throw this.input.error( 5803 'Missed semicolon', 5804 token[0] === 'word' ? token[3] + 1 : token[2] 5805 ) 5806 } 5807 5808 colon(tokens) { 5809 let brackets = 0 5810 let token, type, prev 5811 for (let [i, element] of tokens.entries()) { 5812 token = element 5813 type = token[0] 5814 5815 if (type === '(') { 5816 brackets += 1 5817 } 5818 if (type === ')') { 5819 brackets -= 1 5820 } 5821 if (brackets === 0 && type === ':') { 5822 if (!prev) { 5823 this.doubleColon(token) 5824 } else if (prev[0] === 'word' && prev[1] === 'progid') { 5825 continue 5826 } else { 5827 return i 5828 } 5829 } 5830 5831 prev = token 5832 } 5833 return false 5834 } 5835 5836 comment(token) { 5837 let node = new Comment() 5838 this.init(node, token[2]) 5839 node.source.end = this.getPosition(token[3] || token[2]) 5840 node.source.end.offset++ 5841 5842 let text = token[1].slice(2, -2) 5843 if (/^\s*$/.test(text)) { 5844 node.text = '' 5845 node.raws.left = text 5846 node.raws.right = '' 5847 } else { 5848 let match = text.match(/^(\s*)([^]*\S)(\s*)$/) 5849 node.text = match[2] 5850 node.raws.left = match[1] 5851 node.raws.right = match[3] 5852 } 5853 } 5854 5855 createTokenizer() { 5856 this.tokenizer = tokenizer(this.input) 5857 } 5858 5859 decl(tokens, customProperty) { 5860 let node = new Declaration() 5861 this.init(node, tokens[0][2]) 5862 5863 let last = tokens[tokens.length - 1] 5864 if (last[0] === ';') { 5865 this.semicolon = true 5866 tokens.pop() 5867 } 5868 5869 node.source.end = this.getPosition( 5870 last[3] || last[2] || findLastWithPosition(tokens) 5871 ) 5872 node.source.end.offset++ 5873 5874 while (tokens[0][0] !== 'word') { 5875 if (tokens.length === 1) this.unknownWord(tokens) 5876 node.raws.before += tokens.shift()[1] 5877 } 5878 node.source.start = this.getPosition(tokens[0][2]) 5879 5880 node.prop = '' 5881 while (tokens.length) { 5882 let type = tokens[0][0] 5883 if (type === ':' || type === 'space' || type === 'comment') { 5884 break 5885 } 5886 node.prop += tokens.shift()[1] 5887 } 5888 5889 node.raws.between = '' 5890 5891 let token 5892 while (tokens.length) { 5893 token = tokens.shift() 5894 5895 if (token[0] === ':') { 5896 node.raws.between += token[1] 5897 break 5898 } else { 5899 if (token[0] === 'word' && /\w/.test(token[1])) { 5900 this.unknownWord([token]) 5901 } 5902 node.raws.between += token[1] 5903 } 5904 } 5905 5906 if (node.prop[0] === '_' || node.prop[0] === '*') { 5907 node.raws.before += node.prop[0] 5908 node.prop = node.prop.slice(1) 5909 } 5910 5911 let firstSpaces = [] 5912 let next 5913 while (tokens.length) { 5914 next = tokens[0][0] 5915 if (next !== 'space' && next !== 'comment') break 5916 firstSpaces.push(tokens.shift()) 5917 } 5918 5919 this.precheckMissedSemicolon(tokens) 5920 5921 for (let i = tokens.length - 1; i >= 0; i--) { 5922 token = tokens[i] 5923 if (token[1].toLowerCase() === '!important') { 5924 node.important = true 5925 let string = this.stringFrom(tokens, i) 5926 string = this.spacesFromEnd(tokens) + string 5927 if (string !== ' !important') node.raws.important = string 5928 break 5929 } else if (token[1].toLowerCase() === 'important') { 5930 let cache = tokens.slice(0) 5931 let str = '' 5932 for (let j = i; j > 0; j--) { 5933 let type = cache[j][0] 5934 if (str.trim().indexOf('!') === 0 && type !== 'space') { 5935 break 5936 } 5937 str = cache.pop()[1] + str 5938 } 5939 if (str.trim().indexOf('!') === 0) { 5940 node.important = true 5941 node.raws.important = str 5942 tokens = cache 5943 } 5944 } 5945 5946 if (token[0] !== 'space' && token[0] !== 'comment') { 5947 break 5948 } 5949 } 5950 5951 let hasWord = tokens.some(i => i[0] !== 'space' && i[0] !== 'comment') 5952 5953 if (hasWord) { 5954 node.raws.between += firstSpaces.map(i => i[1]).join('') 5955 firstSpaces = [] 5956 } 5957 this.raw(node, 'value', firstSpaces.concat(tokens), customProperty) 5958 5959 if (node.value.includes(':') && !customProperty) { 5960 this.checkMissedSemicolon(tokens) 5961 } 5962 } 5963 5964 doubleColon(token) { 5965 throw this.input.error( 5966 'Double colon', 5967 { offset: token[2] }, 5968 { offset: token[2] + token[1].length } 5969 ) 5970 } 5971 5972 emptyRule(token) { 5973 let node = new Rule() 5974 this.init(node, token[2]) 5975 node.selector = '' 5976 node.raws.between = '' 5977 this.current = node 5978 } 5979 5980 end(token) { 5981 if (this.current.nodes && this.current.nodes.length) { 5982 this.current.raws.semicolon = this.semicolon 5983 } 5984 this.semicolon = false 5985 5986 this.current.raws.after = (this.current.raws.after || '') + this.spaces 5987 this.spaces = '' 5988 5989 if (this.current.parent) { 5990 this.current.source.end = this.getPosition(token[2]) 5991 this.current.source.end.offset++ 5992 this.current = this.current.parent 5993 } else { 5994 this.unexpectedClose(token) 5995 } 5996 } 5997 5998 endFile() { 5999 if (this.current.parent) this.unclosedBlock() 6000 if (this.current.nodes && this.current.nodes.length) { 6001 this.current.raws.semicolon = this.semicolon 6002 } 6003 this.current.raws.after = (this.current.raws.after || '') + this.spaces 6004 this.root.source.end = this.getPosition(this.tokenizer.position()) 6005 } 6006 6007 freeSemicolon(token) { 6008 this.spaces += token[1] 6009 if (this.current.nodes) { 6010 let prev = this.current.nodes[this.current.nodes.length - 1] 6011 if (prev && prev.type === 'rule' && !prev.raws.ownSemicolon) { 6012 prev.raws.ownSemicolon = this.spaces 6013 this.spaces = '' 6014 } 6015 } 6016 } 6017 6018 // Helpers 6019 6020 getPosition(offset) { 6021 let pos = this.input.fromOffset(offset) 6022 return { 6023 column: pos.col, 6024 line: pos.line, 6025 offset 6026 } 6027 } 6028 6029 init(node, offset) { 6030 this.current.push(node) 6031 node.source = { 6032 input: this.input, 6033 start: this.getPosition(offset) 6034 } 6035 node.raws.before = this.spaces 6036 this.spaces = '' 6037 if (node.type !== 'comment') this.semicolon = false 6038 } 6039 6040 other(start) { 6041 let end = false 6042 let type = null 6043 let colon = false 6044 let bracket = null 6045 let brackets = [] 6046 let customProperty = start[1].startsWith('--') 6047 6048 let tokens = [] 6049 let token = start 6050 while (token) { 6051 type = token[0] 6052 tokens.push(token) 6053 6054 if (type === '(' || type === '[') { 6055 if (!bracket) bracket = token 6056 brackets.push(type === '(' ? ')' : ']') 6057 } else if (customProperty && colon && type === '{') { 6058 if (!bracket) bracket = token 6059 brackets.push('}') 6060 } else if (brackets.length === 0) { 6061 if (type === ';') { 6062 if (colon) { 6063 this.decl(tokens, customProperty) 6064 return 6065 } else { 6066 break 6067 } 6068 } else if (type === '{') { 6069 this.rule(tokens) 6070 return 6071 } else if (type === '}') { 6072 this.tokenizer.back(tokens.pop()) 6073 end = true 6074 break 6075 } else if (type === ':') { 6076 colon = true 6077 } 6078 } else if (type === brackets[brackets.length - 1]) { 6079 brackets.pop() 6080 if (brackets.length === 0) bracket = null 6081 } 6082 6083 token = this.tokenizer.nextToken() 6084 } 6085 6086 if (this.tokenizer.endOfFile()) end = true 6087 if (brackets.length > 0) this.unclosedBracket(bracket) 6088 6089 if (end && colon) { 6090 if (!customProperty) { 6091 while (tokens.length) { 6092 token = tokens[tokens.length - 1][0] 6093 if (token !== 'space' && token !== 'comment') break 6094 this.tokenizer.back(tokens.pop()) 6095 } 6096 } 6097 this.decl(tokens, customProperty) 6098 } else { 6099 this.unknownWord(tokens) 6100 } 6101 } 6102 6103 parse() { 6104 let token 6105 while (!this.tokenizer.endOfFile()) { 6106 token = this.tokenizer.nextToken() 6107 6108 switch (token[0]) { 6109 case 'space': 6110 this.spaces += token[1] 6111 break 6112 6113 case ';': 6114 this.freeSemicolon(token) 6115 break 6116 6117 case '}': 6118 this.end(token) 6119 break 6120 6121 case 'comment': 6122 this.comment(token) 6123 break 6124 6125 case 'at-word': 6126 this.atrule(token) 6127 break 6128 6129 case '{': 6130 this.emptyRule(token) 6131 break 6132 6133 default: 6134 this.other(token) 6135 break 6136 } 6137 } 6138 this.endFile() 6139 } 6140 6141 precheckMissedSemicolon(/* tokens */) { 6142 // Hook for Safe Parser 6143 } 6144 6145 raw(node, prop, tokens, customProperty) { 6146 let token, type 6147 let length = tokens.length 6148 let value = '' 6149 let clean = true 6150 let next, prev 6151 6152 for (let i = 0; i < length; i += 1) { 6153 token = tokens[i] 6154 type = token[0] 6155 if (type === 'space' && i === length - 1 && !customProperty) { 6156 clean = false 6157 } else if (type === 'comment') { 6158 prev = tokens[i - 1] ? tokens[i - 1][0] : 'empty' 6159 next = tokens[i + 1] ? tokens[i + 1][0] : 'empty' 6160 if (!SAFE_COMMENT_NEIGHBOR[prev] && !SAFE_COMMENT_NEIGHBOR[next]) { 6161 if (value.slice(-1) === ',') { 6162 clean = false 6163 } else { 6164 value += token[1] 6165 } 6166 } else { 6167 clean = false 6168 } 6169 } else { 6170 value += token[1] 6171 } 6172 } 6173 if (!clean) { 6174 let raw = tokens.reduce((all, i) => all + i[1], '') 6175 node.raws[prop] = { raw, value } 6176 } 6177 node[prop] = value 6178 } 6179 6180 rule(tokens) { 6181 tokens.pop() 6182 6183 let node = new Rule() 6184 this.init(node, tokens[0][2]) 6185 6186 node.raws.between = this.spacesAndCommentsFromEnd(tokens) 6187 this.raw(node, 'selector', tokens) 6188 this.current = node 6189 } 6190 6191 spacesAndCommentsFromEnd(tokens) { 6192 let lastTokenType 6193 let spaces = '' 6194 while (tokens.length) { 6195 lastTokenType = tokens[tokens.length - 1][0] 6196 if (lastTokenType !== 'space' && lastTokenType !== 'comment') break 6197 spaces = tokens.pop()[1] + spaces 6198 } 6199 return spaces 6200 } 6201 6202 // Errors 6203 6204 spacesAndCommentsFromStart(tokens) { 6205 let next 6206 let spaces = '' 6207 while (tokens.length) { 6208 next = tokens[0][0] 6209 if (next !== 'space' && next !== 'comment') break 6210 spaces += tokens.shift()[1] 6211 } 6212 return spaces 6213 } 6214 6215 spacesFromEnd(tokens) { 6216 let lastTokenType 6217 let spaces = '' 6218 while (tokens.length) { 6219 lastTokenType = tokens[tokens.length - 1][0] 6220 if (lastTokenType !== 'space') break 6221 spaces = tokens.pop()[1] + spaces 6222 } 6223 return spaces 6224 } 6225 6226 stringFrom(tokens, from) { 6227 let result = '' 6228 for (let i = from; i < tokens.length; i++) { 6229 result += tokens[i][1] 6230 } 6231 tokens.splice(from, tokens.length - from) 6232 return result 6233 } 6234 6235 unclosedBlock() { 6236 let pos = this.current.source.start 6237 throw this.input.error('Unclosed block', pos.line, pos.column) 6238 } 6239 6240 unclosedBracket(bracket) { 6241 throw this.input.error( 6242 'Unclosed bracket', 6243 { offset: bracket[2] }, 6244 { offset: bracket[2] + 1 } 6245 ) 6246 } 6247 6248 unexpectedClose(token) { 6249 throw this.input.error( 6250 'Unexpected }', 6251 { offset: token[2] }, 6252 { offset: token[2] + 1 } 6253 ) 6254 } 6255 6256 unknownWord(tokens) { 6257 throw this.input.error( 6258 'Unknown word', 6259 { offset: tokens[0][2] }, 6260 { offset: tokens[0][2] + tokens[0][1].length } 6261 ) 6262 } 6263 6264 unnamedAtrule(node, token) { 6265 throw this.input.error( 6266 'At-rule without name', 6267 { offset: token[2] }, 6268 { offset: token[2] + token[1].length } 6269 ) 6270 } 6271 } 6272 6273 module.exports = Parser 6274 6275 6276 /***/ }), 6277 6278 /***/ 4529: 6279 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 6280 6281 "use strict"; 6282 6283 6284 let CssSyntaxError = __webpack_require__(356) 6285 let Declaration = __webpack_require__(1516) 6286 let LazyResult = __webpack_require__(448) 6287 let Container = __webpack_require__(683) 6288 let Processor = __webpack_require__(9656) 6289 let stringify = __webpack_require__(633) 6290 let fromJSON = __webpack_require__(8940) 6291 let Document = __webpack_require__(271) 6292 let Warning = __webpack_require__(5776) 6293 let Comment = __webpack_require__(6589) 6294 let AtRule = __webpack_require__(1326) 6295 let Result = __webpack_require__(9055) 6296 let Input = __webpack_require__(5380) 6297 let parse = __webpack_require__(4295) 6298 let list = __webpack_require__(7374) 6299 let Rule = __webpack_require__(4092) 6300 let Root = __webpack_require__(9434) 6301 let Node = __webpack_require__(7490) 6302 6303 function postcss(...plugins) { 6304 if (plugins.length === 1 && Array.isArray(plugins[0])) { 6305 plugins = plugins[0] 6306 } 6307 return new Processor(plugins) 6308 } 6309 6310 postcss.plugin = function plugin(name, initializer) { 6311 let warningPrinted = false 6312 function creator(...args) { 6313 // eslint-disable-next-line no-console 6314 if (console && console.warn && !warningPrinted) { 6315 warningPrinted = true 6316 // eslint-disable-next-line no-console 6317 console.warn( 6318 name + 6319 ': postcss.plugin was deprecated. Migration guide:\n' + 6320 'https://evilmartians.com/chronicles/postcss-8-plugin-migration' 6321 ) 6322 if (process.env.LANG && process.env.LANG.startsWith('cn')) { 6323 /* c8 ignore next 7 */ 6324 // eslint-disable-next-line no-console 6325 console.warn( 6326 name + 6327 ': 里面 postcss.plugin 被弃用. 迁移指南:\n' + 6328 'https://www.w3ctech.com/topic/2226' 6329 ) 6330 } 6331 } 6332 let transformer = initializer(...args) 6333 transformer.postcssPlugin = name 6334 transformer.postcssVersion = new Processor().version 6335 return transformer 6336 } 6337 6338 let cache 6339 Object.defineProperty(creator, 'postcss', { 6340 get() { 6341 if (!cache) cache = creator() 6342 return cache 6343 } 6344 }) 6345 6346 creator.process = function (css, processOpts, pluginOpts) { 6347 return postcss([creator(pluginOpts)]).process(css, processOpts) 6348 } 6349 6350 return creator 6351 } 6352 6353 postcss.stringify = stringify 6354 postcss.parse = parse 6355 postcss.fromJSON = fromJSON 6356 postcss.list = list 6357 6358 postcss.comment = defaults => new Comment(defaults) 6359 postcss.atRule = defaults => new AtRule(defaults) 6360 postcss.decl = defaults => new Declaration(defaults) 6361 postcss.rule = defaults => new Rule(defaults) 6362 postcss.root = defaults => new Root(defaults) 6363 postcss.document = defaults => new Document(defaults) 6364 6365 postcss.CssSyntaxError = CssSyntaxError 6366 postcss.Declaration = Declaration 6367 postcss.Container = Container 6368 postcss.Processor = Processor 6369 postcss.Document = Document 6370 postcss.Comment = Comment 6371 postcss.Warning = Warning 6372 postcss.AtRule = AtRule 6373 postcss.Result = Result 6374 postcss.Input = Input 6375 postcss.Rule = Rule 6376 postcss.Root = Root 6377 postcss.Node = Node 6378 6379 LazyResult.registerPostcss(postcss) 6380 6381 module.exports = postcss 6382 postcss.default = postcss 6383 6384 6385 /***/ }), 6386 6387 /***/ 5696: 6388 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 6389 6390 "use strict"; 6391 6392 6393 let { SourceMapConsumer, SourceMapGenerator } = __webpack_require__(1866) 6394 let { existsSync, readFileSync } = __webpack_require__(9977) 6395 let { dirname, join } = __webpack_require__(197) 6396 6397 function fromBase64(str) { 6398 if (Buffer) { 6399 return Buffer.from(str, 'base64').toString() 6400 } else { 6401 /* c8 ignore next 2 */ 6402 return window.atob(str) 6403 } 6404 } 6405 6406 class PreviousMap { 6407 constructor(css, opts) { 6408 if (opts.map === false) return 6409 this.loadAnnotation(css) 6410 this.inline = this.startWith(this.annotation, 'data:') 6411 6412 let prev = opts.map ? opts.map.prev : undefined 6413 let text = this.loadMap(opts.from, prev) 6414 if (!this.mapFile && opts.from) { 6415 this.mapFile = opts.from 6416 } 6417 if (this.mapFile) this.root = dirname(this.mapFile) 6418 if (text) this.text = text 6419 } 6420 6421 consumer() { 6422 if (!this.consumerCache) { 6423 this.consumerCache = new SourceMapConsumer(this.text) 6424 } 6425 return this.consumerCache 6426 } 6427 6428 decodeInline(text) { 6429 let baseCharsetUri = /^data:application\/json;charset=utf-?8;base64,/ 6430 let baseUri = /^data:application\/json;base64,/ 6431 let charsetUri = /^data:application\/json;charset=utf-?8,/ 6432 let uri = /^data:application\/json,/ 6433 6434 if (charsetUri.test(text) || uri.test(text)) { 6435 return decodeURIComponent(text.substr(RegExp.lastMatch.length)) 6436 } 6437 6438 if (baseCharsetUri.test(text) || baseUri.test(text)) { 6439 return fromBase64(text.substr(RegExp.lastMatch.length)) 6440 } 6441 6442 let encoding = text.match(/data:application\/json;([^,]+),/)[1] 6443 throw new Error('Unsupported source map encoding ' + encoding) 6444 } 6445 6446 getAnnotationURL(sourceMapString) { 6447 return sourceMapString.replace(/^\/\*\s*# sourceMappingURL=/, '').trim() 6448 } 6449 6450 isMap(map) { 6451 if (typeof map !== 'object') return false 6452 return ( 6453 typeof map.mappings === 'string' || 6454 typeof map._mappings === 'string' || 6455 Array.isArray(map.sections) 6456 ) 6457 } 6458 6459 loadAnnotation(css) { 6460 let comments = css.match(/\/\*\s*# sourceMappingURL=/gm) 6461 if (!comments) return 6462 6463 // sourceMappingURLs from comments, strings, etc. 6464 let start = css.lastIndexOf(comments.pop()) 6465 let end = css.indexOf('*/', start) 6466 6467 if (start > -1 && end > -1) { 6468 // Locate the last sourceMappingURL to avoid pickin 6469 this.annotation = this.getAnnotationURL(css.substring(start, end)) 6470 } 6471 } 6472 6473 loadFile(path) { 6474 this.root = dirname(path) 6475 if (existsSync(path)) { 6476 this.mapFile = path 6477 return readFileSync(path, 'utf-8').toString().trim() 6478 } 6479 } 6480 6481 loadMap(file, prev) { 6482 if (prev === false) return false 6483 6484 if (prev) { 6485 if (typeof prev === 'string') { 6486 return prev 6487 } else if (typeof prev === 'function') { 6488 let prevPath = prev(file) 6489 if (prevPath) { 6490 let map = this.loadFile(prevPath) 6491 if (!map) { 6492 throw new Error( 6493 'Unable to load previous source map: ' + prevPath.toString() 6494 ) 6495 } 6496 return map 6497 } 6498 } else if (prev instanceof SourceMapConsumer) { 6499 return SourceMapGenerator.fromSourceMap(prev).toString() 6500 } else if (prev instanceof SourceMapGenerator) { 6501 return prev.toString() 6502 } else if (this.isMap(prev)) { 6503 return JSON.stringify(prev) 6504 } else { 6505 throw new Error( 6506 'Unsupported previous source map format: ' + prev.toString() 6507 ) 6508 } 6509 } else if (this.inline) { 6510 return this.decodeInline(this.annotation) 6511 } else if (this.annotation) { 6512 let map = this.annotation 6513 if (file) map = join(dirname(file), map) 6514 return this.loadFile(map) 6515 } 6516 } 6517 6518 startWith(string, start) { 6519 if (!string) return false 6520 return string.substr(0, start.length) === start 6521 } 6522 6523 withContent() { 6524 return !!( 6525 this.consumer().sourcesContent && 6526 this.consumer().sourcesContent.length > 0 6527 ) 6528 } 6529 } 6530 6531 module.exports = PreviousMap 6532 PreviousMap.default = PreviousMap 6533 6534 6535 /***/ }), 6536 6537 /***/ 9656: 6538 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 6539 6540 "use strict"; 6541 6542 6543 let NoWorkResult = __webpack_require__(7661) 6544 let LazyResult = __webpack_require__(448) 6545 let Document = __webpack_require__(271) 6546 let Root = __webpack_require__(9434) 6547 6548 class Processor { 6549 constructor(plugins = []) { 6550 this.version = '8.4.35' 6551 this.plugins = this.normalize(plugins) 6552 } 6553 6554 normalize(plugins) { 6555 let normalized = [] 6556 for (let i of plugins) { 6557 if (i.postcss === true) { 6558 i = i() 6559 } else if (i.postcss) { 6560 i = i.postcss 6561 } 6562 6563 if (typeof i === 'object' && Array.isArray(i.plugins)) { 6564 normalized = normalized.concat(i.plugins) 6565 } else if (typeof i === 'object' && i.postcssPlugin) { 6566 normalized.push(i) 6567 } else if (typeof i === 'function') { 6568 normalized.push(i) 6569 } else if (typeof i === 'object' && (i.parse || i.stringify)) { 6570 if (false) {} 6571 } else { 6572 throw new Error(i + ' is not a PostCSS plugin') 6573 } 6574 } 6575 return normalized 6576 } 6577 6578 process(css, opts = {}) { 6579 if ( 6580 !this.plugins.length && 6581 !opts.parser && 6582 !opts.stringifier && 6583 !opts.syntax 6584 ) { 6585 return new NoWorkResult(this, css, opts) 6586 } else { 6587 return new LazyResult(this, css, opts) 6588 } 6589 } 6590 6591 use(plugin) { 6592 this.plugins = this.plugins.concat(this.normalize([plugin])) 6593 return this 6594 } 6595 } 6596 6597 module.exports = Processor 6598 Processor.default = Processor 6599 6600 Root.registerProcessor(Processor) 6601 Document.registerProcessor(Processor) 6602 6603 6604 /***/ }), 6605 6606 /***/ 9055: 6607 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 6608 6609 "use strict"; 6610 6611 6612 let Warning = __webpack_require__(5776) 6613 6614 class Result { 6615 constructor(processor, root, opts) { 6616 this.processor = processor 6617 this.messages = [] 6618 this.root = root 6619 this.opts = opts 6620 this.css = undefined 6621 this.map = undefined 6622 } 6623 6624 toString() { 6625 return this.css 6626 } 6627 6628 warn(text, opts = {}) { 6629 if (!opts.plugin) { 6630 if (this.lastPlugin && this.lastPlugin.postcssPlugin) { 6631 opts.plugin = this.lastPlugin.postcssPlugin 6632 } 6633 } 6634 6635 let warning = new Warning(text, opts) 6636 this.messages.push(warning) 6637 6638 return warning 6639 } 6640 6641 warnings() { 6642 return this.messages.filter(i => i.type === 'warning') 6643 } 6644 6645 get content() { 6646 return this.css 6647 } 6648 } 6649 6650 module.exports = Result 6651 Result.default = Result 6652 6653 6654 /***/ }), 6655 6656 /***/ 9434: 6657 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 6658 6659 "use strict"; 6660 6661 6662 let Container = __webpack_require__(683) 6663 6664 let LazyResult, Processor 6665 6666 class Root extends Container { 6667 constructor(defaults) { 6668 super(defaults) 6669 this.type = 'root' 6670 if (!this.nodes) this.nodes = [] 6671 } 6672 6673 normalize(child, sample, type) { 6674 let nodes = super.normalize(child) 6675 6676 if (sample) { 6677 if (type === 'prepend') { 6678 if (this.nodes.length > 1) { 6679 sample.raws.before = this.nodes[1].raws.before 6680 } else { 6681 delete sample.raws.before 6682 } 6683 } else if (this.first !== sample) { 6684 for (let node of nodes) { 6685 node.raws.before = sample.raws.before 6686 } 6687 } 6688 } 6689 6690 return nodes 6691 } 6692 6693 removeChild(child, ignore) { 6694 let index = this.index(child) 6695 6696 if (!ignore && index === 0 && this.nodes.length > 1) { 6697 this.nodes[1].raws.before = this.nodes[index].raws.before 6698 } 6699 6700 return super.removeChild(child) 6701 } 6702 6703 toResult(opts = {}) { 6704 let lazy = new LazyResult(new Processor(), this, opts) 6705 return lazy.stringify() 6706 } 6707 } 6708 6709 Root.registerLazyResult = dependant => { 6710 LazyResult = dependant 6711 } 6712 6713 Root.registerProcessor = dependant => { 6714 Processor = dependant 6715 } 6716 6717 module.exports = Root 6718 Root.default = Root 6719 6720 Container.registerRoot(Root) 6721 6722 6723 /***/ }), 6724 6725 /***/ 4092: 6726 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 6727 6728 "use strict"; 6729 6730 6731 let Container = __webpack_require__(683) 6732 let list = __webpack_require__(7374) 6733 6734 class Rule extends Container { 6735 constructor(defaults) { 6736 super(defaults) 6737 this.type = 'rule' 6738 if (!this.nodes) this.nodes = [] 6739 } 6740 6741 get selectors() { 6742 return list.comma(this.selector) 6743 } 6744 6745 set selectors(values) { 6746 let match = this.selector ? this.selector.match(/,\s*/) : null 6747 let sep = match ? match[0] : ',' + this.raw('between', 'beforeOpen') 6748 this.selector = values.join(sep) 6749 } 6750 } 6751 6752 module.exports = Rule 6753 Rule.default = Rule 6754 6755 Container.registerRule(Rule) 6756 6757 6758 /***/ }), 6759 6760 /***/ 346: 6761 /***/ ((module) => { 6762 6763 "use strict"; 6764 6765 6766 const DEFAULT_RAW = { 6767 after: '\n', 6768 beforeClose: '\n', 6769 beforeComment: '\n', 6770 beforeDecl: '\n', 6771 beforeOpen: ' ', 6772 beforeRule: '\n', 6773 colon: ': ', 6774 commentLeft: ' ', 6775 commentRight: ' ', 6776 emptyBody: '', 6777 indent: ' ', 6778 semicolon: false 6779 } 6780 6781 function capitalize(str) { 6782 return str[0].toUpperCase() + str.slice(1) 6783 } 6784 6785 class Stringifier { 6786 constructor(builder) { 6787 this.builder = builder 6788 } 6789 6790 atrule(node, semicolon) { 6791 let name = '@' + node.name 6792 let params = node.params ? this.rawValue(node, 'params') : '' 6793 6794 if (typeof node.raws.afterName !== 'undefined') { 6795 name += node.raws.afterName 6796 } else if (params) { 6797 name += ' ' 6798 } 6799 6800 if (node.nodes) { 6801 this.block(node, name + params) 6802 } else { 6803 let end = (node.raws.between || '') + (semicolon ? ';' : '') 6804 this.builder(name + params + end, node) 6805 } 6806 } 6807 6808 beforeAfter(node, detect) { 6809 let value 6810 if (node.type === 'decl') { 6811 value = this.raw(node, null, 'beforeDecl') 6812 } else if (node.type === 'comment') { 6813 value = this.raw(node, null, 'beforeComment') 6814 } else if (detect === 'before') { 6815 value = this.raw(node, null, 'beforeRule') 6816 } else { 6817 value = this.raw(node, null, 'beforeClose') 6818 } 6819 6820 let buf = node.parent 6821 let depth = 0 6822 while (buf && buf.type !== 'root') { 6823 depth += 1 6824 buf = buf.parent 6825 } 6826 6827 if (value.includes('\n')) { 6828 let indent = this.raw(node, null, 'indent') 6829 if (indent.length) { 6830 for (let step = 0; step < depth; step++) value += indent 6831 } 6832 } 6833 6834 return value 6835 } 6836 6837 block(node, start) { 6838 let between = this.raw(node, 'between', 'beforeOpen') 6839 this.builder(start + between + '{', node, 'start') 6840 6841 let after 6842 if (node.nodes && node.nodes.length) { 6843 this.body(node) 6844 after = this.raw(node, 'after') 6845 } else { 6846 after = this.raw(node, 'after', 'emptyBody') 6847 } 6848 6849 if (after) this.builder(after) 6850 this.builder('}', node, 'end') 6851 } 6852 6853 body(node) { 6854 let last = node.nodes.length - 1 6855 while (last > 0) { 6856 if (node.nodes[last].type !== 'comment') break 6857 last -= 1 6858 } 6859 6860 let semicolon = this.raw(node, 'semicolon') 6861 for (let i = 0; i < node.nodes.length; i++) { 6862 let child = node.nodes[i] 6863 let before = this.raw(child, 'before') 6864 if (before) this.builder(before) 6865 this.stringify(child, last !== i || semicolon) 6866 } 6867 } 6868 6869 comment(node) { 6870 let left = this.raw(node, 'left', 'commentLeft') 6871 let right = this.raw(node, 'right', 'commentRight') 6872 this.builder('/*' + left + node.text + right + '*/', node) 6873 } 6874 6875 decl(node, semicolon) { 6876 let between = this.raw(node, 'between', 'colon') 6877 let string = node.prop + between + this.rawValue(node, 'value') 6878 6879 if (node.important) { 6880 string += node.raws.important || ' !important' 6881 } 6882 6883 if (semicolon) string += ';' 6884 this.builder(string, node) 6885 } 6886 6887 document(node) { 6888 this.body(node) 6889 } 6890 6891 raw(node, own, detect) { 6892 let value 6893 if (!detect) detect = own 6894 6895 // Already had 6896 if (own) { 6897 value = node.raws[own] 6898 if (typeof value !== 'undefined') return value 6899 } 6900 6901 let parent = node.parent 6902 6903 if (detect === 'before') { 6904 // Hack for first rule in CSS 6905 if (!parent || (parent.type === 'root' && parent.first === node)) { 6906 return '' 6907 } 6908 6909 // `root` nodes in `document` should use only their own raws 6910 if (parent && parent.type === 'document') { 6911 return '' 6912 } 6913 } 6914 6915 // Floating child without parent 6916 if (!parent) return DEFAULT_RAW[detect] 6917 6918 // Detect style by other nodes 6919 let root = node.root() 6920 if (!root.rawCache) root.rawCache = {} 6921 if (typeof root.rawCache[detect] !== 'undefined') { 6922 return root.rawCache[detect] 6923 } 6924 6925 if (detect === 'before' || detect === 'after') { 6926 return this.beforeAfter(node, detect) 6927 } else { 6928 let method = 'raw' + capitalize(detect) 6929 if (this[method]) { 6930 value = this[method](root, node) 6931 } else { 6932 root.walk(i => { 6933 value = i.raws[own] 6934 if (typeof value !== 'undefined') return false 6935 }) 6936 } 6937 } 6938 6939 if (typeof value === 'undefined') value = DEFAULT_RAW[detect] 6940 6941 root.rawCache[detect] = value 6942 return value 6943 } 6944 6945 rawBeforeClose(root) { 6946 let value 6947 root.walk(i => { 6948 if (i.nodes && i.nodes.length > 0) { 6949 if (typeof i.raws.after !== 'undefined') { 6950 value = i.raws.after 6951 if (value.includes('\n')) { 6952 value = value.replace(/[^\n]+$/, '') 6953 } 6954 return false 6955 } 6956 } 6957 }) 6958 if (value) value = value.replace(/\S/g, '') 6959 return value 6960 } 6961 6962 rawBeforeComment(root, node) { 6963 let value 6964 root.walkComments(i => { 6965 if (typeof i.raws.before !== 'undefined') { 6966 value = i.raws.before 6967 if (value.includes('\n')) { 6968 value = value.replace(/[^\n]+$/, '') 6969 } 6970 return false 6971 } 6972 }) 6973 if (typeof value === 'undefined') { 6974 value = this.raw(node, null, 'beforeDecl') 6975 } else if (value) { 6976 value = value.replace(/\S/g, '') 6977 } 6978 return value 6979 } 6980 6981 rawBeforeDecl(root, node) { 6982 let value 6983 root.walkDecls(i => { 6984 if (typeof i.raws.before !== 'undefined') { 6985 value = i.raws.before 6986 if (value.includes('\n')) { 6987 value = value.replace(/[^\n]+$/, '') 6988 } 6989 return false 6990 } 6991 }) 6992 if (typeof value === 'undefined') { 6993 value = this.raw(node, null, 'beforeRule') 6994 } else if (value) { 6995 value = value.replace(/\S/g, '') 6996 } 6997 return value 6998 } 6999 7000 rawBeforeOpen(root) { 7001 let value 7002 root.walk(i => { 7003 if (i.type !== 'decl') { 7004 value = i.raws.between 7005 if (typeof value !== 'undefined') return false 7006 } 7007 }) 7008 return value 7009 } 7010 7011 rawBeforeRule(root) { 7012 let value 7013 root.walk(i => { 7014 if (i.nodes && (i.parent !== root || root.first !== i)) { 7015 if (typeof i.raws.before !== 'undefined') { 7016 value = i.raws.before 7017 if (value.includes('\n')) { 7018 value = value.replace(/[^\n]+$/, '') 7019 } 7020 return false 7021 } 7022 } 7023 }) 7024 if (value) value = value.replace(/\S/g, '') 7025 return value 7026 } 7027 7028 rawColon(root) { 7029 let value 7030 root.walkDecls(i => { 7031 if (typeof i.raws.between !== 'undefined') { 7032 value = i.raws.between.replace(/[^\s:]/g, '') 7033 return false 7034 } 7035 }) 7036 return value 7037 } 7038 7039 rawEmptyBody(root) { 7040 let value 7041 root.walk(i => { 7042 if (i.nodes && i.nodes.length === 0) { 7043 value = i.raws.after 7044 if (typeof value !== 'undefined') return false 7045 } 7046 }) 7047 return value 7048 } 7049 7050 rawIndent(root) { 7051 if (root.raws.indent) return root.raws.indent 7052 let value 7053 root.walk(i => { 7054 let p = i.parent 7055 if (p && p !== root && p.parent && p.parent === root) { 7056 if (typeof i.raws.before !== 'undefined') { 7057 let parts = i.raws.before.split('\n') 7058 value = parts[parts.length - 1] 7059 value = value.replace(/\S/g, '') 7060 return false 7061 } 7062 } 7063 }) 7064 return value 7065 } 7066 7067 rawSemicolon(root) { 7068 let value 7069 root.walk(i => { 7070 if (i.nodes && i.nodes.length && i.last.type === 'decl') { 7071 value = i.raws.semicolon 7072 if (typeof value !== 'undefined') return false 7073 } 7074 }) 7075 return value 7076 } 7077 7078 rawValue(node, prop) { 7079 let value = node[prop] 7080 let raw = node.raws[prop] 7081 if (raw && raw.value === value) { 7082 return raw.raw 7083 } 7084 7085 return value 7086 } 7087 7088 root(node) { 7089 this.body(node) 7090 if (node.raws.after) this.builder(node.raws.after) 7091 } 7092 7093 rule(node) { 7094 this.block(node, this.rawValue(node, 'selector')) 7095 if (node.raws.ownSemicolon) { 7096 this.builder(node.raws.ownSemicolon, node, 'end') 7097 } 7098 } 7099 7100 stringify(node, semicolon) { 7101 /* c8 ignore start */ 7102 if (!this[node.type]) { 7103 throw new Error( 7104 'Unknown AST node type ' + 7105 node.type + 7106 '. ' + 7107 'Maybe you need to change PostCSS stringifier.' 7108 ) 7109 } 7110 /* c8 ignore stop */ 7111 this[node.type](node, semicolon) 7112 } 7113 } 7114 7115 module.exports = Stringifier 7116 Stringifier.default = Stringifier 7117 7118 7119 /***/ }), 7120 7121 /***/ 633: 7122 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 7123 7124 "use strict"; 7125 7126 7127 let Stringifier = __webpack_require__(346) 7128 7129 function stringify(node, builder) { 7130 let str = new Stringifier(builder) 7131 str.stringify(node) 7132 } 7133 7134 module.exports = stringify 7135 stringify.default = stringify 7136 7137 7138 /***/ }), 7139 7140 /***/ 1381: 7141 /***/ ((module) => { 7142 7143 "use strict"; 7144 7145 7146 module.exports.isClean = Symbol('isClean') 7147 7148 module.exports.my = Symbol('my') 7149 7150 7151 /***/ }), 7152 7153 /***/ 2327: 7154 /***/ ((module) => { 7155 7156 "use strict"; 7157 7158 7159 const SINGLE_QUOTE = "'".charCodeAt(0) 7160 const DOUBLE_QUOTE = '"'.charCodeAt(0) 7161 const BACKSLASH = '\\'.charCodeAt(0) 7162 const SLASH = '/'.charCodeAt(0) 7163 const NEWLINE = '\n'.charCodeAt(0) 7164 const SPACE = ' '.charCodeAt(0) 7165 const FEED = '\f'.charCodeAt(0) 7166 const TAB = '\t'.charCodeAt(0) 7167 const CR = '\r'.charCodeAt(0) 7168 const OPEN_SQUARE = '['.charCodeAt(0) 7169 const CLOSE_SQUARE = ']'.charCodeAt(0) 7170 const OPEN_PARENTHESES = '('.charCodeAt(0) 7171 const CLOSE_PARENTHESES = ')'.charCodeAt(0) 7172 const OPEN_CURLY = '{'.charCodeAt(0) 7173 const CLOSE_CURLY = '}'.charCodeAt(0) 7174 const SEMICOLON = ';'.charCodeAt(0) 7175 const ASTERISK = '*'.charCodeAt(0) 7176 const COLON = ':'.charCodeAt(0) 7177 const AT = '@'.charCodeAt(0) 7178 7179 const RE_AT_END = /[\t\n\f\r "#'()/;[\\\]{}]/g 7180 const RE_WORD_END = /[\t\n\f\r !"#'():;@[\\\]{}]|\/(?=\*)/g 7181 const RE_BAD_BRACKET = /.[\r\n"'(/\\]/ 7182 const RE_HEX_ESCAPE = /[\da-f]/i 7183 7184 module.exports = function tokenizer(input, options = {}) { 7185 let css = input.css.valueOf() 7186 let ignore = options.ignoreErrors 7187 7188 let code, next, quote, content, escape 7189 let escaped, escapePos, prev, n, currentToken 7190 7191 let length = css.length 7192 let pos = 0 7193 let buffer = [] 7194 let returned = [] 7195 7196 function position() { 7197 return pos 7198 } 7199 7200 function unclosed(what) { 7201 throw input.error('Unclosed ' + what, pos) 7202 } 7203 7204 function endOfFile() { 7205 return returned.length === 0 && pos >= length 7206 } 7207 7208 function nextToken(opts) { 7209 if (returned.length) return returned.pop() 7210 if (pos >= length) return 7211 7212 let ignoreUnclosed = opts ? opts.ignoreUnclosed : false 7213 7214 code = css.charCodeAt(pos) 7215 7216 switch (code) { 7217 case NEWLINE: 7218 case SPACE: 7219 case TAB: 7220 case CR: 7221 case FEED: { 7222 next = pos 7223 do { 7224 next += 1 7225 code = css.charCodeAt(next) 7226 } while ( 7227 code === SPACE || 7228 code === NEWLINE || 7229 code === TAB || 7230 code === CR || 7231 code === FEED 7232 ) 7233 7234 currentToken = ['space', css.slice(pos, next)] 7235 pos = next - 1 7236 break 7237 } 7238 7239 case OPEN_SQUARE: 7240 case CLOSE_SQUARE: 7241 case OPEN_CURLY: 7242 case CLOSE_CURLY: 7243 case COLON: 7244 case SEMICOLON: 7245 case CLOSE_PARENTHESES: { 7246 let controlChar = String.fromCharCode(code) 7247 currentToken = [controlChar, controlChar, pos] 7248 break 7249 } 7250 7251 case OPEN_PARENTHESES: { 7252 prev = buffer.length ? buffer.pop()[1] : '' 7253 n = css.charCodeAt(pos + 1) 7254 if ( 7255 prev === 'url' && 7256 n !== SINGLE_QUOTE && 7257 n !== DOUBLE_QUOTE && 7258 n !== SPACE && 7259 n !== NEWLINE && 7260 n !== TAB && 7261 n !== FEED && 7262 n !== CR 7263 ) { 7264 next = pos 7265 do { 7266 escaped = false 7267 next = css.indexOf(')', next + 1) 7268 if (next === -1) { 7269 if (ignore || ignoreUnclosed) { 7270 next = pos 7271 break 7272 } else { 7273 unclosed('bracket') 7274 } 7275 } 7276 escapePos = next 7277 while (css.charCodeAt(escapePos - 1) === BACKSLASH) { 7278 escapePos -= 1 7279 escaped = !escaped 7280 } 7281 } while (escaped) 7282 7283 currentToken = ['brackets', css.slice(pos, next + 1), pos, next] 7284 7285 pos = next 7286 } else { 7287 next = css.indexOf(')', pos + 1) 7288 content = css.slice(pos, next + 1) 7289 7290 if (next === -1 || RE_BAD_BRACKET.test(content)) { 7291 currentToken = ['(', '(', pos] 7292 } else { 7293 currentToken = ['brackets', content, pos, next] 7294 pos = next 7295 } 7296 } 7297 7298 break 7299 } 7300 7301 case SINGLE_QUOTE: 7302 case DOUBLE_QUOTE: { 7303 quote = code === SINGLE_QUOTE ? "'" : '"' 7304 next = pos 7305 do { 7306 escaped = false 7307 next = css.indexOf(quote, next + 1) 7308 if (next === -1) { 7309 if (ignore || ignoreUnclosed) { 7310 next = pos + 1 7311 break 7312 } else { 7313 unclosed('string') 7314 } 7315 } 7316 escapePos = next 7317 while (css.charCodeAt(escapePos - 1) === BACKSLASH) { 7318 escapePos -= 1 7319 escaped = !escaped 7320 } 7321 } while (escaped) 7322 7323 currentToken = ['string', css.slice(pos, next + 1), pos, next] 7324 pos = next 7325 break 7326 } 7327 7328 case AT: { 7329 RE_AT_END.lastIndex = pos + 1 7330 RE_AT_END.test(css) 7331 if (RE_AT_END.lastIndex === 0) { 7332 next = css.length - 1 7333 } else { 7334 next = RE_AT_END.lastIndex - 2 7335 } 7336 7337 currentToken = ['at-word', css.slice(pos, next + 1), pos, next] 7338 7339 pos = next 7340 break 7341 } 7342 7343 case BACKSLASH: { 7344 next = pos 7345 escape = true 7346 while (css.charCodeAt(next + 1) === BACKSLASH) { 7347 next += 1 7348 escape = !escape 7349 } 7350 code = css.charCodeAt(next + 1) 7351 if ( 7352 escape && 7353 code !== SLASH && 7354 code !== SPACE && 7355 code !== NEWLINE && 7356 code !== TAB && 7357 code !== CR && 7358 code !== FEED 7359 ) { 7360 next += 1 7361 if (RE_HEX_ESCAPE.test(css.charAt(next))) { 7362 while (RE_HEX_ESCAPE.test(css.charAt(next + 1))) { 7363 next += 1 7364 } 7365 if (css.charCodeAt(next + 1) === SPACE) { 7366 next += 1 7367 } 7368 } 7369 } 7370 7371 currentToken = ['word', css.slice(pos, next + 1), pos, next] 7372 7373 pos = next 7374 break 7375 } 7376 7377 default: { 7378 if (code === SLASH && css.charCodeAt(pos + 1) === ASTERISK) { 7379 next = css.indexOf('*/', pos + 2) + 1 7380 if (next === 0) { 7381 if (ignore || ignoreUnclosed) { 7382 next = css.length 7383 } else { 7384 unclosed('comment') 7385 } 7386 } 7387 7388 currentToken = ['comment', css.slice(pos, next + 1), pos, next] 7389 pos = next 7390 } else { 7391 RE_WORD_END.lastIndex = pos + 1 7392 RE_WORD_END.test(css) 7393 if (RE_WORD_END.lastIndex === 0) { 7394 next = css.length - 1 7395 } else { 7396 next = RE_WORD_END.lastIndex - 2 7397 } 7398 7399 currentToken = ['word', css.slice(pos, next + 1), pos, next] 7400 buffer.push(currentToken) 7401 pos = next 7402 } 7403 7404 break 7405 } 7406 } 7407 7408 pos++ 7409 return currentToken 7410 } 7411 7412 function back(token) { 7413 returned.push(token) 7414 } 7415 7416 return { 7417 back, 7418 endOfFile, 7419 nextToken, 7420 position 7421 } 7422 } 7423 7424 7425 /***/ }), 7426 7427 /***/ 3122: 7428 /***/ ((module) => { 7429 7430 "use strict"; 7431 /* eslint-disable no-console */ 7432 7433 7434 let printed = {} 7435 7436 module.exports = function warnOnce(message) { 7437 if (printed[message]) return 7438 printed[message] = true 7439 7440 if (typeof console !== 'undefined' && console.warn) { 7441 console.warn(message) 7442 } 7443 } 7444 7445 7446 /***/ }), 7447 7448 /***/ 5776: 7449 /***/ ((module) => { 7450 7451 "use strict"; 7452 7453 7454 class Warning { 7455 constructor(text, opts = {}) { 7456 this.type = 'warning' 7457 this.text = text 7458 7459 if (opts.node && opts.node.source) { 7460 let range = opts.node.rangeBy(opts) 7461 this.line = range.start.line 7462 this.column = range.start.column 7463 this.endLine = range.end.line 7464 this.endColumn = range.end.column 7465 } 7466 7467 for (let opt in opts) this[opt] = opts[opt] 7468 } 7469 7470 toString() { 7471 if (this.node) { 7472 return this.node.error(this.text, { 7473 index: this.index, 7474 plugin: this.plugin, 7475 word: this.word 7476 }).message 7477 } 7478 7479 if (this.plugin) { 7480 return this.plugin + ': ' + this.text 7481 } 7482 7483 return this.text 7484 } 7485 } 7486 7487 module.exports = Warning 7488 Warning.default = Warning 7489 7490 7491 /***/ }), 7492 7493 /***/ 628: 7494 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 7495 7496 "use strict"; 7497 /** 7498 * Copyright (c) 2013-present, Facebook, Inc. 7499 * 7500 * This source code is licensed under the MIT license found in the 7501 * LICENSE file in the root directory of this source tree. 7502 */ 7503 7504 7505 7506 var ReactPropTypesSecret = __webpack_require__(4067); 7507 7508 function emptyFunction() {} 7509 function emptyFunctionWithReset() {} 7510 emptyFunctionWithReset.resetWarningCache = emptyFunction; 7511 7512 module.exports = function() { 7513 function shim(props, propName, componentName, location, propFullName, secret) { 7514 if (secret === ReactPropTypesSecret) { 7515 // It is still safe when called from React. 7516 return; 7517 } 7518 var err = new Error( 7519 'Calling PropTypes validators directly is not supported by the `prop-types` package. ' + 7520 'Use PropTypes.checkPropTypes() to call them. ' + 7521 'Read more at http://fb.me/use-check-prop-types' 7522 ); 7523 err.name = 'Invariant Violation'; 7524 throw err; 7525 }; 7526 shim.isRequired = shim; 7527 function getShim() { 7528 return shim; 7529 }; 7530 // Important! 7531 // Keep this list in sync with production version in `./factoryWithTypeCheckers.js`. 7532 var ReactPropTypes = { 7533 array: shim, 7534 bigint: shim, 7535 bool: shim, 7536 func: shim, 7537 number: shim, 7538 object: shim, 7539 string: shim, 7540 symbol: shim, 7541 7542 any: shim, 7543 arrayOf: getShim, 7544 element: shim, 7545 elementType: shim, 7546 instanceOf: getShim, 7547 node: shim, 7548 objectOf: getShim, 7549 oneOf: getShim, 7550 oneOfType: getShim, 7551 shape: getShim, 7552 exact: getShim, 7553 7554 checkPropTypes: emptyFunctionWithReset, 7555 resetWarningCache: emptyFunction 7556 }; 7557 7558 ReactPropTypes.PropTypes = ReactPropTypes; 7559 7560 return ReactPropTypes; 7561 }; 7562 7563 7564 /***/ }), 7565 7566 /***/ 5826: 7567 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 7568 7569 /** 7570 * Copyright (c) 2013-present, Facebook, Inc. 7571 * 7572 * This source code is licensed under the MIT license found in the 7573 * LICENSE file in the root directory of this source tree. 7574 */ 7575 7576 if (false) { var throwOnDirectAccess, ReactIs; } else { 7577 // By explicitly using `prop-types` you are opting into new production behavior. 7578 // http://fb.me/prop-types-in-prod 7579 module.exports = __webpack_require__(628)(); 7580 } 7581 7582 7583 /***/ }), 7584 7585 /***/ 4067: 7586 /***/ ((module) => { 7587 7588 "use strict"; 7589 /** 7590 * Copyright (c) 2013-present, Facebook, Inc. 7591 * 7592 * This source code is licensed under the MIT license found in the 7593 * LICENSE file in the root directory of this source tree. 7594 */ 7595 7596 7597 7598 var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'; 7599 7600 module.exports = ReactPropTypesSecret; 7601 7602 7603 /***/ }), 7604 7605 /***/ 4462: 7606 /***/ (function(__unused_webpack_module, exports, __webpack_require__) { 7607 7608 "use strict"; 7609 7610 var __extends = (this && this.__extends) || (function () { 7611 var extendStatics = Object.setPrototypeOf || 7612 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 7613 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; 7614 return function (d, b) { 7615 extendStatics(d, b); 7616 function __() { this.constructor = d; } 7617 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 7618 }; 7619 })(); 7620 var __assign = (this && this.__assign) || Object.assign || function(t) { 7621 for (var s, i = 1, n = arguments.length; i < n; i++) { 7622 s = arguments[i]; 7623 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) 7624 t[p] = s[p]; 7625 } 7626 return t; 7627 }; 7628 var __rest = (this && this.__rest) || function (s, e) { 7629 var t = {}; 7630 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) 7631 t[p] = s[p]; 7632 if (s != null && typeof Object.getOwnPropertySymbols === "function") 7633 for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) 7634 t[p[i]] = s[p[i]]; 7635 return t; 7636 }; 7637 exports.__esModule = true; 7638 var React = __webpack_require__(1609); 7639 var PropTypes = __webpack_require__(5826); 7640 var autosize = __webpack_require__(4306); 7641 var _getLineHeight = __webpack_require__(461); 7642 var getLineHeight = _getLineHeight; 7643 var RESIZED = "autosize:resized"; 7644 /** 7645 * A light replacement for built-in textarea component 7646 * which automaticaly adjusts its height to match the content 7647 */ 7648 var TextareaAutosizeClass = /** @class */ (function (_super) { 7649 __extends(TextareaAutosizeClass, _super); 7650 function TextareaAutosizeClass() { 7651 var _this = _super !== null && _super.apply(this, arguments) || this; 7652 _this.state = { 7653 lineHeight: null 7654 }; 7655 _this.textarea = null; 7656 _this.onResize = function (e) { 7657 if (_this.props.onResize) { 7658 _this.props.onResize(e); 7659 } 7660 }; 7661 _this.updateLineHeight = function () { 7662 if (_this.textarea) { 7663 _this.setState({ 7664 lineHeight: getLineHeight(_this.textarea) 7665 }); 7666 } 7667 }; 7668 _this.onChange = function (e) { 7669 var onChange = _this.props.onChange; 7670 _this.currentValue = e.currentTarget.value; 7671 onChange && onChange(e); 7672 }; 7673 return _this; 7674 } 7675 TextareaAutosizeClass.prototype.componentDidMount = function () { 7676 var _this = this; 7677 var _a = this.props, maxRows = _a.maxRows, async = _a.async; 7678 if (typeof maxRows === "number") { 7679 this.updateLineHeight(); 7680 } 7681 if (typeof maxRows === "number" || async) { 7682 /* 7683 the defer is needed to: 7684 - force "autosize" to activate the scrollbar when this.props.maxRows is passed 7685 - support StyledComponents (see #71) 7686 */ 7687 setTimeout(function () { return _this.textarea && autosize(_this.textarea); }); 7688 } 7689 else { 7690 this.textarea && autosize(this.textarea); 7691 } 7692 if (this.textarea) { 7693 this.textarea.addEventListener(RESIZED, this.onResize); 7694 } 7695 }; 7696 TextareaAutosizeClass.prototype.componentWillUnmount = function () { 7697 if (this.textarea) { 7698 this.textarea.removeEventListener(RESIZED, this.onResize); 7699 autosize.destroy(this.textarea); 7700 } 7701 }; 7702 TextareaAutosizeClass.prototype.render = function () { 7703 var _this = this; 7704 var _a = this, _b = _a.props, onResize = _b.onResize, maxRows = _b.maxRows, onChange = _b.onChange, style = _b.style, innerRef = _b.innerRef, children = _b.children, props = __rest(_b, ["onResize", "maxRows", "onChange", "style", "innerRef", "children"]), lineHeight = _a.state.lineHeight; 7705 var maxHeight = maxRows && lineHeight ? lineHeight * maxRows : null; 7706 return (React.createElement("textarea", __assign({}, props, { onChange: this.onChange, style: maxHeight ? __assign({}, style, { maxHeight: maxHeight }) : style, ref: function (element) { 7707 _this.textarea = element; 7708 if (typeof _this.props.innerRef === 'function') { 7709 _this.props.innerRef(element); 7710 } 7711 else if (_this.props.innerRef) { 7712 _this.props.innerRef.current = element; 7713 } 7714 } }), children)); 7715 }; 7716 TextareaAutosizeClass.prototype.componentDidUpdate = function () { 7717 this.textarea && autosize.update(this.textarea); 7718 }; 7719 TextareaAutosizeClass.defaultProps = { 7720 rows: 1, 7721 async: false 7722 }; 7723 TextareaAutosizeClass.propTypes = { 7724 rows: PropTypes.number, 7725 maxRows: PropTypes.number, 7726 onResize: PropTypes.func, 7727 innerRef: PropTypes.any, 7728 async: PropTypes.bool 7729 }; 7730 return TextareaAutosizeClass; 7731 }(React.Component)); 7732 exports.TextareaAutosize = React.forwardRef(function (props, ref) { 7733 return React.createElement(TextareaAutosizeClass, __assign({}, props, { innerRef: ref })); 7734 }); 7735 7736 7737 /***/ }), 7738 7739 /***/ 4132: 7740 /***/ ((__unused_webpack_module, exports, __webpack_require__) => { 7741 7742 "use strict"; 7743 var __webpack_unused_export__; 7744 7745 __webpack_unused_export__ = true; 7746 var TextareaAutosize_1 = __webpack_require__(4462); 7747 exports.A = TextareaAutosize_1.TextareaAutosize; 7748 7749 7750 /***/ }), 7751 7752 /***/ 9681: 7753 /***/ ((module) => { 7754 7755 var characterMap = { 7756 "À": "A", 7757 "Á": "A", 7758 "Â": "A", 7759 "Ã": "A", 7760 "Ä": "A", 7761 "Å": "A", 7762 "Ấ": "A", 7763 "Ắ": "A", 7764 "Ẳ": "A", 7765 "Ẵ": "A", 7766 "Ặ": "A", 7767 "Æ": "AE", 7768 "Ầ": "A", 7769 "Ằ": "A", 7770 "Ȃ": "A", 7771 "Ả": "A", 7772 "Ạ": "A", 7773 "Ẩ": "A", 7774 "Ẫ": "A", 7775 "Ậ": "A", 7776 "Ç": "C", 7777 "Ḉ": "C", 7778 "È": "E", 7779 "É": "E", 7780 "Ê": "E", 7781 "Ë": "E", 7782 "Ế": "E", 7783 "Ḗ": "E", 7784 "Ề": "E", 7785 "Ḕ": "E", 7786 "Ḝ": "E", 7787 "Ȇ": "E", 7788 "Ẻ": "E", 7789 "Ẽ": "E", 7790 "Ẹ": "E", 7791 "Ể": "E", 7792 "Ễ": "E", 7793 "Ệ": "E", 7794 "Ì": "I", 7795 "Í": "I", 7796 "Î": "I", 7797 "Ï": "I", 7798 "Ḯ": "I", 7799 "Ȋ": "I", 7800 "Ỉ": "I", 7801 "Ị": "I", 7802 "Ð": "D", 7803 "Ñ": "N", 7804 "Ò": "O", 7805 "Ó": "O", 7806 "Ô": "O", 7807 "Õ": "O", 7808 "Ö": "O", 7809 "Ø": "O", 7810 "Ố": "O", 7811 "Ṍ": "O", 7812 "Ṓ": "O", 7813 "Ȏ": "O", 7814 "Ỏ": "O", 7815 "Ọ": "O", 7816 "Ổ": "O", 7817 "Ỗ": "O", 7818 "Ộ": "O", 7819 "Ờ": "O", 7820 "Ở": "O", 7821 "Ỡ": "O", 7822 "Ớ": "O", 7823 "Ợ": "O", 7824 "Ù": "U", 7825 "Ú": "U", 7826 "Û": "U", 7827 "Ü": "U", 7828 "Ủ": "U", 7829 "Ụ": "U", 7830 "Ử": "U", 7831 "Ữ": "U", 7832 "Ự": "U", 7833 "Ý": "Y", 7834 "à": "a", 7835 "á": "a", 7836 "â": "a", 7837 "ã": "a", 7838 "ä": "a", 7839 "å": "a", 7840 "ấ": "a", 7841 "ắ": "a", 7842 "ẳ": "a", 7843 "ẵ": "a", 7844 "ặ": "a", 7845 "æ": "ae", 7846 "ầ": "a", 7847 "ằ": "a", 7848 "ȃ": "a", 7849 "ả": "a", 7850 "ạ": "a", 7851 "ẩ": "a", 7852 "ẫ": "a", 7853 "ậ": "a", 7854 "ç": "c", 7855 "ḉ": "c", 7856 "è": "e", 7857 "é": "e", 7858 "ê": "e", 7859 "ë": "e", 7860 "ế": "e", 7861 "ḗ": "e", 7862 "ề": "e", 7863 "ḕ": "e", 7864 "ḝ": "e", 7865 "ȇ": "e", 7866 "ẻ": "e", 7867 "ẽ": "e", 7868 "ẹ": "e", 7869 "ể": "e", 7870 "ễ": "e", 7871 "ệ": "e", 7872 "ì": "i", 7873 "í": "i", 7874 "î": "i", 7875 "ï": "i", 7876 "ḯ": "i", 7877 "ȋ": "i", 7878 "ỉ": "i", 7879 "ị": "i", 7880 "ð": "d", 7881 "ñ": "n", 7882 "ò": "o", 7883 "ó": "o", 7884 "ô": "o", 7885 "õ": "o", 7886 "ö": "o", 7887 "ø": "o", 7888 "ố": "o", 7889 "ṍ": "o", 7890 "ṓ": "o", 7891 "ȏ": "o", 7892 "ỏ": "o", 7893 "ọ": "o", 7894 "ổ": "o", 7895 "ỗ": "o", 7896 "ộ": "o", 7897 "ờ": "o", 7898 "ở": "o", 7899 "ỡ": "o", 7900 "ớ": "o", 7901 "ợ": "o", 7902 "ù": "u", 7903 "ú": "u", 7904 "û": "u", 7905 "ü": "u", 7906 "ủ": "u", 7907 "ụ": "u", 7908 "ử": "u", 7909 "ữ": "u", 7910 "ự": "u", 7911 "ý": "y", 7912 "ÿ": "y", 7913 "Ā": "A", 7914 "ā": "a", 7915 "Ă": "A", 7916 "ă": "a", 7917 "Ą": "A", 7918 "ą": "a", 7919 "Ć": "C", 7920 "ć": "c", 7921 "Ĉ": "C", 7922 "ĉ": "c", 7923 "Ċ": "C", 7924 "ċ": "c", 7925 "Č": "C", 7926 "č": "c", 7927 "C̆": "C", 7928 "c̆": "c", 7929 "Ď": "D", 7930 "ď": "d", 7931 "Đ": "D", 7932 "đ": "d", 7933 "Ē": "E", 7934 "ē": "e", 7935 "Ĕ": "E", 7936 "ĕ": "e", 7937 "Ė": "E", 7938 "ė": "e", 7939 "Ę": "E", 7940 "ę": "e", 7941 "Ě": "E", 7942 "ě": "e", 7943 "Ĝ": "G", 7944 "Ǵ": "G", 7945 "ĝ": "g", 7946 "ǵ": "g", 7947 "Ğ": "G", 7948 "ğ": "g", 7949 "Ġ": "G", 7950 "ġ": "g", 7951 "Ģ": "G", 7952 "ģ": "g", 7953 "Ĥ": "H", 7954 "ĥ": "h", 7955 "Ħ": "H", 7956 "ħ": "h", 7957 "Ḫ": "H", 7958 "ḫ": "h", 7959 "Ĩ": "I", 7960 "ĩ": "i", 7961 "Ī": "I", 7962 "ī": "i", 7963 "Ĭ": "I", 7964 "ĭ": "i", 7965 "Į": "I", 7966 "į": "i", 7967 "İ": "I", 7968 "ı": "i", 7969 "IJ": "IJ", 7970 "ij": "ij", 7971 "Ĵ": "J", 7972 "ĵ": "j", 7973 "Ķ": "K", 7974 "ķ": "k", 7975 "Ḱ": "K", 7976 "ḱ": "k", 7977 "K̆": "K", 7978 "k̆": "k", 7979 "Ĺ": "L", 7980 "ĺ": "l", 7981 "Ļ": "L", 7982 "ļ": "l", 7983 "Ľ": "L", 7984 "ľ": "l", 7985 "Ŀ": "L", 7986 "ŀ": "l", 7987 "Ł": "l", 7988 "ł": "l", 7989 "Ḿ": "M", 7990 "ḿ": "m", 7991 "M̆": "M", 7992 "m̆": "m", 7993 "Ń": "N", 7994 "ń": "n", 7995 "Ņ": "N", 7996 "ņ": "n", 7997 "Ň": "N", 7998 "ň": "n", 7999 "ʼn": "n", 8000 "N̆": "N", 8001 "n̆": "n", 8002 "Ō": "O", 8003 "ō": "o", 8004 "Ŏ": "O", 8005 "ŏ": "o", 8006 "Ő": "O", 8007 "ő": "o", 8008 "Œ": "OE", 8009 "œ": "oe", 8010 "P̆": "P", 8011 "p̆": "p", 8012 "Ŕ": "R", 8013 "ŕ": "r", 8014 "Ŗ": "R", 8015 "ŗ": "r", 8016 "Ř": "R", 8017 "ř": "r", 8018 "R̆": "R", 8019 "r̆": "r", 8020 "Ȓ": "R", 8021 "ȓ": "r", 8022 "Ś": "S", 8023 "ś": "s", 8024 "Ŝ": "S", 8025 "ŝ": "s", 8026 "Ş": "S", 8027 "Ș": "S", 8028 "ș": "s", 8029 "ş": "s", 8030 "Š": "S", 8031 "š": "s", 8032 "Ţ": "T", 8033 "ţ": "t", 8034 "ț": "t", 8035 "Ț": "T", 8036 "Ť": "T", 8037 "ť": "t", 8038 "Ŧ": "T", 8039 "ŧ": "t", 8040 "T̆": "T", 8041 "t̆": "t", 8042 "Ũ": "U", 8043 "ũ": "u", 8044 "Ū": "U", 8045 "ū": "u", 8046 "Ŭ": "U", 8047 "ŭ": "u", 8048 "Ů": "U", 8049 "ů": "u", 8050 "Ű": "U", 8051 "ű": "u", 8052 "Ų": "U", 8053 "ų": "u", 8054 "Ȗ": "U", 8055 "ȗ": "u", 8056 "V̆": "V", 8057 "v̆": "v", 8058 "Ŵ": "W", 8059 "ŵ": "w", 8060 "Ẃ": "W", 8061 "ẃ": "w", 8062 "X̆": "X", 8063 "x̆": "x", 8064 "Ŷ": "Y", 8065 "ŷ": "y", 8066 "Ÿ": "Y", 8067 "Y̆": "Y", 8068 "y̆": "y", 8069 "Ź": "Z", 8070 "ź": "z", 8071 "Ż": "Z", 8072 "ż": "z", 8073 "Ž": "Z", 8074 "ž": "z", 8075 "ſ": "s", 8076 "ƒ": "f", 8077 "Ơ": "O", 8078 "ơ": "o", 8079 "Ư": "U", 8080 "ư": "u", 8081 "Ǎ": "A", 8082 "ǎ": "a", 8083 "Ǐ": "I", 8084 "ǐ": "i", 8085 "Ǒ": "O", 8086 "ǒ": "o", 8087 "Ǔ": "U", 8088 "ǔ": "u", 8089 "Ǖ": "U", 8090 "ǖ": "u", 8091 "Ǘ": "U", 8092 "ǘ": "u", 8093 "Ǚ": "U", 8094 "ǚ": "u", 8095 "Ǜ": "U", 8096 "ǜ": "u", 8097 "Ứ": "U", 8098 "ứ": "u", 8099 "Ṹ": "U", 8100 "ṹ": "u", 8101 "Ǻ": "A", 8102 "ǻ": "a", 8103 "Ǽ": "AE", 8104 "ǽ": "ae", 8105 "Ǿ": "O", 8106 "ǿ": "o", 8107 "Þ": "TH", 8108 "þ": "th", 8109 "Ṕ": "P", 8110 "ṕ": "p", 8111 "Ṥ": "S", 8112 "ṥ": "s", 8113 "X́": "X", 8114 "x́": "x", 8115 "Ѓ": "Г", 8116 "ѓ": "г", 8117 "Ќ": "К", 8118 "ќ": "к", 8119 "A̋": "A", 8120 "a̋": "a", 8121 "E̋": "E", 8122 "e̋": "e", 8123 "I̋": "I", 8124 "i̋": "i", 8125 "Ǹ": "N", 8126 "ǹ": "n", 8127 "Ồ": "O", 8128 "ồ": "o", 8129 "Ṑ": "O", 8130 "ṑ": "o", 8131 "Ừ": "U", 8132 "ừ": "u", 8133 "Ẁ": "W", 8134 "ẁ": "w", 8135 "Ỳ": "Y", 8136 "ỳ": "y", 8137 "Ȁ": "A", 8138 "ȁ": "a", 8139 "Ȅ": "E", 8140 "ȅ": "e", 8141 "Ȉ": "I", 8142 "ȉ": "i", 8143 "Ȍ": "O", 8144 "ȍ": "o", 8145 "Ȑ": "R", 8146 "ȑ": "r", 8147 "Ȕ": "U", 8148 "ȕ": "u", 8149 "B̌": "B", 8150 "b̌": "b", 8151 "Č̣": "C", 8152 "č̣": "c", 8153 "Ê̌": "E", 8154 "ê̌": "e", 8155 "F̌": "F", 8156 "f̌": "f", 8157 "Ǧ": "G", 8158 "ǧ": "g", 8159 "Ȟ": "H", 8160 "ȟ": "h", 8161 "J̌": "J", 8162 "ǰ": "j", 8163 "Ǩ": "K", 8164 "ǩ": "k", 8165 "M̌": "M", 8166 "m̌": "m", 8167 "P̌": "P", 8168 "p̌": "p", 8169 "Q̌": "Q", 8170 "q̌": "q", 8171 "Ř̩": "R", 8172 "ř̩": "r", 8173 "Ṧ": "S", 8174 "ṧ": "s", 8175 "V̌": "V", 8176 "v̌": "v", 8177 "W̌": "W", 8178 "w̌": "w", 8179 "X̌": "X", 8180 "x̌": "x", 8181 "Y̌": "Y", 8182 "y̌": "y", 8183 "A̧": "A", 8184 "a̧": "a", 8185 "B̧": "B", 8186 "b̧": "b", 8187 "Ḑ": "D", 8188 "ḑ": "d", 8189 "Ȩ": "E", 8190 "ȩ": "e", 8191 "Ɛ̧": "E", 8192 "ɛ̧": "e", 8193 "Ḩ": "H", 8194 "ḩ": "h", 8195 "I̧": "I", 8196 "i̧": "i", 8197 "Ɨ̧": "I", 8198 "ɨ̧": "i", 8199 "M̧": "M", 8200 "m̧": "m", 8201 "O̧": "O", 8202 "o̧": "o", 8203 "Q̧": "Q", 8204 "q̧": "q", 8205 "U̧": "U", 8206 "u̧": "u", 8207 "X̧": "X", 8208 "x̧": "x", 8209 "Z̧": "Z", 8210 "z̧": "z", 8211 "й":"и", 8212 "Й":"И", 8213 "ё":"е", 8214 "Ё":"Е", 8215 }; 8216 8217 var chars = Object.keys(characterMap).join('|'); 8218 var allAccents = new RegExp(chars, 'g'); 8219 var firstAccent = new RegExp(chars, ''); 8220 8221 function matcher(match) { 8222 return characterMap[match]; 8223 } 8224 8225 var removeAccents = function(string) { 8226 return string.replace(allAccents, matcher); 8227 }; 8228 8229 var hasAccents = function(string) { 8230 return !!string.match(firstAccent); 8231 }; 8232 8233 module.exports = removeAccents; 8234 module.exports.has = hasAccents; 8235 module.exports.remove = removeAccents; 8236 8237 8238 /***/ }), 8239 8240 /***/ 1609: 8241 /***/ ((module) => { 8242 8243 "use strict"; 8244 module.exports = window["React"]; 8245 8246 /***/ }), 8247 8248 /***/ 9746: 8249 /***/ (() => { 8250 8251 /* (ignored) */ 8252 8253 /***/ }), 8254 8255 /***/ 9977: 8256 /***/ (() => { 8257 8258 /* (ignored) */ 8259 8260 /***/ }), 8261 8262 /***/ 197: 8263 /***/ (() => { 8264 8265 /* (ignored) */ 8266 8267 /***/ }), 8268 8269 /***/ 1866: 8270 /***/ (() => { 8271 8272 /* (ignored) */ 8273 8274 /***/ }), 8275 8276 /***/ 2739: 8277 /***/ (() => { 8278 8279 /* (ignored) */ 8280 8281 /***/ }), 8282 8283 /***/ 5042: 8284 /***/ ((module) => { 8285 8286 let urlAlphabet = 8287 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict' 8288 let customAlphabet = (alphabet, defaultSize = 21) => { 8289 return (size = defaultSize) => { 8290 let id = '' 8291 let i = size 8292 while (i--) { 8293 id += alphabet[(Math.random() * alphabet.length) | 0] 8294 } 8295 return id 8296 } 8297 } 8298 let nanoid = (size = 21) => { 8299 let id = '' 8300 let i = size 8301 while (i--) { 8302 id += urlAlphabet[(Math.random() * 64) | 0] 8303 } 8304 return id 8305 } 8306 module.exports = { nanoid, customAlphabet } 8307 8308 8309 /***/ }) 8310 8311 /******/ }); 8312 /************************************************************************/ 8313 /******/ // The module cache 8314 /******/ var __webpack_module_cache__ = {}; 8315 /******/ 8316 /******/ // The require function 8317 /******/ function __webpack_require__(moduleId) { 8318 /******/ // Check if module is in cache 8319 /******/ var cachedModule = __webpack_module_cache__[moduleId]; 8320 /******/ if (cachedModule !== undefined) { 8321 /******/ return cachedModule.exports; 8322 /******/ } 8323 /******/ // Create a new module (and put it into the cache) 8324 /******/ var module = __webpack_module_cache__[moduleId] = { 8325 /******/ // no module.id needed 8326 /******/ // no module.loaded needed 8327 /******/ exports: {} 8328 /******/ }; 8329 /******/ 8330 /******/ // Execute the module function 8331 /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); 8332 /******/ 8333 /******/ // Return the exports of the module 8334 /******/ return module.exports; 8335 /******/ } 8336 /******/ 8337 /************************************************************************/ 8338 /******/ /* webpack/runtime/compat get default export */ 8339 /******/ (() => { 8340 /******/ // getDefaultExport function for compatibility with non-harmony modules 8341 /******/ __webpack_require__.n = (module) => { 8342 /******/ var getter = module && module.__esModule ? 8343 /******/ () => (module['default']) : 8344 /******/ () => (module); 8345 /******/ __webpack_require__.d(getter, { a: getter }); 8346 /******/ return getter; 8347 /******/ }; 8348 /******/ })(); 8349 /******/ 8350 /******/ /* webpack/runtime/define property getters */ 8351 /******/ (() => { 8352 /******/ // define getter functions for harmony exports 8353 /******/ __webpack_require__.d = (exports, definition) => { 8354 /******/ for(var key in definition) { 8355 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { 8356 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); 8357 /******/ } 8358 /******/ } 8359 /******/ }; 8360 /******/ })(); 8361 /******/ 8362 /******/ /* webpack/runtime/hasOwnProperty shorthand */ 8363 /******/ (() => { 8364 /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) 8365 /******/ })(); 8366 /******/ 8367 /******/ /* webpack/runtime/make namespace object */ 8368 /******/ (() => { 8369 /******/ // define __esModule on exports 8370 /******/ __webpack_require__.r = (exports) => { 8371 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 8372 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 8373 /******/ } 8374 /******/ Object.defineProperty(exports, '__esModule', { value: true }); 8375 /******/ }; 8376 /******/ })(); 8377 /******/ 8378 /************************************************************************/ 8379 var __webpack_exports__ = {}; 8380 // This entry need to be wrapped in an IIFE because it need to be in strict mode. 8381 (() => { 8382 "use strict"; 8383 // ESM COMPAT FLAG 8384 __webpack_require__.r(__webpack_exports__); 8385 8386 // EXPORTS 8387 __webpack_require__.d(__webpack_exports__, { 8388 AlignmentControl: () => (/* reexport */ AlignmentControl), 8389 AlignmentToolbar: () => (/* reexport */ AlignmentToolbar), 8390 Autocomplete: () => (/* reexport */ autocomplete), 8391 BlockAlignmentControl: () => (/* reexport */ BlockAlignmentControl), 8392 BlockAlignmentToolbar: () => (/* reexport */ BlockAlignmentToolbar), 8393 BlockBreadcrumb: () => (/* reexport */ block_breadcrumb), 8394 BlockCanvas: () => (/* reexport */ block_canvas), 8395 BlockColorsStyleSelector: () => (/* reexport */ color_style_selector), 8396 BlockContextProvider: () => (/* reexport */ BlockContextProvider), 8397 BlockControls: () => (/* reexport */ block_controls), 8398 BlockEdit: () => (/* reexport */ BlockEdit), 8399 BlockEditorKeyboardShortcuts: () => (/* reexport */ keyboard_shortcuts), 8400 BlockEditorProvider: () => (/* reexport */ provider), 8401 BlockFormatControls: () => (/* reexport */ BlockFormatControls), 8402 BlockIcon: () => (/* reexport */ block_icon), 8403 BlockInspector: () => (/* reexport */ block_inspector), 8404 BlockList: () => (/* reexport */ BlockList), 8405 BlockMover: () => (/* reexport */ block_mover), 8406 BlockNavigationDropdown: () => (/* reexport */ dropdown), 8407 BlockPreview: () => (/* reexport */ block_preview), 8408 BlockSelectionClearer: () => (/* reexport */ BlockSelectionClearer), 8409 BlockSettingsMenu: () => (/* reexport */ block_settings_menu), 8410 BlockSettingsMenuControls: () => (/* reexport */ block_settings_menu_controls), 8411 BlockStyles: () => (/* reexport */ block_styles), 8412 BlockTitle: () => (/* reexport */ BlockTitle), 8413 BlockToolbar: () => (/* reexport */ BlockToolbar), 8414 BlockTools: () => (/* reexport */ BlockTools), 8415 BlockVerticalAlignmentControl: () => (/* reexport */ BlockVerticalAlignmentControl), 8416 BlockVerticalAlignmentToolbar: () => (/* reexport */ BlockVerticalAlignmentToolbar), 8417 ButtonBlockAppender: () => (/* reexport */ button_block_appender), 8418 ButtonBlockerAppender: () => (/* reexport */ ButtonBlockerAppender), 8419 ColorPalette: () => (/* reexport */ color_palette), 8420 ColorPaletteControl: () => (/* reexport */ ColorPaletteControl), 8421 ContrastChecker: () => (/* reexport */ contrast_checker), 8422 CopyHandler: () => (/* reexport */ CopyHandler), 8423 DefaultBlockAppender: () => (/* reexport */ DefaultBlockAppender), 8424 FontSizePicker: () => (/* reexport */ font_size_picker), 8425 HeadingLevelDropdown: () => (/* reexport */ HeadingLevelDropdown), 8426 HeightControl: () => (/* reexport */ HeightControl), 8427 InnerBlocks: () => (/* reexport */ inner_blocks), 8428 Inserter: () => (/* reexport */ inserter), 8429 InspectorAdvancedControls: () => (/* reexport */ InspectorAdvancedControls), 8430 InspectorControls: () => (/* reexport */ inspector_controls), 8431 JustifyContentControl: () => (/* reexport */ JustifyContentControl), 8432 JustifyToolbar: () => (/* reexport */ JustifyToolbar), 8433 LineHeightControl: () => (/* reexport */ line_height_control), 8434 MediaPlaceholder: () => (/* reexport */ media_placeholder), 8435 MediaReplaceFlow: () => (/* reexport */ media_replace_flow), 8436 MediaUpload: () => (/* reexport */ media_upload), 8437 MediaUploadCheck: () => (/* reexport */ check), 8438 MultiSelectScrollIntoView: () => (/* reexport */ MultiSelectScrollIntoView), 8439 NavigableToolbar: () => (/* reexport */ NavigableToolbar), 8440 ObserveTyping: () => (/* reexport */ observe_typing), 8441 PanelColorSettings: () => (/* reexport */ panel_color_settings), 8442 PlainText: () => (/* reexport */ plain_text), 8443 RecursionProvider: () => (/* reexport */ RecursionProvider), 8444 ReusableBlocksRenameHint: () => (/* reexport */ ReusableBlocksRenameHint), 8445 RichText: () => (/* reexport */ rich_text), 8446 RichTextShortcut: () => (/* reexport */ RichTextShortcut), 8447 RichTextToolbarButton: () => (/* reexport */ RichTextToolbarButton), 8448 SETTINGS_DEFAULTS: () => (/* reexport */ SETTINGS_DEFAULTS), 8449 SkipToSelectedBlock: () => (/* reexport */ skip_to_selected_block), 8450 ToolSelector: () => (/* reexport */ tool_selector), 8451 Typewriter: () => (/* reexport */ typewriter), 8452 URLInput: () => (/* reexport */ url_input), 8453 URLInputButton: () => (/* reexport */ url_input_button), 8454 URLPopover: () => (/* reexport */ url_popover), 8455 Warning: () => (/* reexport */ warning), 8456 WritingFlow: () => (/* reexport */ writing_flow), 8457 __experimentalBlockAlignmentMatrixControl: () => (/* reexport */ block_alignment_matrix_control), 8458 __experimentalBlockFullHeightAligmentControl: () => (/* reexport */ block_full_height_alignment_control), 8459 __experimentalBlockPatternSetup: () => (/* reexport */ block_pattern_setup), 8460 __experimentalBlockPatternsList: () => (/* reexport */ block_patterns_list), 8461 __experimentalBlockVariationPicker: () => (/* reexport */ block_variation_picker), 8462 __experimentalBlockVariationTransforms: () => (/* reexport */ block_variation_transforms), 8463 __experimentalBorderRadiusControl: () => (/* reexport */ BorderRadiusControl), 8464 __experimentalColorGradientControl: () => (/* reexport */ control), 8465 __experimentalColorGradientSettingsDropdown: () => (/* reexport */ ColorGradientSettingsDropdown), 8466 __experimentalDateFormatPicker: () => (/* reexport */ DateFormatPicker), 8467 __experimentalDuotoneControl: () => (/* reexport */ duotone_control), 8468 __experimentalFontAppearanceControl: () => (/* reexport */ FontAppearanceControl), 8469 __experimentalFontFamilyControl: () => (/* reexport */ FontFamilyControl), 8470 __experimentalGetBorderClassesAndStyles: () => (/* reexport */ getBorderClassesAndStyles), 8471 __experimentalGetColorClassesAndStyles: () => (/* reexport */ getColorClassesAndStyles), 8472 __experimentalGetElementClassName: () => (/* reexport */ __experimentalGetElementClassName), 8473 __experimentalGetGapCSSValue: () => (/* reexport */ getGapCSSValue), 8474 __experimentalGetGradientClass: () => (/* reexport */ __experimentalGetGradientClass), 8475 __experimentalGetGradientObjectByGradientValue: () => (/* reexport */ __experimentalGetGradientObjectByGradientValue), 8476 __experimentalGetShadowClassesAndStyles: () => (/* reexport */ getShadowClassesAndStyles), 8477 __experimentalGetSpacingClassesAndStyles: () => (/* reexport */ getSpacingClassesAndStyles), 8478 __experimentalImageEditor: () => (/* reexport */ ImageEditor), 8479 __experimentalImageSizeControl: () => (/* reexport */ ImageSizeControl), 8480 __experimentalImageURLInputUI: () => (/* reexport */ ImageURLInputUI), 8481 __experimentalInspectorPopoverHeader: () => (/* reexport */ InspectorPopoverHeader), 8482 __experimentalLetterSpacingControl: () => (/* reexport */ LetterSpacingControl), 8483 __experimentalLibrary: () => (/* reexport */ library), 8484 __experimentalLinkControl: () => (/* reexport */ link_control), 8485 __experimentalLinkControlSearchInput: () => (/* reexport */ search_input), 8486 __experimentalLinkControlSearchItem: () => (/* reexport */ search_item), 8487 __experimentalLinkControlSearchResults: () => (/* reexport */ LinkControlSearchResults), 8488 __experimentalListView: () => (/* reexport */ components_list_view), 8489 __experimentalPanelColorGradientSettings: () => (/* reexport */ panel_color_gradient_settings), 8490 __experimentalPreviewOptions: () => (/* reexport */ PreviewOptions), 8491 __experimentalPublishDateTimePicker: () => (/* reexport */ publish_date_time_picker), 8492 __experimentalRecursionProvider: () => (/* reexport */ DeprecatedExperimentalRecursionProvider), 8493 __experimentalResponsiveBlockControl: () => (/* reexport */ responsive_block_control), 8494 __experimentalSpacingSizesControl: () => (/* reexport */ SpacingSizesControl), 8495 __experimentalTextDecorationControl: () => (/* reexport */ TextDecorationControl), 8496 __experimentalTextTransformControl: () => (/* reexport */ TextTransformControl), 8497 __experimentalUnitControl: () => (/* reexport */ UnitControl), 8498 __experimentalUseBlockOverlayActive: () => (/* reexport */ useBlockOverlayActive), 8499 __experimentalUseBlockPreview: () => (/* reexport */ useBlockPreview), 8500 __experimentalUseBorderProps: () => (/* reexport */ useBorderProps), 8501 __experimentalUseColorProps: () => (/* reexport */ useColorProps), 8502 __experimentalUseCustomSides: () => (/* reexport */ useCustomSides), 8503 __experimentalUseGradient: () => (/* reexport */ __experimentalUseGradient), 8504 __experimentalUseHasRecursion: () => (/* reexport */ DeprecatedExperimentalUseHasRecursion), 8505 __experimentalUseMultipleOriginColorsAndGradients: () => (/* reexport */ useMultipleOriginColorsAndGradients), 8506 __experimentalUseResizeCanvas: () => (/* reexport */ useResizeCanvas), 8507 __experimentalWritingModeControl: () => (/* reexport */ WritingModeControl), 8508 __unstableBlockNameContext: () => (/* reexport */ block_name_context), 8509 __unstableBlockSettingsMenuFirstItem: () => (/* reexport */ block_settings_menu_first_item), 8510 __unstableBlockToolbarLastItem: () => (/* reexport */ block_toolbar_last_item), 8511 __unstableEditorStyles: () => (/* reexport */ EditorStyles), 8512 __unstableIframe: () => (/* reexport */ iframe), 8513 __unstableInserterMenuExtension: () => (/* reexport */ inserter_menu_extension), 8514 __unstableRichTextInputEvent: () => (/* reexport */ __unstableRichTextInputEvent), 8515 __unstableUseBlockSelectionClearer: () => (/* reexport */ useBlockSelectionClearer), 8516 __unstableUseClipboardHandler: () => (/* reexport */ __unstableUseClipboardHandler), 8517 __unstableUseMouseMoveTypingReset: () => (/* reexport */ useMouseMoveTypingReset), 8518 __unstableUseTypewriter: () => (/* reexport */ useTypewriter), 8519 __unstableUseTypingObserver: () => (/* reexport */ useTypingObserver), 8520 createCustomColorsHOC: () => (/* reexport */ createCustomColorsHOC), 8521 getColorClassName: () => (/* reexport */ getColorClassName), 8522 getColorObjectByAttributeValues: () => (/* reexport */ getColorObjectByAttributeValues), 8523 getColorObjectByColorValue: () => (/* reexport */ getColorObjectByColorValue), 8524 getComputedFluidTypographyValue: () => (/* reexport */ getComputedFluidTypographyValue), 8525 getCustomValueFromPreset: () => (/* reexport */ getCustomValueFromPreset), 8526 getFontSize: () => (/* reexport */ utils_getFontSize), 8527 getFontSizeClass: () => (/* reexport */ getFontSizeClass), 8528 getFontSizeObjectByValue: () => (/* reexport */ utils_getFontSizeObjectByValue), 8529 getGradientSlugByValue: () => (/* reexport */ getGradientSlugByValue), 8530 getGradientValueBySlug: () => (/* reexport */ getGradientValueBySlug), 8531 getPxFromCssUnit: () => (/* reexport */ get_px_from_css_unit), 8532 getSpacingPresetCssVar: () => (/* reexport */ getSpacingPresetCssVar), 8533 getTypographyClassesAndStyles: () => (/* reexport */ getTypographyClassesAndStyles), 8534 isValueSpacingPreset: () => (/* reexport */ isValueSpacingPreset), 8535 privateApis: () => (/* reexport */ privateApis), 8536 store: () => (/* reexport */ store), 8537 storeConfig: () => (/* reexport */ storeConfig), 8538 transformStyles: () => (/* reexport */ transform_styles), 8539 useBlockCommands: () => (/* reexport */ useBlockCommands), 8540 useBlockDisplayInformation: () => (/* reexport */ useBlockDisplayInformation), 8541 useBlockEditContext: () => (/* reexport */ useBlockEditContext), 8542 useBlockEditingMode: () => (/* reexport */ useBlockEditingMode), 8543 useBlockProps: () => (/* reexport */ use_block_props_useBlockProps), 8544 useCachedTruthy: () => (/* reexport */ useCachedTruthy), 8545 useHasRecursion: () => (/* reexport */ useHasRecursion), 8546 useInnerBlocksProps: () => (/* reexport */ useInnerBlocksProps), 8547 useSetting: () => (/* reexport */ useSetting), 8548 useSettings: () => (/* reexport */ use_settings_useSettings), 8549 withColorContext: () => (/* reexport */ with_color_context), 8550 withColors: () => (/* reexport */ withColors), 8551 withFontSizes: () => (/* reexport */ with_font_sizes) 8552 }); 8553 8554 // NAMESPACE OBJECT: ./node_modules/@wordpress/block-editor/build-module/store/selectors.js 8555 var selectors_namespaceObject = {}; 8556 __webpack_require__.r(selectors_namespaceObject); 8557 __webpack_require__.d(selectors_namespaceObject, { 8558 __experimentalGetActiveBlockIdByBlockNames: () => (__experimentalGetActiveBlockIdByBlockNames), 8559 __experimentalGetAllowedBlocks: () => (__experimentalGetAllowedBlocks), 8560 __experimentalGetAllowedPatterns: () => (__experimentalGetAllowedPatterns), 8561 __experimentalGetBlockListSettingsForBlocks: () => (__experimentalGetBlockListSettingsForBlocks), 8562 __experimentalGetDirectInsertBlock: () => (__experimentalGetDirectInsertBlock), 8563 __experimentalGetGlobalBlocksByName: () => (__experimentalGetGlobalBlocksByName), 8564 __experimentalGetLastBlockAttributeChanges: () => (__experimentalGetLastBlockAttributeChanges), 8565 __experimentalGetParsedPattern: () => (__experimentalGetParsedPattern), 8566 __experimentalGetPatternTransformItems: () => (__experimentalGetPatternTransformItems), 8567 __experimentalGetPatternsByBlockTypes: () => (__experimentalGetPatternsByBlockTypes), 8568 __experimentalGetReusableBlockTitle: () => (__experimentalGetReusableBlockTitle), 8569 __unstableGetBlockWithoutInnerBlocks: () => (__unstableGetBlockWithoutInnerBlocks), 8570 __unstableGetClientIdWithClientIdsTree: () => (__unstableGetClientIdWithClientIdsTree), 8571 __unstableGetClientIdsTree: () => (__unstableGetClientIdsTree), 8572 __unstableGetContentLockingParent: () => (__unstableGetContentLockingParent), 8573 __unstableGetEditorMode: () => (__unstableGetEditorMode), 8574 __unstableGetSelectedBlocksWithPartialSelection: () => (__unstableGetSelectedBlocksWithPartialSelection), 8575 __unstableGetTemporarilyEditingAsBlocks: () => (__unstableGetTemporarilyEditingAsBlocks), 8576 __unstableGetTemporarilyEditingFocusModeToRevert: () => (__unstableGetTemporarilyEditingFocusModeToRevert), 8577 __unstableGetVisibleBlocks: () => (__unstableGetVisibleBlocks), 8578 __unstableHasActiveBlockOverlayActive: () => (__unstableHasActiveBlockOverlayActive), 8579 __unstableIsFullySelected: () => (__unstableIsFullySelected), 8580 __unstableIsLastBlockChangeIgnored: () => (__unstableIsLastBlockChangeIgnored), 8581 __unstableIsSelectionCollapsed: () => (__unstableIsSelectionCollapsed), 8582 __unstableIsSelectionMergeable: () => (__unstableIsSelectionMergeable), 8583 __unstableIsWithinBlockOverlay: () => (__unstableIsWithinBlockOverlay), 8584 __unstableSelectionHasUnmergeableBlock: () => (__unstableSelectionHasUnmergeableBlock), 8585 areInnerBlocksControlled: () => (areInnerBlocksControlled), 8586 canEditBlock: () => (canEditBlock), 8587 canInsertBlockType: () => (canInsertBlockType), 8588 canInsertBlocks: () => (canInsertBlocks), 8589 canLockBlockType: () => (canLockBlockType), 8590 canMoveBlock: () => (canMoveBlock), 8591 canMoveBlocks: () => (canMoveBlocks), 8592 canRemoveBlock: () => (canRemoveBlock), 8593 canRemoveBlocks: () => (canRemoveBlocks), 8594 didAutomaticChange: () => (didAutomaticChange), 8595 getAdjacentBlockClientId: () => (getAdjacentBlockClientId), 8596 getAllowedBlocks: () => (getAllowedBlocks), 8597 getBlock: () => (getBlock), 8598 getBlockAttributes: () => (getBlockAttributes), 8599 getBlockCount: () => (getBlockCount), 8600 getBlockEditingMode: () => (getBlockEditingMode), 8601 getBlockHierarchyRootClientId: () => (getBlockHierarchyRootClientId), 8602 getBlockIndex: () => (getBlockIndex), 8603 getBlockInsertionPoint: () => (getBlockInsertionPoint), 8604 getBlockListSettings: () => (getBlockListSettings), 8605 getBlockMode: () => (getBlockMode), 8606 getBlockName: () => (getBlockName), 8607 getBlockNamesByClientId: () => (getBlockNamesByClientId), 8608 getBlockOrder: () => (getBlockOrder), 8609 getBlockParents: () => (getBlockParents), 8610 getBlockParentsByBlockName: () => (getBlockParentsByBlockName), 8611 getBlockRootClientId: () => (getBlockRootClientId), 8612 getBlockSelectionEnd: () => (getBlockSelectionEnd), 8613 getBlockSelectionStart: () => (getBlockSelectionStart), 8614 getBlockTransformItems: () => (getBlockTransformItems), 8615 getBlocks: () => (getBlocks), 8616 getBlocksByClientId: () => (getBlocksByClientId), 8617 getBlocksByName: () => (getBlocksByName), 8618 getClientIdsOfDescendants: () => (getClientIdsOfDescendants), 8619 getClientIdsWithDescendants: () => (getClientIdsWithDescendants), 8620 getDirectInsertBlock: () => (getDirectInsertBlock), 8621 getDraggedBlockClientIds: () => (getDraggedBlockClientIds), 8622 getFirstMultiSelectedBlockClientId: () => (getFirstMultiSelectedBlockClientId), 8623 getGlobalBlockCount: () => (getGlobalBlockCount), 8624 getInserterItems: () => (getInserterItems), 8625 getLastMultiSelectedBlockClientId: () => (getLastMultiSelectedBlockClientId), 8626 getLowestCommonAncestorWithSelectedBlock: () => (getLowestCommonAncestorWithSelectedBlock), 8627 getMultiSelectedBlockClientIds: () => (getMultiSelectedBlockClientIds), 8628 getMultiSelectedBlocks: () => (getMultiSelectedBlocks), 8629 getMultiSelectedBlocksEndClientId: () => (getMultiSelectedBlocksEndClientId), 8630 getMultiSelectedBlocksStartClientId: () => (getMultiSelectedBlocksStartClientId), 8631 getNextBlockClientId: () => (getNextBlockClientId), 8632 getPatternsByBlockTypes: () => (getPatternsByBlockTypes), 8633 getPreviousBlockClientId: () => (getPreviousBlockClientId), 8634 getSelectedBlock: () => (getSelectedBlock), 8635 getSelectedBlockClientId: () => (getSelectedBlockClientId), 8636 getSelectedBlockClientIds: () => (getSelectedBlockClientIds), 8637 getSelectedBlockCount: () => (getSelectedBlockCount), 8638 getSelectedBlocksInitialCaretPosition: () => (getSelectedBlocksInitialCaretPosition), 8639 getSelectionEnd: () => (getSelectionEnd), 8640 getSelectionStart: () => (getSelectionStart), 8641 getSettings: () => (getSettings), 8642 getTemplate: () => (getTemplate), 8643 getTemplateLock: () => (getTemplateLock), 8644 hasBlockMovingClientId: () => (selectors_hasBlockMovingClientId), 8645 hasDraggedInnerBlock: () => (hasDraggedInnerBlock), 8646 hasInserterItems: () => (hasInserterItems), 8647 hasMultiSelection: () => (hasMultiSelection), 8648 hasSelectedBlock: () => (hasSelectedBlock), 8649 hasSelectedInnerBlock: () => (hasSelectedInnerBlock), 8650 isAncestorBeingDragged: () => (isAncestorBeingDragged), 8651 isAncestorMultiSelected: () => (isAncestorMultiSelected), 8652 isBlockBeingDragged: () => (isBlockBeingDragged), 8653 isBlockHighlighted: () => (isBlockHighlighted), 8654 isBlockInsertionPointVisible: () => (isBlockInsertionPointVisible), 8655 isBlockMultiSelected: () => (isBlockMultiSelected), 8656 isBlockSelected: () => (isBlockSelected), 8657 isBlockValid: () => (isBlockValid), 8658 isBlockVisible: () => (isBlockVisible), 8659 isBlockWithinSelection: () => (isBlockWithinSelection), 8660 isCaretWithinFormattedText: () => (isCaretWithinFormattedText), 8661 isDraggingBlocks: () => (isDraggingBlocks), 8662 isFirstMultiSelectedBlock: () => (isFirstMultiSelectedBlock), 8663 isGroupable: () => (isGroupable), 8664 isLastBlockChangePersistent: () => (isLastBlockChangePersistent), 8665 isMultiSelecting: () => (selectors_isMultiSelecting), 8666 isNavigationMode: () => (isNavigationMode), 8667 isSelectionEnabled: () => (selectors_isSelectionEnabled), 8668 isTyping: () => (selectors_isTyping), 8669 isUngroupable: () => (isUngroupable), 8670 isValidTemplate: () => (isValidTemplate), 8671 wasBlockJustInserted: () => (wasBlockJustInserted) 8672 }); 8673 8674 // NAMESPACE OBJECT: ./node_modules/@wordpress/block-editor/build-module/store/private-actions.js 8675 var private_actions_namespaceObject = {}; 8676 __webpack_require__.r(private_actions_namespaceObject); 8677 __webpack_require__.d(private_actions_namespaceObject, { 8678 __experimentalUpdateSettings: () => (__experimentalUpdateSettings), 8679 clearBlockRemovalPrompt: () => (clearBlockRemovalPrompt), 8680 deleteStyleOverride: () => (deleteStyleOverride), 8681 ensureDefaultBlock: () => (ensureDefaultBlock), 8682 hideBlockInterface: () => (hideBlockInterface), 8683 privateRemoveBlocks: () => (privateRemoveBlocks), 8684 setBlockRemovalRules: () => (setBlockRemovalRules), 8685 setLastFocus: () => (setLastFocus), 8686 setOpenedBlockSettingsMenu: () => (setOpenedBlockSettingsMenu), 8687 setStyleOverride: () => (setStyleOverride), 8688 showBlockInterface: () => (showBlockInterface), 8689 startDragging: () => (startDragging), 8690 stopDragging: () => (stopDragging), 8691 stopEditingAsBlocks: () => (stopEditingAsBlocks), 8692 syncDerivedUpdates: () => (syncDerivedUpdates) 8693 }); 8694 8695 // NAMESPACE OBJECT: ./node_modules/@wordpress/block-editor/build-module/store/private-selectors.js 8696 var private_selectors_namespaceObject = {}; 8697 __webpack_require__.r(private_selectors_namespaceObject); 8698 __webpack_require__.d(private_selectors_namespaceObject, { 8699 getAllPatterns: () => (getAllPatterns), 8700 getBlockRemovalRules: () => (getBlockRemovalRules), 8701 getBlockSettings: () => (getBlockSettings), 8702 getBlockWithoutAttributes: () => (getBlockWithoutAttributes), 8703 getEnabledBlockParents: () => (getEnabledBlockParents), 8704 getEnabledClientIdsTree: () => (getEnabledClientIdsTree), 8705 getInserterMediaCategories: () => (getInserterMediaCategories), 8706 getLastFocus: () => (getLastFocus), 8707 getLastInsertedBlocksClientIds: () => (getLastInsertedBlocksClientIds), 8708 getOpenedBlockSettingsMenu: () => (getOpenedBlockSettingsMenu), 8709 getRegisteredInserterMediaCategories: () => (getRegisteredInserterMediaCategories), 8710 getRemovalPromptData: () => (getRemovalPromptData), 8711 getStyleOverrides: () => (getStyleOverrides), 8712 hasAllowedPatterns: () => (hasAllowedPatterns), 8713 isBlockInterfaceHidden: () => (private_selectors_isBlockInterfaceHidden), 8714 isBlockSubtreeDisabled: () => (isBlockSubtreeDisabled), 8715 isDragging: () => (private_selectors_isDragging) 8716 }); 8717 8718 // NAMESPACE OBJECT: ./node_modules/@wordpress/block-editor/build-module/store/actions.js 8719 var actions_namespaceObject = {}; 8720 __webpack_require__.r(actions_namespaceObject); 8721 __webpack_require__.d(actions_namespaceObject, { 8722 __unstableDeleteSelection: () => (__unstableDeleteSelection), 8723 __unstableExpandSelection: () => (__unstableExpandSelection), 8724 __unstableMarkAutomaticChange: () => (__unstableMarkAutomaticChange), 8725 __unstableMarkLastChangeAsPersistent: () => (__unstableMarkLastChangeAsPersistent), 8726 __unstableMarkNextChangeAsNotPersistent: () => (__unstableMarkNextChangeAsNotPersistent), 8727 __unstableSaveReusableBlock: () => (__unstableSaveReusableBlock), 8728 __unstableSetEditorMode: () => (__unstableSetEditorMode), 8729 __unstableSetTemporarilyEditingAsBlocks: () => (__unstableSetTemporarilyEditingAsBlocks), 8730 __unstableSplitSelection: () => (__unstableSplitSelection), 8731 clearSelectedBlock: () => (clearSelectedBlock), 8732 duplicateBlocks: () => (duplicateBlocks), 8733 enterFormattedText: () => (enterFormattedText), 8734 exitFormattedText: () => (exitFormattedText), 8735 flashBlock: () => (flashBlock), 8736 hideInsertionPoint: () => (hideInsertionPoint), 8737 insertAfterBlock: () => (insertAfterBlock), 8738 insertBeforeBlock: () => (insertBeforeBlock), 8739 insertBlock: () => (insertBlock), 8740 insertBlocks: () => (insertBlocks), 8741 insertDefaultBlock: () => (insertDefaultBlock), 8742 mergeBlocks: () => (mergeBlocks), 8743 moveBlockToPosition: () => (moveBlockToPosition), 8744 moveBlocksDown: () => (moveBlocksDown), 8745 moveBlocksToPosition: () => (moveBlocksToPosition), 8746 moveBlocksUp: () => (moveBlocksUp), 8747 multiSelect: () => (multiSelect), 8748 receiveBlocks: () => (receiveBlocks), 8749 registerInserterMediaCategory: () => (registerInserterMediaCategory), 8750 removeBlock: () => (removeBlock), 8751 removeBlocks: () => (removeBlocks), 8752 replaceBlock: () => (replaceBlock), 8753 replaceBlocks: () => (replaceBlocks), 8754 replaceInnerBlocks: () => (replaceInnerBlocks), 8755 resetBlocks: () => (resetBlocks), 8756 resetSelection: () => (resetSelection), 8757 selectBlock: () => (selectBlock), 8758 selectNextBlock: () => (selectNextBlock), 8759 selectPreviousBlock: () => (selectPreviousBlock), 8760 selectionChange: () => (selectionChange), 8761 setBlockEditingMode: () => (setBlockEditingMode), 8762 setBlockMovingClientId: () => (setBlockMovingClientId), 8763 setBlockVisibility: () => (setBlockVisibility), 8764 setHasControlledInnerBlocks: () => (setHasControlledInnerBlocks), 8765 setNavigationMode: () => (setNavigationMode), 8766 setTemplateValidity: () => (setTemplateValidity), 8767 showInsertionPoint: () => (showInsertionPoint), 8768 startDraggingBlocks: () => (startDraggingBlocks), 8769 startMultiSelect: () => (startMultiSelect), 8770 startTyping: () => (startTyping), 8771 stopDraggingBlocks: () => (stopDraggingBlocks), 8772 stopMultiSelect: () => (stopMultiSelect), 8773 stopTyping: () => (stopTyping), 8774 synchronizeTemplate: () => (synchronizeTemplate), 8775 toggleBlockHighlight: () => (toggleBlockHighlight), 8776 toggleBlockMode: () => (toggleBlockMode), 8777 toggleSelection: () => (toggleSelection), 8778 unsetBlockEditingMode: () => (unsetBlockEditingMode), 8779 updateBlock: () => (updateBlock), 8780 updateBlockAttributes: () => (updateBlockAttributes), 8781 updateBlockListSettings: () => (updateBlockListSettings), 8782 updateSettings: () => (updateSettings), 8783 validateBlocksToTemplate: () => (validateBlocksToTemplate) 8784 }); 8785 8786 // NAMESPACE OBJECT: ./node_modules/@wordpress/block-editor/build-module/components/global-styles/index.js 8787 var global_styles_namespaceObject = {}; 8788 __webpack_require__.r(global_styles_namespaceObject); 8789 __webpack_require__.d(global_styles_namespaceObject, { 8790 AdvancedPanel: () => (AdvancedPanel), 8791 BorderPanel: () => (BorderPanel), 8792 ColorPanel: () => (ColorPanel), 8793 DimensionsPanel: () => (DimensionsPanel), 8794 FiltersPanel: () => (FiltersPanel), 8795 GlobalStylesContext: () => (GlobalStylesContext), 8796 ImageSettingsPanel: () => (ImageSettingsPanel), 8797 TypographyPanel: () => (TypographyPanel), 8798 areGlobalStyleConfigsEqual: () => (areGlobalStyleConfigsEqual), 8799 getBlockCSSSelector: () => (getBlockCSSSelector), 8800 getGlobalStylesChanges: () => (getGlobalStylesChanges), 8801 getLayoutStyles: () => (getLayoutStyles), 8802 useGlobalSetting: () => (useGlobalSetting), 8803 useGlobalStyle: () => (useGlobalStyle), 8804 useGlobalStylesOutput: () => (useGlobalStylesOutput), 8805 useGlobalStylesOutputWithConfig: () => (useGlobalStylesOutputWithConfig), 8806 useGlobalStylesReset: () => (useGlobalStylesReset), 8807 useHasBorderPanel: () => (useHasBorderPanel), 8808 useHasBorderPanelControls: () => (useHasBorderPanelControls), 8809 useHasColorPanel: () => (useHasColorPanel), 8810 useHasDimensionsPanel: () => (useHasDimensionsPanel), 8811 useHasFiltersPanel: () => (useHasFiltersPanel), 8812 useHasImageSettingsPanel: () => (useHasImageSettingsPanel), 8813 useHasTypographyPanel: () => (useHasTypographyPanel), 8814 useSettingsForBlockElement: () => (useSettingsForBlockElement) 8815 }); 8816 8817 // EXTERNAL MODULE: external "React" 8818 var external_React_ = __webpack_require__(1609); 8819 var external_React_default = /*#__PURE__*/__webpack_require__.n(external_React_); 8820 ;// CONCATENATED MODULE: external ["wp","blocks"] 8821 const external_wp_blocks_namespaceObject = window["wp"]["blocks"]; 8822 ;// CONCATENATED MODULE: external ["wp","element"] 8823 const external_wp_element_namespaceObject = window["wp"]["element"]; 8824 ;// CONCATENATED MODULE: external ["wp","data"] 8825 const external_wp_data_namespaceObject = window["wp"]["data"]; 8826 ;// CONCATENATED MODULE: external ["wp","compose"] 8827 const external_wp_compose_namespaceObject = window["wp"]["compose"]; 8828 ;// CONCATENATED MODULE: external ["wp","hooks"] 8829 const external_wp_hooks_namespaceObject = window["wp"]["hooks"]; 8830 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-edit/context.js 8831 /** 8832 * WordPress dependencies 8833 */ 8834 8835 const mayDisplayControlsKey = Symbol('mayDisplayControls'); 8836 const mayDisplayParentControlsKey = Symbol('mayDisplayParentControls'); 8837 const blockEditingModeKey = Symbol('blockEditingMode'); 8838 const blockBindingsKey = Symbol('blockBindings'); 8839 const DEFAULT_BLOCK_EDIT_CONTEXT = { 8840 name: '', 8841 isSelected: false 8842 }; 8843 const Context = (0,external_wp_element_namespaceObject.createContext)(DEFAULT_BLOCK_EDIT_CONTEXT); 8844 const { 8845 Provider 8846 } = Context; 8847 8848 8849 /** 8850 * A hook that returns the block edit context. 8851 * 8852 * @return {Object} Block edit context 8853 */ 8854 function useBlockEditContext() { 8855 return (0,external_wp_element_namespaceObject.useContext)(Context); 8856 } 8857 8858 ;// CONCATENATED MODULE: external ["wp","deprecated"] 8859 const external_wp_deprecated_namespaceObject = window["wp"]["deprecated"]; 8860 var external_wp_deprecated_default = /*#__PURE__*/__webpack_require__.n(external_wp_deprecated_namespaceObject); 8861 // EXTERNAL MODULE: ./node_modules/fast-deep-equal/es6/index.js 8862 var es6 = __webpack_require__(7734); 8863 var es6_default = /*#__PURE__*/__webpack_require__.n(es6); 8864 ;// CONCATENATED MODULE: external ["wp","i18n"] 8865 const external_wp_i18n_namespaceObject = window["wp"]["i18n"]; 8866 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/store/defaults.js 8867 /** 8868 * WordPress dependencies 8869 */ 8870 8871 const PREFERENCES_DEFAULTS = { 8872 insertUsage: {} 8873 }; 8874 8875 /** 8876 * The default editor settings 8877 * 8878 * @typedef {Object} SETTINGS_DEFAULT 8879 * @property {boolean} alignWide Enable/Disable Wide/Full Alignments 8880 * @property {boolean} supportsLayout Enable/disable layouts support in container blocks. 8881 * @property {boolean} imageEditing Image Editing settings set to false to disable. 8882 * @property {Array} imageSizes Available image sizes 8883 * @property {number} maxWidth Max width to constraint resizing 8884 * @property {boolean|Array} allowedBlockTypes Allowed block types 8885 * @property {boolean} hasFixedToolbar Whether or not the editor toolbar is fixed 8886 * @property {boolean} distractionFree Whether or not the editor UI is distraction free 8887 * @property {boolean} focusMode Whether the focus mode is enabled or not 8888 * @property {Array} styles Editor Styles 8889 * @property {boolean} keepCaretInsideBlock Whether caret should move between blocks in edit mode 8890 * @property {string} bodyPlaceholder Empty post placeholder 8891 * @property {string} titlePlaceholder Empty title placeholder 8892 * @property {boolean} canLockBlocks Whether the user can manage Block Lock state 8893 * @property {boolean} codeEditingEnabled Whether or not the user can switch to the code editor 8894 * @property {boolean} generateAnchors Enable/Disable auto anchor generation for Heading blocks 8895 * @property {boolean} enableOpenverseMediaCategory Enable/Disable the Openverse media category in the inserter. 8896 * @property {boolean} clearBlockSelection Whether the block editor should clear selection on mousedown when a block is not clicked. 8897 * @property {boolean} __experimentalCanUserUseUnfilteredHTML Whether the user should be able to use unfiltered HTML or the HTML should be filtered e.g., to remove elements considered insecure like iframes. 8898 * @property {boolean} __experimentalBlockDirectory Whether the user has enabled the Block Directory 8899 * @property {Array} __experimentalBlockPatterns Array of objects representing the block patterns 8900 * @property {Array} __experimentalBlockPatternCategories Array of objects representing the block pattern categories 8901 * @property {boolean} __unstableGalleryWithImageBlocks Whether the user has enabled the refactored gallery block which uses InnerBlocks 8902 */ 8903 const SETTINGS_DEFAULTS = { 8904 alignWide: false, 8905 supportsLayout: true, 8906 // colors setting is not used anymore now defaults are passed from theme.json on the server and core has its own defaults. 8907 // The setting is only kept for backward compatibility purposes. 8908 colors: [{ 8909 name: (0,external_wp_i18n_namespaceObject.__)('Black'), 8910 slug: 'black', 8911 color: '#000000' 8912 }, { 8913 name: (0,external_wp_i18n_namespaceObject.__)('Cyan bluish gray'), 8914 slug: 'cyan-bluish-gray', 8915 color: '#abb8c3' 8916 }, { 8917 name: (0,external_wp_i18n_namespaceObject.__)('White'), 8918 slug: 'white', 8919 color: '#ffffff' 8920 }, { 8921 name: (0,external_wp_i18n_namespaceObject.__)('Pale pink'), 8922 slug: 'pale-pink', 8923 color: '#f78da7' 8924 }, { 8925 name: (0,external_wp_i18n_namespaceObject.__)('Vivid red'), 8926 slug: 'vivid-red', 8927 color: '#cf2e2e' 8928 }, { 8929 name: (0,external_wp_i18n_namespaceObject.__)('Luminous vivid orange'), 8930 slug: 'luminous-vivid-orange', 8931 color: '#ff6900' 8932 }, { 8933 name: (0,external_wp_i18n_namespaceObject.__)('Luminous vivid amber'), 8934 slug: 'luminous-vivid-amber', 8935 color: '#fcb900' 8936 }, { 8937 name: (0,external_wp_i18n_namespaceObject.__)('Light green cyan'), 8938 slug: 'light-green-cyan', 8939 color: '#7bdcb5' 8940 }, { 8941 name: (0,external_wp_i18n_namespaceObject.__)('Vivid green cyan'), 8942 slug: 'vivid-green-cyan', 8943 color: '#00d084' 8944 }, { 8945 name: (0,external_wp_i18n_namespaceObject.__)('Pale cyan blue'), 8946 slug: 'pale-cyan-blue', 8947 color: '#8ed1fc' 8948 }, { 8949 name: (0,external_wp_i18n_namespaceObject.__)('Vivid cyan blue'), 8950 slug: 'vivid-cyan-blue', 8951 color: '#0693e3' 8952 }, { 8953 name: (0,external_wp_i18n_namespaceObject.__)('Vivid purple'), 8954 slug: 'vivid-purple', 8955 color: '#9b51e0' 8956 }], 8957 // fontSizes setting is not used anymore now defaults are passed from theme.json on the server and core has its own defaults. 8958 // The setting is only kept for backward compatibility purposes. 8959 fontSizes: [{ 8960 name: (0,external_wp_i18n_namespaceObject._x)('Small', 'font size name'), 8961 size: 13, 8962 slug: 'small' 8963 }, { 8964 name: (0,external_wp_i18n_namespaceObject._x)('Normal', 'font size name'), 8965 size: 16, 8966 slug: 'normal' 8967 }, { 8968 name: (0,external_wp_i18n_namespaceObject._x)('Medium', 'font size name'), 8969 size: 20, 8970 slug: 'medium' 8971 }, { 8972 name: (0,external_wp_i18n_namespaceObject._x)('Large', 'font size name'), 8973 size: 36, 8974 slug: 'large' 8975 }, { 8976 name: (0,external_wp_i18n_namespaceObject._x)('Huge', 'font size name'), 8977 size: 42, 8978 slug: 'huge' 8979 }], 8980 // Image default size slug. 8981 imageDefaultSize: 'large', 8982 imageSizes: [{ 8983 slug: 'thumbnail', 8984 name: (0,external_wp_i18n_namespaceObject.__)('Thumbnail') 8985 }, { 8986 slug: 'medium', 8987 name: (0,external_wp_i18n_namespaceObject.__)('Medium') 8988 }, { 8989 slug: 'large', 8990 name: (0,external_wp_i18n_namespaceObject.__)('Large') 8991 }, { 8992 slug: 'full', 8993 name: (0,external_wp_i18n_namespaceObject.__)('Full Size') 8994 }], 8995 // Allow plugin to disable Image Editor if need be. 8996 imageEditing: true, 8997 // This is current max width of the block inner area 8998 // It's used to constraint image resizing and this value could be overridden later by themes 8999 maxWidth: 580, 9000 // Allowed block types for the editor, defaulting to true (all supported). 9001 allowedBlockTypes: true, 9002 // Maximum upload size in bytes allowed for the site. 9003 maxUploadFileSize: 0, 9004 // List of allowed mime types and file extensions. 9005 allowedMimeTypes: null, 9006 // Allows to disable block locking interface. 9007 canLockBlocks: true, 9008 // Allows to disable Openverse media category in the inserter. 9009 enableOpenverseMediaCategory: true, 9010 clearBlockSelection: true, 9011 __experimentalCanUserUseUnfilteredHTML: false, 9012 __experimentalBlockDirectory: false, 9013 __mobileEnablePageTemplates: false, 9014 __experimentalBlockPatterns: [], 9015 __experimentalBlockPatternCategories: [], 9016 __unstableGalleryWithImageBlocks: false, 9017 __unstableIsPreviewMode: false, 9018 // These settings will be completely revamped in the future. 9019 // The goal is to evolve this into an API which will instruct 9020 // the block inspector to animate transitions between what it 9021 // displays based on the relationship between the selected block 9022 // and its parent, and only enable it if the parent is controlling 9023 // its children blocks. 9024 blockInspectorAnimation: { 9025 animationParent: 'core/navigation', 9026 'core/navigation': { 9027 enterDirection: 'leftToRight' 9028 }, 9029 'core/navigation-submenu': { 9030 enterDirection: 'rightToLeft' 9031 }, 9032 'core/navigation-link': { 9033 enterDirection: 'rightToLeft' 9034 }, 9035 'core/search': { 9036 enterDirection: 'rightToLeft' 9037 }, 9038 'core/social-links': { 9039 enterDirection: 'rightToLeft' 9040 }, 9041 'core/page-list': { 9042 enterDirection: 'rightToLeft' 9043 }, 9044 'core/spacer': { 9045 enterDirection: 'rightToLeft' 9046 }, 9047 'core/home-link': { 9048 enterDirection: 'rightToLeft' 9049 }, 9050 'core/site-title': { 9051 enterDirection: 'rightToLeft' 9052 }, 9053 'core/site-logo': { 9054 enterDirection: 'rightToLeft' 9055 } 9056 }, 9057 generateAnchors: false, 9058 // gradients setting is not used anymore now defaults are passed from theme.json on the server and core has its own defaults. 9059 // The setting is only kept for backward compatibility purposes. 9060 gradients: [{ 9061 name: (0,external_wp_i18n_namespaceObject.__)('Vivid cyan blue to vivid purple'), 9062 gradient: 'linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)', 9063 slug: 'vivid-cyan-blue-to-vivid-purple' 9064 }, { 9065 name: (0,external_wp_i18n_namespaceObject.__)('Light green cyan to vivid green cyan'), 9066 gradient: 'linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%)', 9067 slug: 'light-green-cyan-to-vivid-green-cyan' 9068 }, { 9069 name: (0,external_wp_i18n_namespaceObject.__)('Luminous vivid amber to luminous vivid orange'), 9070 gradient: 'linear-gradient(135deg,rgba(252,185,0,1) 0%,rgba(255,105,0,1) 100%)', 9071 slug: 'luminous-vivid-amber-to-luminous-vivid-orange' 9072 }, { 9073 name: (0,external_wp_i18n_namespaceObject.__)('Luminous vivid orange to vivid red'), 9074 gradient: 'linear-gradient(135deg,rgba(255,105,0,1) 0%,rgb(207,46,46) 100%)', 9075 slug: 'luminous-vivid-orange-to-vivid-red' 9076 }, { 9077 name: (0,external_wp_i18n_namespaceObject.__)('Very light gray to cyan bluish gray'), 9078 gradient: 'linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%)', 9079 slug: 'very-light-gray-to-cyan-bluish-gray' 9080 }, { 9081 name: (0,external_wp_i18n_namespaceObject.__)('Cool to warm spectrum'), 9082 gradient: 'linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%)', 9083 slug: 'cool-to-warm-spectrum' 9084 }, { 9085 name: (0,external_wp_i18n_namespaceObject.__)('Blush light purple'), 9086 gradient: 'linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%)', 9087 slug: 'blush-light-purple' 9088 }, { 9089 name: (0,external_wp_i18n_namespaceObject.__)('Blush bordeaux'), 9090 gradient: 'linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%)', 9091 slug: 'blush-bordeaux' 9092 }, { 9093 name: (0,external_wp_i18n_namespaceObject.__)('Luminous dusk'), 9094 gradient: 'linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)', 9095 slug: 'luminous-dusk' 9096 }, { 9097 name: (0,external_wp_i18n_namespaceObject.__)('Pale ocean'), 9098 gradient: 'linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%)', 9099 slug: 'pale-ocean' 9100 }, { 9101 name: (0,external_wp_i18n_namespaceObject.__)('Electric grass'), 9102 gradient: 'linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%)', 9103 slug: 'electric-grass' 9104 }, { 9105 name: (0,external_wp_i18n_namespaceObject.__)('Midnight'), 9106 gradient: 'linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%)', 9107 slug: 'midnight' 9108 }], 9109 __unstableResolvedAssets: { 9110 styles: [], 9111 scripts: [] 9112 } 9113 }; 9114 9115 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/store/array.js 9116 /** 9117 * Insert one or multiple elements into a given position of an array. 9118 * 9119 * @param {Array} array Source array. 9120 * @param {*} elements Elements to insert. 9121 * @param {number} index Insert Position. 9122 * 9123 * @return {Array} Result. 9124 */ 9125 function insertAt(array, elements, index) { 9126 return [...array.slice(0, index), ...(Array.isArray(elements) ? elements : [elements]), ...array.slice(index)]; 9127 } 9128 9129 /** 9130 * Moves an element in an array. 9131 * 9132 * @param {Array} array Source array. 9133 * @param {number} from Source index. 9134 * @param {number} to Destination index. 9135 * @param {number} count Number of elements to move. 9136 * 9137 * @return {Array} Result. 9138 */ 9139 function moveTo(array, from, to, count = 1) { 9140 const withoutMovedElements = [...array]; 9141 withoutMovedElements.splice(from, count); 9142 return insertAt(withoutMovedElements, array.slice(from, from + count), to); 9143 } 9144 9145 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/store/reducer.js 9146 /** 9147 * External dependencies 9148 */ 9149 9150 9151 /** 9152 * WordPress dependencies 9153 */ 9154 9155 9156 9157 /** 9158 * Internal dependencies 9159 */ 9160 9161 9162 const identity = x => x; 9163 9164 /** 9165 * Given an array of blocks, returns an object where each key is a nesting 9166 * context, the value of which is an array of block client IDs existing within 9167 * that nesting context. 9168 * 9169 * @param {Array} blocks Blocks to map. 9170 * @param {?string} rootClientId Assumed root client ID. 9171 * 9172 * @return {Object} Block order map object. 9173 */ 9174 function mapBlockOrder(blocks, rootClientId = '') { 9175 const result = new Map(); 9176 const current = []; 9177 result.set(rootClientId, current); 9178 blocks.forEach(block => { 9179 const { 9180 clientId, 9181 innerBlocks 9182 } = block; 9183 current.push(clientId); 9184 mapBlockOrder(innerBlocks, clientId).forEach((order, subClientId) => { 9185 result.set(subClientId, order); 9186 }); 9187 }); 9188 return result; 9189 } 9190 9191 /** 9192 * Given an array of blocks, returns an object where each key contains 9193 * the clientId of the block and the value is the parent of the block. 9194 * 9195 * @param {Array} blocks Blocks to map. 9196 * @param {?string} rootClientId Assumed root client ID. 9197 * 9198 * @return {Object} Block order map object. 9199 */ 9200 function mapBlockParents(blocks, rootClientId = '') { 9201 const result = []; 9202 const stack = [[rootClientId, blocks]]; 9203 while (stack.length) { 9204 const [parent, currentBlocks] = stack.shift(); 9205 currentBlocks.forEach(({ 9206 innerBlocks, 9207 ...block 9208 }) => { 9209 result.push([block.clientId, parent]); 9210 if (innerBlocks?.length) { 9211 stack.push([block.clientId, innerBlocks]); 9212 } 9213 }); 9214 } 9215 return result; 9216 } 9217 9218 /** 9219 * Helper method to iterate through all blocks, recursing into inner blocks, 9220 * applying a transformation function to each one. 9221 * Returns a flattened object with the transformed blocks. 9222 * 9223 * @param {Array} blocks Blocks to flatten. 9224 * @param {Function} transform Transforming function to be applied to each block. 9225 * 9226 * @return {Array} Flattened object. 9227 */ 9228 function flattenBlocks(blocks, transform = identity) { 9229 const result = []; 9230 const stack = [...blocks]; 9231 while (stack.length) { 9232 const { 9233 innerBlocks, 9234 ...block 9235 } = stack.shift(); 9236 stack.push(...innerBlocks); 9237 result.push([block.clientId, transform(block)]); 9238 } 9239 return result; 9240 } 9241 function getFlattenedClientIds(blocks) { 9242 const result = {}; 9243 const stack = [...blocks]; 9244 while (stack.length) { 9245 const { 9246 innerBlocks, 9247 ...block 9248 } = stack.shift(); 9249 stack.push(...innerBlocks); 9250 result[block.clientId] = true; 9251 } 9252 return result; 9253 } 9254 9255 /** 9256 * Given an array of blocks, returns an object containing all blocks, without 9257 * attributes, recursing into inner blocks. Keys correspond to the block client 9258 * ID, the value of which is the attributes object. 9259 * 9260 * @param {Array} blocks Blocks to flatten. 9261 * 9262 * @return {Array} Flattened block attributes object. 9263 */ 9264 function getFlattenedBlocksWithoutAttributes(blocks) { 9265 return flattenBlocks(blocks, block => { 9266 const { 9267 attributes, 9268 ...restBlock 9269 } = block; 9270 return restBlock; 9271 }); 9272 } 9273 9274 /** 9275 * Given an array of blocks, returns an object containing all block attributes, 9276 * recursing into inner blocks. Keys correspond to the block client ID, the 9277 * value of which is the attributes object. 9278 * 9279 * @param {Array} blocks Blocks to flatten. 9280 * 9281 * @return {Array} Flattened block attributes object. 9282 */ 9283 function getFlattenedBlockAttributes(blocks) { 9284 return flattenBlocks(blocks, block => block.attributes); 9285 } 9286 9287 /** 9288 * Returns true if the two object arguments have the same keys, or false 9289 * otherwise. 9290 * 9291 * @param {Object} a First object. 9292 * @param {Object} b Second object. 9293 * 9294 * @return {boolean} Whether the two objects have the same keys. 9295 */ 9296 function hasSameKeys(a, b) { 9297 return es6_default()(Object.keys(a), Object.keys(b)); 9298 } 9299 9300 /** 9301 * Returns true if, given the currently dispatching action and the previously 9302 * dispatched action, the two actions are updating the same block attribute, or 9303 * false otherwise. 9304 * 9305 * @param {Object} action Currently dispatching action. 9306 * @param {Object} lastAction Previously dispatched action. 9307 * 9308 * @return {boolean} Whether actions are updating the same block attribute. 9309 */ 9310 function isUpdatingSameBlockAttribute(action, lastAction) { 9311 return action.type === 'UPDATE_BLOCK_ATTRIBUTES' && lastAction !== undefined && lastAction.type === 'UPDATE_BLOCK_ATTRIBUTES' && es6_default()(action.clientIds, lastAction.clientIds) && hasSameKeys(action.attributes, lastAction.attributes); 9312 } 9313 function updateBlockTreeForBlocks(state, blocks) { 9314 const treeToUpdate = state.tree; 9315 const stack = [...blocks]; 9316 const flattenedBlocks = [...blocks]; 9317 while (stack.length) { 9318 const block = stack.shift(); 9319 stack.push(...block.innerBlocks); 9320 flattenedBlocks.push(...block.innerBlocks); 9321 } 9322 // Create objects before mutating them, that way it's always defined. 9323 for (const block of flattenedBlocks) { 9324 treeToUpdate.set(block.clientId, {}); 9325 } 9326 for (const block of flattenedBlocks) { 9327 treeToUpdate.set(block.clientId, Object.assign(treeToUpdate.get(block.clientId), { 9328 ...state.byClientId.get(block.clientId), 9329 attributes: state.attributes.get(block.clientId), 9330 innerBlocks: block.innerBlocks.map(subBlock => treeToUpdate.get(subBlock.clientId)) 9331 })); 9332 } 9333 } 9334 function updateParentInnerBlocksInTree(state, updatedClientIds, updateChildrenOfUpdatedClientIds = false) { 9335 const treeToUpdate = state.tree; 9336 const uncontrolledParents = new Set([]); 9337 const controlledParents = new Set(); 9338 for (const clientId of updatedClientIds) { 9339 let current = updateChildrenOfUpdatedClientIds ? clientId : state.parents.get(clientId); 9340 do { 9341 if (state.controlledInnerBlocks[current]) { 9342 // Should stop on controlled blocks. 9343 // If we reach a controlled parent, break out of the loop. 9344 controlledParents.add(current); 9345 break; 9346 } else { 9347 // Else continue traversing up through parents. 9348 uncontrolledParents.add(current); 9349 current = state.parents.get(current); 9350 } 9351 } while (current !== undefined); 9352 } 9353 9354 // To make sure the order of assignments doesn't matter, 9355 // we first create empty objects and mutates the inner blocks later. 9356 for (const clientId of uncontrolledParents) { 9357 treeToUpdate.set(clientId, { 9358 ...treeToUpdate.get(clientId) 9359 }); 9360 } 9361 for (const clientId of uncontrolledParents) { 9362 treeToUpdate.get(clientId).innerBlocks = (state.order.get(clientId) || []).map(subClientId => treeToUpdate.get(subClientId)); 9363 } 9364 9365 // Controlled parent blocks, need a dedicated key for their inner blocks 9366 // to be used when doing getBlocks( controlledBlockClientId ). 9367 for (const clientId of controlledParents) { 9368 treeToUpdate.set('controlled||' + clientId, { 9369 innerBlocks: (state.order.get(clientId) || []).map(subClientId => treeToUpdate.get(subClientId)) 9370 }); 9371 } 9372 } 9373 9374 /** 9375 * Higher-order reducer intended to compute full block objects key for each block in the post. 9376 * This is a denormalization to optimize the performance of the getBlock selectors and avoid 9377 * recomputing the block objects and avoid heavy memoization. 9378 * 9379 * @param {Function} reducer Original reducer function. 9380 * 9381 * @return {Function} Enhanced reducer function. 9382 */ 9383 const withBlockTree = reducer => (state = {}, action) => { 9384 const newState = reducer(state, action); 9385 if (newState === state) { 9386 return state; 9387 } 9388 newState.tree = state.tree ? state.tree : new Map(); 9389 switch (action.type) { 9390 case 'RECEIVE_BLOCKS': 9391 case 'INSERT_BLOCKS': 9392 { 9393 newState.tree = new Map(newState.tree); 9394 updateBlockTreeForBlocks(newState, action.blocks); 9395 updateParentInnerBlocksInTree(newState, action.rootClientId ? [action.rootClientId] : [''], true); 9396 break; 9397 } 9398 case 'UPDATE_BLOCK': 9399 newState.tree = new Map(newState.tree); 9400 newState.tree.set(action.clientId, { 9401 ...newState.tree.get(action.clientId), 9402 ...newState.byClientId.get(action.clientId), 9403 attributes: newState.attributes.get(action.clientId) 9404 }); 9405 updateParentInnerBlocksInTree(newState, [action.clientId], false); 9406 break; 9407 case 'SYNC_DERIVED_BLOCK_ATTRIBUTES': 9408 case 'UPDATE_BLOCK_ATTRIBUTES': 9409 { 9410 newState.tree = new Map(newState.tree); 9411 action.clientIds.forEach(clientId => { 9412 newState.tree.set(clientId, { 9413 ...newState.tree.get(clientId), 9414 attributes: newState.attributes.get(clientId) 9415 }); 9416 }); 9417 updateParentInnerBlocksInTree(newState, action.clientIds, false); 9418 break; 9419 } 9420 case 'REPLACE_BLOCKS_AUGMENTED_WITH_CHILDREN': 9421 { 9422 const inserterClientIds = getFlattenedClientIds(action.blocks); 9423 newState.tree = new Map(newState.tree); 9424 action.replacedClientIds.concat( 9425 // Controlled inner blocks are only removed 9426 // if the block doesn't move to another position 9427 // otherwise their content will be lost. 9428 action.replacedClientIds.filter(clientId => !inserterClientIds[clientId]).map(clientId => 'controlled||' + clientId)).forEach(key => { 9429 newState.tree.delete(key); 9430 }); 9431 updateBlockTreeForBlocks(newState, action.blocks); 9432 updateParentInnerBlocksInTree(newState, action.blocks.map(b => b.clientId), false); 9433 9434 // If there are no replaced blocks, it means we're removing blocks so we need to update their parent. 9435 const parentsOfRemovedBlocks = []; 9436 for (const clientId of action.clientIds) { 9437 if (state.parents.get(clientId) !== undefined && (state.parents.get(clientId) === '' || newState.byClientId.get(state.parents.get(clientId)))) { 9438 parentsOfRemovedBlocks.push(state.parents.get(clientId)); 9439 } 9440 } 9441 updateParentInnerBlocksInTree(newState, parentsOfRemovedBlocks, true); 9442 break; 9443 } 9444 case 'REMOVE_BLOCKS_AUGMENTED_WITH_CHILDREN': 9445 const parentsOfRemovedBlocks = []; 9446 for (const clientId of action.clientIds) { 9447 if (state.parents.get(clientId) !== undefined && (state.parents.get(clientId) === '' || newState.byClientId.get(state.parents.get(clientId)))) { 9448 parentsOfRemovedBlocks.push(state.parents.get(clientId)); 9449 } 9450 } 9451 newState.tree = new Map(newState.tree); 9452 action.removedClientIds.concat(action.removedClientIds.map(clientId => 'controlled||' + clientId)).forEach(key => { 9453 newState.tree.delete(key); 9454 }); 9455 updateParentInnerBlocksInTree(newState, parentsOfRemovedBlocks, true); 9456 break; 9457 case 'MOVE_BLOCKS_TO_POSITION': 9458 { 9459 const updatedBlockUids = []; 9460 if (action.fromRootClientId) { 9461 updatedBlockUids.push(action.fromRootClientId); 9462 } else { 9463 updatedBlockUids.push(''); 9464 } 9465 if (action.toRootClientId) { 9466 updatedBlockUids.push(action.toRootClientId); 9467 } 9468 newState.tree = new Map(newState.tree); 9469 updateParentInnerBlocksInTree(newState, updatedBlockUids, true); 9470 break; 9471 } 9472 case 'MOVE_BLOCKS_UP': 9473 case 'MOVE_BLOCKS_DOWN': 9474 { 9475 const updatedBlockUids = [action.rootClientId ? action.rootClientId : '']; 9476 newState.tree = new Map(newState.tree); 9477 updateParentInnerBlocksInTree(newState, updatedBlockUids, true); 9478 break; 9479 } 9480 case 'SAVE_REUSABLE_BLOCK_SUCCESS': 9481 { 9482 const updatedBlockUids = []; 9483 newState.attributes.forEach((attributes, clientId) => { 9484 if (newState.byClientId.get(clientId).name === 'core/block' && attributes.ref === action.updatedId) { 9485 updatedBlockUids.push(clientId); 9486 } 9487 }); 9488 newState.tree = new Map(newState.tree); 9489 updatedBlockUids.forEach(clientId => { 9490 newState.tree.set(clientId, { 9491 ...newState.byClientId.get(clientId), 9492 attributes: newState.attributes.get(clientId), 9493 innerBlocks: newState.tree.get(clientId).innerBlocks 9494 }); 9495 }); 9496 updateParentInnerBlocksInTree(newState, updatedBlockUids, false); 9497 } 9498 } 9499 return newState; 9500 }; 9501 9502 /** 9503 * Higher-order reducer intended to augment the blocks reducer, assigning an 9504 * `isPersistentChange` property value corresponding to whether a change in 9505 * state can be considered as persistent. All changes are considered persistent 9506 * except when updating the same block attribute as in the previous action. 9507 * 9508 * @param {Function} reducer Original reducer function. 9509 * 9510 * @return {Function} Enhanced reducer function. 9511 */ 9512 function withPersistentBlockChange(reducer) { 9513 let lastAction; 9514 let markNextChangeAsNotPersistent = false; 9515 let explicitPersistent; 9516 return (state, action) => { 9517 let nextState = reducer(state, action); 9518 let nextIsPersistentChange; 9519 if (action.type === 'SET_EXPLICIT_PERSISTENT') { 9520 var _state$isPersistentCh; 9521 explicitPersistent = action.isPersistentChange; 9522 nextIsPersistentChange = (_state$isPersistentCh = state.isPersistentChange) !== null && _state$isPersistentCh !== void 0 ? _state$isPersistentCh : true; 9523 } 9524 if (explicitPersistent !== undefined) { 9525 nextIsPersistentChange = explicitPersistent; 9526 return nextIsPersistentChange === nextState.isPersistentChange ? nextState : { 9527 ...nextState, 9528 isPersistentChange: nextIsPersistentChange 9529 }; 9530 } 9531 const isExplicitPersistentChange = action.type === 'MARK_LAST_CHANGE_AS_PERSISTENT' || markNextChangeAsNotPersistent; 9532 9533 // Defer to previous state value (or default) unless changing or 9534 // explicitly marking as persistent. 9535 if (state === nextState && !isExplicitPersistentChange) { 9536 var _state$isPersistentCh2; 9537 markNextChangeAsNotPersistent = action.type === 'MARK_NEXT_CHANGE_AS_NOT_PERSISTENT'; 9538 nextIsPersistentChange = (_state$isPersistentCh2 = state?.isPersistentChange) !== null && _state$isPersistentCh2 !== void 0 ? _state$isPersistentCh2 : true; 9539 if (state.isPersistentChange === nextIsPersistentChange) { 9540 return state; 9541 } 9542 return { 9543 ...nextState, 9544 isPersistentChange: nextIsPersistentChange 9545 }; 9546 } 9547 nextState = { 9548 ...nextState, 9549 isPersistentChange: isExplicitPersistentChange ? !markNextChangeAsNotPersistent : !isUpdatingSameBlockAttribute(action, lastAction) 9550 }; 9551 9552 // In comparing against the previous action, consider only those which 9553 // would have qualified as one which would have been ignored or not 9554 // have resulted in a changed state. 9555 lastAction = action; 9556 markNextChangeAsNotPersistent = action.type === 'MARK_NEXT_CHANGE_AS_NOT_PERSISTENT'; 9557 return nextState; 9558 }; 9559 } 9560 9561 /** 9562 * Higher-order reducer intended to augment the blocks reducer, assigning an 9563 * `isIgnoredChange` property value corresponding to whether a change in state 9564 * can be considered as ignored. A change is considered ignored when the result 9565 * of an action not incurred by direct user interaction. 9566 * 9567 * @param {Function} reducer Original reducer function. 9568 * 9569 * @return {Function} Enhanced reducer function. 9570 */ 9571 function withIgnoredBlockChange(reducer) { 9572 /** 9573 * Set of action types for which a blocks state change should be ignored. 9574 * 9575 * @type {Set} 9576 */ 9577 const IGNORED_ACTION_TYPES = new Set(['RECEIVE_BLOCKS']); 9578 return (state, action) => { 9579 const nextState = reducer(state, action); 9580 if (nextState !== state) { 9581 nextState.isIgnoredChange = IGNORED_ACTION_TYPES.has(action.type); 9582 } 9583 return nextState; 9584 }; 9585 } 9586 9587 /** 9588 * Higher-order reducer targeting the combined blocks reducer, augmenting 9589 * block client IDs in remove action to include cascade of inner blocks. 9590 * 9591 * @param {Function} reducer Original reducer function. 9592 * 9593 * @return {Function} Enhanced reducer function. 9594 */ 9595 const withInnerBlocksRemoveCascade = reducer => (state, action) => { 9596 // Gets all children which need to be removed. 9597 const getAllChildren = clientIds => { 9598 let result = clientIds; 9599 for (let i = 0; i < result.length; i++) { 9600 if (!state.order.get(result[i]) || action.keepControlledInnerBlocks && action.keepControlledInnerBlocks[result[i]]) { 9601 continue; 9602 } 9603 if (result === clientIds) { 9604 result = [...result]; 9605 } 9606 result.push(...state.order.get(result[i])); 9607 } 9608 return result; 9609 }; 9610 if (state) { 9611 switch (action.type) { 9612 case 'REMOVE_BLOCKS': 9613 action = { 9614 ...action, 9615 type: 'REMOVE_BLOCKS_AUGMENTED_WITH_CHILDREN', 9616 removedClientIds: getAllChildren(action.clientIds) 9617 }; 9618 break; 9619 case 'REPLACE_BLOCKS': 9620 action = { 9621 ...action, 9622 type: 'REPLACE_BLOCKS_AUGMENTED_WITH_CHILDREN', 9623 replacedClientIds: getAllChildren(action.clientIds) 9624 }; 9625 break; 9626 } 9627 } 9628 return reducer(state, action); 9629 }; 9630 9631 /** 9632 * Higher-order reducer which targets the combined blocks reducer and handles 9633 * the `RESET_BLOCKS` action. When dispatched, this action will replace all 9634 * blocks that exist in the post, leaving blocks that exist only in state (e.g. 9635 * reusable blocks and blocks controlled by inner blocks controllers) alone. 9636 * 9637 * @param {Function} reducer Original reducer function. 9638 * 9639 * @return {Function} Enhanced reducer function. 9640 */ 9641 const withBlockReset = reducer => (state, action) => { 9642 if (action.type === 'RESET_BLOCKS') { 9643 const newState = { 9644 ...state, 9645 byClientId: new Map(getFlattenedBlocksWithoutAttributes(action.blocks)), 9646 attributes: new Map(getFlattenedBlockAttributes(action.blocks)), 9647 order: mapBlockOrder(action.blocks), 9648 parents: new Map(mapBlockParents(action.blocks)), 9649 controlledInnerBlocks: {} 9650 }; 9651 newState.tree = new Map(state?.tree); 9652 updateBlockTreeForBlocks(newState, action.blocks); 9653 newState.tree.set('', { 9654 innerBlocks: action.blocks.map(subBlock => newState.tree.get(subBlock.clientId)) 9655 }); 9656 return newState; 9657 } 9658 return reducer(state, action); 9659 }; 9660 9661 /** 9662 * Higher-order reducer which targets the combined blocks reducer and handles 9663 * the `REPLACE_INNER_BLOCKS` action. When dispatched, this action the state 9664 * should become equivalent to the execution of a `REMOVE_BLOCKS` action 9665 * containing all the child's of the root block followed by the execution of 9666 * `INSERT_BLOCKS` with the new blocks. 9667 * 9668 * @param {Function} reducer Original reducer function. 9669 * 9670 * @return {Function} Enhanced reducer function. 9671 */ 9672 const withReplaceInnerBlocks = reducer => (state, action) => { 9673 if (action.type !== 'REPLACE_INNER_BLOCKS') { 9674 return reducer(state, action); 9675 } 9676 9677 // Finds every nested inner block controller. We must check the action blocks 9678 // and not just the block parent state because some inner block controllers 9679 // should be deleted if specified, whereas others should not be deleted. If 9680 // a controlled should not be deleted, then we need to avoid deleting its 9681 // inner blocks from the block state because its inner blocks will not be 9682 // attached to the block in the action. 9683 const nestedControllers = {}; 9684 if (Object.keys(state.controlledInnerBlocks).length) { 9685 const stack = [...action.blocks]; 9686 while (stack.length) { 9687 const { 9688 innerBlocks, 9689 ...block 9690 } = stack.shift(); 9691 stack.push(...innerBlocks); 9692 if (!!state.controlledInnerBlocks[block.clientId]) { 9693 nestedControllers[block.clientId] = true; 9694 } 9695 } 9696 } 9697 9698 // The `keepControlledInnerBlocks` prop will keep the inner blocks of the 9699 // marked block in the block state so that they can be reattached to the 9700 // marked block when we re-insert everything a few lines below. 9701 let stateAfterBlocksRemoval = state; 9702 if (state.order.get(action.rootClientId)) { 9703 stateAfterBlocksRemoval = reducer(stateAfterBlocksRemoval, { 9704 type: 'REMOVE_BLOCKS', 9705 keepControlledInnerBlocks: nestedControllers, 9706 clientIds: state.order.get(action.rootClientId) 9707 }); 9708 } 9709 let stateAfterInsert = stateAfterBlocksRemoval; 9710 if (action.blocks.length) { 9711 stateAfterInsert = reducer(stateAfterInsert, { 9712 ...action, 9713 type: 'INSERT_BLOCKS', 9714 index: 0 9715 }); 9716 9717 // We need to re-attach the controlled inner blocks to the blocks tree and 9718 // preserve their block order. Otherwise, an inner block controller's blocks 9719 // will be deleted entirely from its entity. 9720 const stateAfterInsertOrder = new Map(stateAfterInsert.order); 9721 Object.keys(nestedControllers).forEach(key => { 9722 if (state.order.get(key)) { 9723 stateAfterInsertOrder.set(key, state.order.get(key)); 9724 } 9725 }); 9726 stateAfterInsert.order = stateAfterInsertOrder; 9727 stateAfterInsert.tree = new Map(stateAfterInsert.tree); 9728 Object.keys(nestedControllers).forEach(_key => { 9729 const key = `controlled||$_key}`; 9730 if (state.tree.has(key)) { 9731 stateAfterInsert.tree.set(key, state.tree.get(key)); 9732 } 9733 }); 9734 } 9735 return stateAfterInsert; 9736 }; 9737 9738 /** 9739 * Higher-order reducer which targets the combined blocks reducer and handles 9740 * the `SAVE_REUSABLE_BLOCK_SUCCESS` action. This action can't be handled by 9741 * regular reducers and needs a higher-order reducer since it needs access to 9742 * both `byClientId` and `attributes` simultaneously. 9743 * 9744 * @param {Function} reducer Original reducer function. 9745 * 9746 * @return {Function} Enhanced reducer function. 9747 */ 9748 const withSaveReusableBlock = reducer => (state, action) => { 9749 if (state && action.type === 'SAVE_REUSABLE_BLOCK_SUCCESS') { 9750 const { 9751 id, 9752 updatedId 9753 } = action; 9754 9755 // If a temporary reusable block is saved, we swap the temporary id with the final one. 9756 if (id === updatedId) { 9757 return state; 9758 } 9759 state = { 9760 ...state 9761 }; 9762 state.attributes = new Map(state.attributes); 9763 state.attributes.forEach((attributes, clientId) => { 9764 const { 9765 name 9766 } = state.byClientId.get(clientId); 9767 if (name === 'core/block' && attributes.ref === id) { 9768 state.attributes.set(clientId, { 9769 ...attributes, 9770 ref: updatedId 9771 }); 9772 } 9773 }); 9774 } 9775 return reducer(state, action); 9776 }; 9777 /** 9778 * Higher-order reducer which removes blocks from state when switching parent block controlled state. 9779 * 9780 * @param {Function} reducer Original reducer function. 9781 * 9782 * @return {Function} Enhanced reducer function. 9783 */ 9784 const withResetControlledBlocks = reducer => (state, action) => { 9785 if (action.type === 'SET_HAS_CONTROLLED_INNER_BLOCKS') { 9786 // when switching a block from controlled to uncontrolled or inverse, 9787 // we need to remove its content first. 9788 const tempState = reducer(state, { 9789 type: 'REPLACE_INNER_BLOCKS', 9790 rootClientId: action.clientId, 9791 blocks: [] 9792 }); 9793 return reducer(tempState, action); 9794 } 9795 return reducer(state, action); 9796 }; 9797 9798 /** 9799 * Reducer returning the blocks state. 9800 * 9801 * @param {Object} state Current state. 9802 * @param {Object} action Dispatched action. 9803 * 9804 * @return {Object} Updated state. 9805 */ 9806 const blocks = (0,external_wp_compose_namespaceObject.pipe)(external_wp_data_namespaceObject.combineReducers, withSaveReusableBlock, 9807 // Needs to be before withBlockCache. 9808 withBlockTree, 9809 // Needs to be before withInnerBlocksRemoveCascade. 9810 withInnerBlocksRemoveCascade, withReplaceInnerBlocks, 9811 // Needs to be after withInnerBlocksRemoveCascade. 9812 withBlockReset, withPersistentBlockChange, withIgnoredBlockChange, withResetControlledBlocks)({ 9813 // The state is using a Map instead of a plain object for performance reasons. 9814 // You can run the "./test/performance.js" unit test to check the impact 9815 // code changes can have on this reducer. 9816 byClientId(state = new Map(), action) { 9817 switch (action.type) { 9818 case 'RECEIVE_BLOCKS': 9819 case 'INSERT_BLOCKS': 9820 { 9821 const newState = new Map(state); 9822 getFlattenedBlocksWithoutAttributes(action.blocks).forEach(([key, value]) => { 9823 newState.set(key, value); 9824 }); 9825 return newState; 9826 } 9827 case 'UPDATE_BLOCK': 9828 { 9829 // Ignore updates if block isn't known. 9830 if (!state.has(action.clientId)) { 9831 return state; 9832 } 9833 9834 // Do nothing if only attributes change. 9835 const { 9836 attributes, 9837 ...changes 9838 } = action.updates; 9839 if (Object.values(changes).length === 0) { 9840 return state; 9841 } 9842 const newState = new Map(state); 9843 newState.set(action.clientId, { 9844 ...state.get(action.clientId), 9845 ...changes 9846 }); 9847 return newState; 9848 } 9849 case 'REPLACE_BLOCKS_AUGMENTED_WITH_CHILDREN': 9850 { 9851 if (!action.blocks) { 9852 return state; 9853 } 9854 const newState = new Map(state); 9855 action.replacedClientIds.forEach(clientId => { 9856 newState.delete(clientId); 9857 }); 9858 getFlattenedBlocksWithoutAttributes(action.blocks).forEach(([key, value]) => { 9859 newState.set(key, value); 9860 }); 9861 return newState; 9862 } 9863 case 'REMOVE_BLOCKS_AUGMENTED_WITH_CHILDREN': 9864 { 9865 const newState = new Map(state); 9866 action.removedClientIds.forEach(clientId => { 9867 newState.delete(clientId); 9868 }); 9869 return newState; 9870 } 9871 } 9872 return state; 9873 }, 9874 // The state is using a Map instead of a plain object for performance reasons. 9875 // You can run the "./test/performance.js" unit test to check the impact 9876 // code changes can have on this reducer. 9877 attributes(state = new Map(), action) { 9878 switch (action.type) { 9879 case 'RECEIVE_BLOCKS': 9880 case 'INSERT_BLOCKS': 9881 { 9882 const newState = new Map(state); 9883 getFlattenedBlockAttributes(action.blocks).forEach(([key, value]) => { 9884 newState.set(key, value); 9885 }); 9886 return newState; 9887 } 9888 case 'UPDATE_BLOCK': 9889 { 9890 // Ignore updates if block isn't known or there are no attribute changes. 9891 if (!state.get(action.clientId) || !action.updates.attributes) { 9892 return state; 9893 } 9894 const newState = new Map(state); 9895 newState.set(action.clientId, { 9896 ...state.get(action.clientId), 9897 ...action.updates.attributes 9898 }); 9899 return newState; 9900 } 9901 case 'SYNC_DERIVED_BLOCK_ATTRIBUTES': 9902 case 'UPDATE_BLOCK_ATTRIBUTES': 9903 { 9904 // Avoid a state change if none of the block IDs are known. 9905 if (action.clientIds.every(id => !state.get(id))) { 9906 return state; 9907 } 9908 let hasChange = false; 9909 const newState = new Map(state); 9910 for (const clientId of action.clientIds) { 9911 var _action$attributes; 9912 const updatedAttributeEntries = Object.entries(action.uniqueByBlock ? action.attributes[clientId] : (_action$attributes = action.attributes) !== null && _action$attributes !== void 0 ? _action$attributes : {}); 9913 if (updatedAttributeEntries.length === 0) { 9914 continue; 9915 } 9916 let hasUpdatedAttributes = false; 9917 const existingAttributes = state.get(clientId); 9918 const newAttributes = {}; 9919 updatedAttributeEntries.forEach(([key, value]) => { 9920 if (existingAttributes[key] !== value) { 9921 hasUpdatedAttributes = true; 9922 newAttributes[key] = value; 9923 } 9924 }); 9925 hasChange = hasChange || hasUpdatedAttributes; 9926 if (hasUpdatedAttributes) { 9927 newState.set(clientId, { 9928 ...existingAttributes, 9929 ...newAttributes 9930 }); 9931 } 9932 } 9933 return hasChange ? newState : state; 9934 } 9935 case 'REPLACE_BLOCKS_AUGMENTED_WITH_CHILDREN': 9936 { 9937 if (!action.blocks) { 9938 return state; 9939 } 9940 const newState = new Map(state); 9941 action.replacedClientIds.forEach(clientId => { 9942 newState.delete(clientId); 9943 }); 9944 getFlattenedBlockAttributes(action.blocks).forEach(([key, value]) => { 9945 newState.set(key, value); 9946 }); 9947 return newState; 9948 } 9949 case 'REMOVE_BLOCKS_AUGMENTED_WITH_CHILDREN': 9950 { 9951 const newState = new Map(state); 9952 action.removedClientIds.forEach(clientId => { 9953 newState.delete(clientId); 9954 }); 9955 return newState; 9956 } 9957 } 9958 return state; 9959 }, 9960 // The state is using a Map instead of a plain object for performance reasons. 9961 // You can run the "./test/performance.js" unit test to check the impact 9962 // code changes can have on this reducer. 9963 order(state = new Map(), action) { 9964 switch (action.type) { 9965 case 'RECEIVE_BLOCKS': 9966 { 9967 var _state$get; 9968 const blockOrder = mapBlockOrder(action.blocks); 9969 const newState = new Map(state); 9970 blockOrder.forEach((order, clientId) => { 9971 if (clientId !== '') { 9972 newState.set(clientId, order); 9973 } 9974 }); 9975 newState.set('', ((_state$get = state.get('')) !== null && _state$get !== void 0 ? _state$get : []).concat(blockOrder[''])); 9976 return newState; 9977 } 9978 case 'INSERT_BLOCKS': 9979 { 9980 const { 9981 rootClientId = '' 9982 } = action; 9983 const subState = state.get(rootClientId) || []; 9984 const mappedBlocks = mapBlockOrder(action.blocks, rootClientId); 9985 const { 9986 index = subState.length 9987 } = action; 9988 const newState = new Map(state); 9989 mappedBlocks.forEach((order, clientId) => { 9990 newState.set(clientId, order); 9991 }); 9992 newState.set(rootClientId, insertAt(subState, mappedBlocks.get(rootClientId), index)); 9993 return newState; 9994 } 9995 case 'MOVE_BLOCKS_TO_POSITION': 9996 { 9997 var _state$get$filter; 9998 const { 9999 fromRootClientId = '', 10000 toRootClientId = '', 10001 clientIds 10002 } = action; 10003 const { 10004 index = state.get(toRootClientId).length 10005 } = action; 10006 10007 // Moving inside the same parent block. 10008 if (fromRootClientId === toRootClientId) { 10009 const subState = state.get(toRootClientId); 10010 const fromIndex = subState.indexOf(clientIds[0]); 10011 const newState = new Map(state); 10012 newState.set(toRootClientId, moveTo(state.get(toRootClientId), fromIndex, index, clientIds.length)); 10013 return newState; 10014 } 10015 10016 // Moving from a parent block to another. 10017 const newState = new Map(state); 10018 newState.set(fromRootClientId, (_state$get$filter = state.get(fromRootClientId)?.filter(id => !clientIds.includes(id))) !== null && _state$get$filter !== void 0 ? _state$get$filter : []); 10019 newState.set(toRootClientId, insertAt(state.get(toRootClientId), clientIds, index)); 10020 return newState; 10021 } 10022 case 'MOVE_BLOCKS_UP': 10023 { 10024 const { 10025 clientIds, 10026 rootClientId = '' 10027 } = action; 10028 const firstClientId = clientIds[0]; 10029 const subState = state.get(rootClientId); 10030 if (!subState.length || firstClientId === subState[0]) { 10031 return state; 10032 } 10033 const firstIndex = subState.indexOf(firstClientId); 10034 const newState = new Map(state); 10035 newState.set(rootClientId, moveTo(subState, firstIndex, firstIndex - 1, clientIds.length)); 10036 return newState; 10037 } 10038 case 'MOVE_BLOCKS_DOWN': 10039 { 10040 const { 10041 clientIds, 10042 rootClientId = '' 10043 } = action; 10044 const firstClientId = clientIds[0]; 10045 const lastClientId = clientIds[clientIds.length - 1]; 10046 const subState = state.get(rootClientId); 10047 if (!subState.length || lastClientId === subState[subState.length - 1]) { 10048 return state; 10049 } 10050 const firstIndex = subState.indexOf(firstClientId); 10051 const newState = new Map(state); 10052 newState.set(rootClientId, moveTo(subState, firstIndex, firstIndex + 1, clientIds.length)); 10053 return newState; 10054 } 10055 case 'REPLACE_BLOCKS_AUGMENTED_WITH_CHILDREN': 10056 { 10057 const { 10058 clientIds 10059 } = action; 10060 if (!action.blocks) { 10061 return state; 10062 } 10063 const mappedBlocks = mapBlockOrder(action.blocks); 10064 const newState = new Map(state); 10065 action.replacedClientIds.forEach(clientId => { 10066 newState.delete(clientId); 10067 }); 10068 mappedBlocks.forEach((order, clientId) => { 10069 if (clientId !== '') { 10070 newState.set(clientId, order); 10071 } 10072 }); 10073 newState.forEach((order, clientId) => { 10074 const newSubOrder = Object.values(order).reduce((result, subClientId) => { 10075 if (subClientId === clientIds[0]) { 10076 return [...result, ...mappedBlocks.get('')]; 10077 } 10078 if (clientIds.indexOf(subClientId) === -1) { 10079 result.push(subClientId); 10080 } 10081 return result; 10082 }, []); 10083 newState.set(clientId, newSubOrder); 10084 }); 10085 return newState; 10086 } 10087 case 'REMOVE_BLOCKS_AUGMENTED_WITH_CHILDREN': 10088 { 10089 const newState = new Map(state); 10090 // Remove inner block ordering for removed blocks. 10091 action.removedClientIds.forEach(clientId => { 10092 newState.delete(clientId); 10093 }); 10094 newState.forEach((order, clientId) => { 10095 var _order$filter; 10096 const newSubOrder = (_order$filter = order?.filter(id => !action.removedClientIds.includes(id))) !== null && _order$filter !== void 0 ? _order$filter : []; 10097 if (newSubOrder.length !== order.length) { 10098 newState.set(clientId, newSubOrder); 10099 } 10100 }); 10101 return newState; 10102 } 10103 } 10104 return state; 10105 }, 10106 // While technically redundant data as the inverse of `order`, it serves as 10107 // an optimization for the selectors which derive the ancestry of a block. 10108 parents(state = new Map(), action) { 10109 switch (action.type) { 10110 case 'RECEIVE_BLOCKS': 10111 { 10112 const newState = new Map(state); 10113 mapBlockParents(action.blocks).forEach(([key, value]) => { 10114 newState.set(key, value); 10115 }); 10116 return newState; 10117 } 10118 case 'INSERT_BLOCKS': 10119 { 10120 const newState = new Map(state); 10121 mapBlockParents(action.blocks, action.rootClientId || '').forEach(([key, value]) => { 10122 newState.set(key, value); 10123 }); 10124 return newState; 10125 } 10126 case 'MOVE_BLOCKS_TO_POSITION': 10127 { 10128 const newState = new Map(state); 10129 action.clientIds.forEach(id => { 10130 newState.set(id, action.toRootClientId || ''); 10131 }); 10132 return newState; 10133 } 10134 case 'REPLACE_BLOCKS_AUGMENTED_WITH_CHILDREN': 10135 { 10136 const newState = new Map(state); 10137 action.replacedClientIds.forEach(clientId => { 10138 newState.delete(clientId); 10139 }); 10140 mapBlockParents(action.blocks, state.get(action.clientIds[0])).forEach(([key, value]) => { 10141 newState.set(key, value); 10142 }); 10143 return newState; 10144 } 10145 case 'REMOVE_BLOCKS_AUGMENTED_WITH_CHILDREN': 10146 { 10147 const newState = new Map(state); 10148 action.removedClientIds.forEach(clientId => { 10149 newState.delete(clientId); 10150 }); 10151 return newState; 10152 } 10153 } 10154 return state; 10155 }, 10156 controlledInnerBlocks(state = {}, { 10157 type, 10158 clientId, 10159 hasControlledInnerBlocks 10160 }) { 10161 if (type === 'SET_HAS_CONTROLLED_INNER_BLOCKS') { 10162 return { 10163 ...state, 10164 [clientId]: hasControlledInnerBlocks 10165 }; 10166 } 10167 return state; 10168 } 10169 }); 10170 10171 /** 10172 * Reducer returning visibility status of block interface. 10173 * 10174 * @param {boolean} state Current state. 10175 * @param {Object} action Dispatched action. 10176 * 10177 * @return {boolean} Updated state. 10178 */ 10179 function isBlockInterfaceHidden(state = false, action) { 10180 switch (action.type) { 10181 case 'HIDE_BLOCK_INTERFACE': 10182 return true; 10183 case 'SHOW_BLOCK_INTERFACE': 10184 return false; 10185 } 10186 return state; 10187 } 10188 10189 /** 10190 * Reducer returning typing state. 10191 * 10192 * @param {boolean} state Current state. 10193 * @param {Object} action Dispatched action. 10194 * 10195 * @return {boolean} Updated state. 10196 */ 10197 function isTyping(state = false, action) { 10198 switch (action.type) { 10199 case 'START_TYPING': 10200 return true; 10201 case 'STOP_TYPING': 10202 return false; 10203 } 10204 return state; 10205 } 10206 10207 /** 10208 * Reducer returning dragging state. It is possible for a user to be dragging 10209 * data from outside of the editor, so this state is separate from `draggedBlocks`. 10210 * 10211 * @param {boolean} state Current state. 10212 * @param {Object} action Dispatched action. 10213 * 10214 * @return {boolean} Updated state. 10215 */ 10216 function isDragging(state = false, action) { 10217 switch (action.type) { 10218 case 'START_DRAGGING': 10219 return true; 10220 case 'STOP_DRAGGING': 10221 return false; 10222 } 10223 return state; 10224 } 10225 10226 /** 10227 * Reducer returning dragged block client id. 10228 * 10229 * @param {string[]} state Current state. 10230 * @param {Object} action Dispatched action. 10231 * 10232 * @return {string[]} Updated state. 10233 */ 10234 function draggedBlocks(state = [], action) { 10235 switch (action.type) { 10236 case 'START_DRAGGING_BLOCKS': 10237 return action.clientIds; 10238 case 'STOP_DRAGGING_BLOCKS': 10239 return []; 10240 } 10241 return state; 10242 } 10243 10244 /** 10245 * Reducer tracking the visible blocks. 10246 * 10247 * @param {Record<string,boolean>} state Current state. 10248 * @param {Object} action Dispatched action. 10249 * 10250 * @return {Record<string,boolean>} Block visibility. 10251 */ 10252 function blockVisibility(state = {}, action) { 10253 if (action.type === 'SET_BLOCK_VISIBILITY') { 10254 return { 10255 ...state, 10256 ...action.updates 10257 }; 10258 } 10259 return state; 10260 } 10261 10262 /** 10263 * Internal helper reducer for selectionStart and selectionEnd. Can hold a block 10264 * selection, represented by an object with property clientId. 10265 * 10266 * @param {Object} state Current state. 10267 * @param {Object} action Dispatched action. 10268 * 10269 * @return {Object} Updated state. 10270 */ 10271 function selectionHelper(state = {}, action) { 10272 switch (action.type) { 10273 case 'CLEAR_SELECTED_BLOCK': 10274 { 10275 if (state.clientId) { 10276 return {}; 10277 } 10278 return state; 10279 } 10280 case 'SELECT_BLOCK': 10281 if (action.clientId === state.clientId) { 10282 return state; 10283 } 10284 return { 10285 clientId: action.clientId 10286 }; 10287 case 'REPLACE_INNER_BLOCKS': 10288 case 'INSERT_BLOCKS': 10289 { 10290 if (!action.updateSelection || !action.blocks.length) { 10291 return state; 10292 } 10293 return { 10294 clientId: action.blocks[0].clientId 10295 }; 10296 } 10297 case 'REMOVE_BLOCKS': 10298 if (!action.clientIds || !action.clientIds.length || action.clientIds.indexOf(state.clientId) === -1) { 10299 return state; 10300 } 10301 return {}; 10302 case 'REPLACE_BLOCKS': 10303 { 10304 if (action.clientIds.indexOf(state.clientId) === -1) { 10305 return state; 10306 } 10307 const blockToSelect = action.blocks[action.indexToSelect] || action.blocks[action.blocks.length - 1]; 10308 if (!blockToSelect) { 10309 return {}; 10310 } 10311 if (blockToSelect.clientId === state.clientId) { 10312 return state; 10313 } 10314 return { 10315 clientId: blockToSelect.clientId 10316 }; 10317 } 10318 } 10319 return state; 10320 } 10321 10322 /** 10323 * Reducer returning the selection state. 10324 * 10325 * @param {boolean} state Current state. 10326 * @param {Object} action Dispatched action. 10327 * 10328 * @return {boolean} Updated state. 10329 */ 10330 function selection(state = {}, action) { 10331 switch (action.type) { 10332 case 'SELECTION_CHANGE': 10333 if (action.clientId) { 10334 return { 10335 selectionStart: { 10336 clientId: action.clientId, 10337 attributeKey: action.attributeKey, 10338 offset: action.startOffset 10339 }, 10340 selectionEnd: { 10341 clientId: action.clientId, 10342 attributeKey: action.attributeKey, 10343 offset: action.endOffset 10344 } 10345 }; 10346 } 10347 return { 10348 selectionStart: action.start || state.selectionStart, 10349 selectionEnd: action.end || state.selectionEnd 10350 }; 10351 case 'RESET_SELECTION': 10352 const { 10353 selectionStart, 10354 selectionEnd 10355 } = action; 10356 return { 10357 selectionStart, 10358 selectionEnd 10359 }; 10360 case 'MULTI_SELECT': 10361 const { 10362 start, 10363 end 10364 } = action; 10365 if (start === state.selectionStart?.clientId && end === state.selectionEnd?.clientId) { 10366 return state; 10367 } 10368 return { 10369 selectionStart: { 10370 clientId: start 10371 }, 10372 selectionEnd: { 10373 clientId: end 10374 } 10375 }; 10376 case 'RESET_BLOCKS': 10377 const startClientId = state?.selectionStart?.clientId; 10378 const endClientId = state?.selectionEnd?.clientId; 10379 10380 // Do nothing if there's no selected block. 10381 if (!startClientId && !endClientId) { 10382 return state; 10383 } 10384 10385 // If the start of the selection won't exist after reset, remove selection. 10386 if (!action.blocks.some(block => block.clientId === startClientId)) { 10387 return { 10388 selectionStart: {}, 10389 selectionEnd: {} 10390 }; 10391 } 10392 10393 // If the end of the selection won't exist after reset, collapse selection. 10394 if (!action.blocks.some(block => block.clientId === endClientId)) { 10395 return { 10396 ...state, 10397 selectionEnd: state.selectionStart 10398 }; 10399 } 10400 } 10401 const selectionStart = selectionHelper(state.selectionStart, action); 10402 const selectionEnd = selectionHelper(state.selectionEnd, action); 10403 if (selectionStart === state.selectionStart && selectionEnd === state.selectionEnd) { 10404 return state; 10405 } 10406 return { 10407 selectionStart, 10408 selectionEnd 10409 }; 10410 } 10411 10412 /** 10413 * Reducer returning whether the user is multi-selecting. 10414 * 10415 * @param {boolean} state Current state. 10416 * @param {Object} action Dispatched action. 10417 * 10418 * @return {boolean} Updated state. 10419 */ 10420 function isMultiSelecting(state = false, action) { 10421 switch (action.type) { 10422 case 'START_MULTI_SELECT': 10423 return true; 10424 case 'STOP_MULTI_SELECT': 10425 return false; 10426 } 10427 return state; 10428 } 10429 10430 /** 10431 * Reducer returning whether selection is enabled. 10432 * 10433 * @param {boolean} state Current state. 10434 * @param {Object} action Dispatched action. 10435 * 10436 * @return {boolean} Updated state. 10437 */ 10438 function isSelectionEnabled(state = true, action) { 10439 switch (action.type) { 10440 case 'TOGGLE_SELECTION': 10441 return action.isSelectionEnabled; 10442 } 10443 return state; 10444 } 10445 10446 /** 10447 * Reducer returning the data needed to display a prompt when certain blocks 10448 * are removed, or `false` if no such prompt is requested. 10449 * 10450 * @param {boolean} state Current state. 10451 * @param {Object} action Dispatched action. 10452 * 10453 * @return {Object|false} Data for removal prompt display, if any. 10454 */ 10455 function removalPromptData(state = false, action) { 10456 switch (action.type) { 10457 case 'DISPLAY_BLOCK_REMOVAL_PROMPT': 10458 const { 10459 clientIds, 10460 selectPrevious, 10461 blockNamesForPrompt, 10462 messageType 10463 } = action; 10464 return { 10465 clientIds, 10466 selectPrevious, 10467 blockNamesForPrompt, 10468 messageType 10469 }; 10470 case 'CLEAR_BLOCK_REMOVAL_PROMPT': 10471 return false; 10472 } 10473 return state; 10474 } 10475 10476 /** 10477 * Reducer returning any rules that a block editor may provide in order to 10478 * prevent a user from accidentally removing certain blocks. These rules are 10479 * then used to display a confirmation prompt to the user. For instance, in the 10480 * Site Editor, the Query Loop block is important enough to warrant such 10481 * confirmation. 10482 * 10483 * The data is a record whose keys are block types (e.g. 'core/query') and 10484 * whose values are the explanation to be shown to users (e.g. 'Query Loop 10485 * displays a list of posts or pages.'). 10486 * 10487 * @param {boolean} state Current state. 10488 * @param {Object} action Dispatched action. 10489 * 10490 * @return {Record<string,string>} Updated state. 10491 */ 10492 function blockRemovalRules(state = false, action) { 10493 switch (action.type) { 10494 case 'SET_BLOCK_REMOVAL_RULES': 10495 return action.rules; 10496 } 10497 return state; 10498 } 10499 10500 /** 10501 * Reducer returning the initial block selection. 10502 * 10503 * Currently this in only used to restore the selection after block deletion and 10504 * pasting new content.This reducer should eventually be removed in favour of setting 10505 * selection directly. 10506 * 10507 * @param {boolean} state Current state. 10508 * @param {Object} action Dispatched action. 10509 * 10510 * @return {number|null} Initial position: 0, -1 or null. 10511 */ 10512 function initialPosition(state = null, action) { 10513 if (action.type === 'REPLACE_BLOCKS' && action.initialPosition !== undefined) { 10514 return action.initialPosition; 10515 } else if (['MULTI_SELECT', 'SELECT_BLOCK', 'RESET_SELECTION', 'INSERT_BLOCKS', 'REPLACE_INNER_BLOCKS'].includes(action.type)) { 10516 return action.initialPosition; 10517 } 10518 return state; 10519 } 10520 function blocksMode(state = {}, action) { 10521 if (action.type === 'TOGGLE_BLOCK_MODE') { 10522 const { 10523 clientId 10524 } = action; 10525 return { 10526 ...state, 10527 [clientId]: state[clientId] && state[clientId] === 'html' ? 'visual' : 'html' 10528 }; 10529 } 10530 return state; 10531 } 10532 10533 /** 10534 * Reducer returning the block insertion point visibility, either null if there 10535 * is not an explicit insertion point assigned, or an object of its `index` and 10536 * `rootClientId`. 10537 * 10538 * @param {Object} state Current state. 10539 * @param {Object} action Dispatched action. 10540 * 10541 * @return {Object} Updated state. 10542 */ 10543 function insertionPoint(state = null, action) { 10544 switch (action.type) { 10545 case 'SHOW_INSERTION_POINT': 10546 { 10547 const { 10548 rootClientId, 10549 index, 10550 __unstableWithInserter, 10551 operation, 10552 nearestSide 10553 } = action; 10554 const nextState = { 10555 rootClientId, 10556 index, 10557 __unstableWithInserter, 10558 operation, 10559 nearestSide 10560 }; 10561 10562 // Bail out updates if the states are the same. 10563 return es6_default()(state, nextState) ? state : nextState; 10564 } 10565 case 'HIDE_INSERTION_POINT': 10566 return null; 10567 } 10568 return state; 10569 } 10570 10571 /** 10572 * Reducer returning whether the post blocks match the defined template or not. 10573 * 10574 * @param {Object} state Current state. 10575 * @param {Object} action Dispatched action. 10576 * 10577 * @return {boolean} Updated state. 10578 */ 10579 function template(state = { 10580 isValid: true 10581 }, action) { 10582 switch (action.type) { 10583 case 'SET_TEMPLATE_VALIDITY': 10584 return { 10585 ...state, 10586 isValid: action.isValid 10587 }; 10588 } 10589 return state; 10590 } 10591 10592 /** 10593 * Reducer returning the editor setting. 10594 * 10595 * @param {Object} state Current state. 10596 * @param {Object} action Dispatched action. 10597 * 10598 * @return {Object} Updated state. 10599 */ 10600 function settings(state = SETTINGS_DEFAULTS, action) { 10601 switch (action.type) { 10602 case 'UPDATE_SETTINGS': 10603 if (action.reset) { 10604 return { 10605 ...SETTINGS_DEFAULTS, 10606 ...action.settings 10607 }; 10608 } 10609 return { 10610 ...state, 10611 ...action.settings 10612 }; 10613 } 10614 return state; 10615 } 10616 10617 /** 10618 * Reducer returning the user preferences. 10619 * 10620 * @param {Object} state Current state. 10621 * @param {Object} action Dispatched action. 10622 * 10623 * @return {string} Updated state. 10624 */ 10625 function preferences(state = PREFERENCES_DEFAULTS, action) { 10626 switch (action.type) { 10627 case 'INSERT_BLOCKS': 10628 case 'REPLACE_BLOCKS': 10629 return action.blocks.reduce((prevState, block) => { 10630 const { 10631 attributes, 10632 name: blockName 10633 } = block; 10634 let id = blockName; 10635 // If a block variation match is found change the name to be the same with the 10636 // one that is used for block variations in the Inserter (`getItemFromVariation`). 10637 const match = (0,external_wp_data_namespaceObject.select)(external_wp_blocks_namespaceObject.store).getActiveBlockVariation(blockName, attributes); 10638 if (match?.name) { 10639 id += '/' + match.name; 10640 } 10641 if (blockName === 'core/block') { 10642 id += '/' + attributes.ref; 10643 } 10644 return { 10645 ...prevState, 10646 insertUsage: { 10647 ...prevState.insertUsage, 10648 [id]: { 10649 time: action.time, 10650 count: prevState.insertUsage[id] ? prevState.insertUsage[id].count + 1 : 1 10651 } 10652 } 10653 }; 10654 }, state); 10655 } 10656 return state; 10657 } 10658 10659 /** 10660 * Reducer returning an object where each key is a block client ID, its value 10661 * representing the settings for its nested blocks. 10662 * 10663 * @param {Object} state Current state. 10664 * @param {Object} action Dispatched action. 10665 * 10666 * @return {Object} Updated state. 10667 */ 10668 const blockListSettings = (state = {}, action) => { 10669 switch (action.type) { 10670 // Even if the replaced blocks have the same client ID, our logic 10671 // should correct the state. 10672 case 'REPLACE_BLOCKS': 10673 case 'REMOVE_BLOCKS': 10674 { 10675 return Object.fromEntries(Object.entries(state).filter(([id]) => !action.clientIds.includes(id))); 10676 } 10677 case 'UPDATE_BLOCK_LIST_SETTINGS': 10678 { 10679 const { 10680 clientId 10681 } = action; 10682 if (!action.settings) { 10683 if (state.hasOwnProperty(clientId)) { 10684 const { 10685 [clientId]: removedBlock, 10686 ...restBlocks 10687 } = state; 10688 return restBlocks; 10689 } 10690 return state; 10691 } 10692 if (es6_default()(state[clientId], action.settings)) { 10693 return state; 10694 } 10695 return { 10696 ...state, 10697 [clientId]: action.settings 10698 }; 10699 } 10700 } 10701 return state; 10702 }; 10703 10704 /** 10705 * Reducer returning which mode is enabled. 10706 * 10707 * @param {string} state Current state. 10708 * @param {Object} action Dispatched action. 10709 * 10710 * @return {string} Updated state. 10711 */ 10712 function editorMode(state = 'edit', action) { 10713 // Let inserting block in navigation mode always trigger Edit mode. 10714 if (action.type === 'INSERT_BLOCKS' && state === 'navigation') { 10715 return 'edit'; 10716 } 10717 if (action.type === 'SET_EDITOR_MODE') { 10718 return action.mode; 10719 } 10720 return state; 10721 } 10722 10723 /** 10724 * Reducer returning whether the block moving mode is enabled or not. 10725 * 10726 * @param {string|null} state Current state. 10727 * @param {Object} action Dispatched action. 10728 * 10729 * @return {string|null} Updated state. 10730 */ 10731 function hasBlockMovingClientId(state = null, action) { 10732 if (action.type === 'SET_BLOCK_MOVING_MODE') { 10733 return action.hasBlockMovingClientId; 10734 } 10735 if (action.type === 'SET_EDITOR_MODE') { 10736 return null; 10737 } 10738 return state; 10739 } 10740 10741 /** 10742 * Reducer return an updated state representing the most recent block attribute 10743 * update. The state is structured as an object where the keys represent the 10744 * client IDs of blocks, the values a subset of attributes from the most recent 10745 * block update. The state is always reset to null if the last action is 10746 * anything other than an attributes update. 10747 * 10748 * @param {Object<string,Object>} state Current state. 10749 * @param {Object} action Action object. 10750 * 10751 * @return {[string,Object]} Updated state. 10752 */ 10753 function lastBlockAttributesChange(state = null, action) { 10754 switch (action.type) { 10755 case 'UPDATE_BLOCK': 10756 if (!action.updates.attributes) { 10757 break; 10758 } 10759 return { 10760 [action.clientId]: action.updates.attributes 10761 }; 10762 case 'UPDATE_BLOCK_ATTRIBUTES': 10763 return action.clientIds.reduce((accumulator, id) => ({ 10764 ...accumulator, 10765 [id]: action.uniqueByBlock ? action.attributes[id] : action.attributes 10766 }), {}); 10767 } 10768 return state; 10769 } 10770 10771 /** 10772 * Reducer returning current highlighted block. 10773 * 10774 * @param {boolean} state Current highlighted block. 10775 * @param {Object} action Dispatched action. 10776 * 10777 * @return {string} Updated state. 10778 */ 10779 function highlightedBlock(state, action) { 10780 switch (action.type) { 10781 case 'TOGGLE_BLOCK_HIGHLIGHT': 10782 const { 10783 clientId, 10784 isHighlighted 10785 } = action; 10786 if (isHighlighted) { 10787 return clientId; 10788 } else if (state === clientId) { 10789 return null; 10790 } 10791 return state; 10792 case 'SELECT_BLOCK': 10793 if (action.clientId !== state) { 10794 return null; 10795 } 10796 } 10797 return state; 10798 } 10799 10800 /** 10801 * Reducer returning the block insertion event list state. 10802 * 10803 * @param {Object} state Current state. 10804 * @param {Object} action Dispatched action. 10805 * 10806 * @return {Object} Updated state. 10807 */ 10808 function lastBlockInserted(state = {}, action) { 10809 switch (action.type) { 10810 case 'INSERT_BLOCKS': 10811 case 'REPLACE_BLOCKS': 10812 if (!action.blocks.length) { 10813 return state; 10814 } 10815 const clientIds = action.blocks.map(block => { 10816 return block.clientId; 10817 }); 10818 const source = action.meta?.source; 10819 return { 10820 clientIds, 10821 source 10822 }; 10823 case 'RESET_BLOCKS': 10824 return {}; 10825 } 10826 return state; 10827 } 10828 10829 /** 10830 * Reducer returning the block that is eding temporarily edited as blocks. 10831 * 10832 * @param {Object} state Current state. 10833 * @param {Object} action Dispatched action. 10834 * 10835 * @return {Object} Updated state. 10836 */ 10837 function temporarilyEditingAsBlocks(state = '', action) { 10838 if (action.type === 'SET_TEMPORARILY_EDITING_AS_BLOCKS') { 10839 return action.temporarilyEditingAsBlocks; 10840 } 10841 return state; 10842 } 10843 10844 /** 10845 * Reducer returning the focus mode that should be used when temporarily edit as blocks finishes. 10846 * 10847 * @param {Object} state Current state. 10848 * @param {Object} action Dispatched action. 10849 * 10850 * @return {Object} Updated state. 10851 */ 10852 function temporarilyEditingFocusModeRevert(state = '', action) { 10853 if (action.type === 'SET_TEMPORARILY_EDITING_AS_BLOCKS') { 10854 return action.focusModeToRevert; 10855 } 10856 return state; 10857 } 10858 10859 /** 10860 * Reducer returning a map of block client IDs to block editing modes. 10861 * 10862 * @param {Map} state Current state. 10863 * @param {Object} action Dispatched action. 10864 * 10865 * @return {Map} Updated state. 10866 */ 10867 function blockEditingModes(state = new Map(), action) { 10868 switch (action.type) { 10869 case 'SET_BLOCK_EDITING_MODE': 10870 return new Map(state).set(action.clientId, action.mode); 10871 case 'UNSET_BLOCK_EDITING_MODE': 10872 { 10873 const newState = new Map(state); 10874 newState.delete(action.clientId); 10875 return newState; 10876 } 10877 case 'RESET_BLOCKS': 10878 { 10879 return state.has('') ? new Map().set('', state.get('')) : state; 10880 } 10881 } 10882 return state; 10883 } 10884 10885 /** 10886 * Reducer returning the clientId of the block settings menu that is currently open. 10887 * 10888 * @param {string|null} state Current state. 10889 * @param {Object} action Dispatched action. 10890 * 10891 * @return {string|null} Updated state. 10892 */ 10893 function openedBlockSettingsMenu(state = null, action) { 10894 if ('SET_OPENED_BLOCK_SETTINGS_MENU' === action.type) { 10895 var _action$clientId; 10896 return (_action$clientId = action?.clientId) !== null && _action$clientId !== void 0 ? _action$clientId : null; 10897 } 10898 return state; 10899 } 10900 10901 /** 10902 * Reducer returning a map of style IDs to style overrides. 10903 * 10904 * @param {Map} state Current state. 10905 * @param {Object} action Dispatched action. 10906 * 10907 * @return {Map} Updated state. 10908 */ 10909 function styleOverrides(state = new Map(), action) { 10910 switch (action.type) { 10911 case 'SET_STYLE_OVERRIDE': 10912 return new Map(state).set(action.id, action.style); 10913 case 'DELETE_STYLE_OVERRIDE': 10914 { 10915 const newState = new Map(state); 10916 newState.delete(action.id); 10917 return newState; 10918 } 10919 } 10920 return state; 10921 } 10922 10923 /** 10924 * Reducer returning a map of the registered inserter media categories. 10925 * 10926 * @param {Array} state Current state. 10927 * @param {Object} action Dispatched action. 10928 * 10929 * @return {Array} Updated state. 10930 */ 10931 function registeredInserterMediaCategories(state = [], action) { 10932 switch (action.type) { 10933 case 'REGISTER_INSERTER_MEDIA_CATEGORY': 10934 return [...state, action.category]; 10935 } 10936 return state; 10937 } 10938 10939 /** 10940 * Reducer setting last focused element 10941 * 10942 * @param {boolean} state Current state. 10943 * @param {Object} action Dispatched action. 10944 * 10945 * @return {boolean} Updated state. 10946 */ 10947 function lastFocus(state = false, action) { 10948 switch (action.type) { 10949 case 'LAST_FOCUS': 10950 return action.lastFocus; 10951 } 10952 return state; 10953 } 10954 const combinedReducers = (0,external_wp_data_namespaceObject.combineReducers)({ 10955 blocks, 10956 isDragging, 10957 isTyping, 10958 isBlockInterfaceHidden, 10959 draggedBlocks, 10960 selection, 10961 isMultiSelecting, 10962 isSelectionEnabled, 10963 initialPosition, 10964 blocksMode, 10965 blockListSettings, 10966 insertionPoint, 10967 template, 10968 settings, 10969 preferences, 10970 lastBlockAttributesChange, 10971 lastFocus, 10972 editorMode, 10973 hasBlockMovingClientId, 10974 highlightedBlock, 10975 lastBlockInserted, 10976 temporarilyEditingAsBlocks, 10977 temporarilyEditingFocusModeRevert, 10978 blockVisibility, 10979 blockEditingModes, 10980 styleOverrides, 10981 removalPromptData, 10982 blockRemovalRules, 10983 openedBlockSettingsMenu, 10984 registeredInserterMediaCategories 10985 }); 10986 function withAutomaticChangeReset(reducer) { 10987 return (state, action) => { 10988 const nextState = reducer(state, action); 10989 if (!state) { 10990 return nextState; 10991 } 10992 10993 // Take over the last value without creating a new reference. 10994 nextState.automaticChangeStatus = state.automaticChangeStatus; 10995 if (action.type === 'MARK_AUTOMATIC_CHANGE') { 10996 return { 10997 ...nextState, 10998 automaticChangeStatus: 'pending' 10999 }; 11000 } 11001 if (action.type === 'MARK_AUTOMATIC_CHANGE_FINAL' && state.automaticChangeStatus === 'pending') { 11002 return { 11003 ...nextState, 11004 automaticChangeStatus: 'final' 11005 }; 11006 } 11007 11008 // If there's a change that doesn't affect blocks or selection, maintain 11009 // the current status. 11010 if (nextState.blocks === state.blocks && nextState.selection === state.selection) { 11011 return nextState; 11012 } 11013 11014 // As long as the state is not final, ignore any selection changes. 11015 if (nextState.automaticChangeStatus !== 'final' && nextState.selection !== state.selection) { 11016 return nextState; 11017 } 11018 11019 // Reset the status if blocks change or selection changes (when status is final). 11020 return { 11021 ...nextState, 11022 automaticChangeStatus: undefined 11023 }; 11024 }; 11025 } 11026 /* harmony default export */ const reducer = (withAutomaticChangeReset(combinedReducers)); 11027 11028 ;// CONCATENATED MODULE: ./node_modules/rememo/rememo.js 11029 11030 11031 /** @typedef {(...args: any[]) => *[]} GetDependants */ 11032 11033 /** @typedef {() => void} Clear */ 11034 11035 /** 11036 * @typedef {{ 11037 * getDependants: GetDependants, 11038 * clear: Clear 11039 * }} EnhancedSelector 11040 */ 11041 11042 /** 11043 * Internal cache entry. 11044 * 11045 * @typedef CacheNode 11046 * 11047 * @property {?CacheNode|undefined} [prev] Previous node. 11048 * @property {?CacheNode|undefined} [next] Next node. 11049 * @property {*[]} args Function arguments for cache entry. 11050 * @property {*} val Function result. 11051 */ 11052 11053 /** 11054 * @typedef Cache 11055 * 11056 * @property {Clear} clear Function to clear cache. 11057 * @property {boolean} [isUniqueByDependants] Whether dependants are valid in 11058 * considering cache uniqueness. A cache is unique if dependents are all arrays 11059 * or objects. 11060 * @property {CacheNode?} [head] Cache head. 11061 * @property {*[]} [lastDependants] Dependants from previous invocation. 11062 */ 11063 11064 /** 11065 * Arbitrary value used as key for referencing cache object in WeakMap tree. 11066 * 11067 * @type {{}} 11068 */ 11069 var LEAF_KEY = {}; 11070 11071 /** 11072 * Returns the first argument as the sole entry in an array. 11073 * 11074 * @template T 11075 * 11076 * @param {T} value Value to return. 11077 * 11078 * @return {[T]} Value returned as entry in array. 11079 */ 11080 function arrayOf(value) { 11081 return [value]; 11082 } 11083 11084 /** 11085 * Returns true if the value passed is object-like, or false otherwise. A value 11086 * is object-like if it can support property assignment, e.g. object or array. 11087 * 11088 * @param {*} value Value to test. 11089 * 11090 * @return {boolean} Whether value is object-like. 11091 */ 11092 function isObjectLike(value) { 11093 return !!value && 'object' === typeof value; 11094 } 11095 11096 /** 11097 * Creates and returns a new cache object. 11098 * 11099 * @return {Cache} Cache object. 11100 */ 11101 function createCache() { 11102 /** @type {Cache} */ 11103 var cache = { 11104 clear: function () { 11105 cache.head = null; 11106 }, 11107 }; 11108 11109 return cache; 11110 } 11111 11112 /** 11113 * Returns true if entries within the two arrays are strictly equal by 11114 * reference from a starting index. 11115 * 11116 * @param {*[]} a First array. 11117 * @param {*[]} b Second array. 11118 * @param {number} fromIndex Index from which to start comparison. 11119 * 11120 * @return {boolean} Whether arrays are shallowly equal. 11121 */ 11122 function isShallowEqual(a, b, fromIndex) { 11123 var i; 11124 11125 if (a.length !== b.length) { 11126 return false; 11127 } 11128 11129 for (i = fromIndex; i < a.length; i++) { 11130 if (a[i] !== b[i]) { 11131 return false; 11132 } 11133 } 11134 11135 return true; 11136 } 11137 11138 /** 11139 * Returns a memoized selector function. The getDependants function argument is 11140 * called before the memoized selector and is expected to return an immutable 11141 * reference or array of references on which the selector depends for computing 11142 * its own return value. The memoize cache is preserved only as long as those 11143 * dependant references remain the same. If getDependants returns a different 11144 * reference(s), the cache is cleared and the selector value regenerated. 11145 * 11146 * @template {(...args: *[]) => *} S 11147 * 11148 * @param {S} selector Selector function. 11149 * @param {GetDependants=} getDependants Dependant getter returning an array of 11150 * references used in cache bust consideration. 11151 */ 11152 /* harmony default export */ function rememo(selector, getDependants) { 11153 /** @type {WeakMap<*,*>} */ 11154 var rootCache; 11155 11156 /** @type {GetDependants} */ 11157 var normalizedGetDependants = getDependants ? getDependants : arrayOf; 11158 11159 /** 11160 * Returns the cache for a given dependants array. When possible, a WeakMap 11161 * will be used to create a unique cache for each set of dependants. This 11162 * is feasible due to the nature of WeakMap in allowing garbage collection 11163 * to occur on entries where the key object is no longer referenced. Since 11164 * WeakMap requires the key to be an object, this is only possible when the 11165 * dependant is object-like. The root cache is created as a hierarchy where 11166 * each top-level key is the first entry in a dependants set, the value a 11167 * WeakMap where each key is the next dependant, and so on. This continues 11168 * so long as the dependants are object-like. If no dependants are object- 11169 * like, then the cache is shared across all invocations. 11170 * 11171 * @see isObjectLike 11172 * 11173 * @param {*[]} dependants Selector dependants. 11174 * 11175 * @return {Cache} Cache object. 11176 */ 11177 function getCache(dependants) { 11178 var caches = rootCache, 11179 isUniqueByDependants = true, 11180 i, 11181 dependant, 11182 map, 11183 cache; 11184 11185 for (i = 0; i < dependants.length; i++) { 11186 dependant = dependants[i]; 11187 11188 // Can only compose WeakMap from object-like key. 11189 if (!isObjectLike(dependant)) { 11190 isUniqueByDependants = false; 11191 break; 11192 } 11193 11194 // Does current segment of cache already have a WeakMap? 11195 if (caches.has(dependant)) { 11196 // Traverse into nested WeakMap. 11197 caches = caches.get(dependant); 11198 } else { 11199 // Create, set, and traverse into a new one. 11200 map = new WeakMap(); 11201 caches.set(dependant, map); 11202 caches = map; 11203 } 11204 } 11205 11206 // We use an arbitrary (but consistent) object as key for the last item 11207 // in the WeakMap to serve as our running cache. 11208 if (!caches.has(LEAF_KEY)) { 11209 cache = createCache(); 11210 cache.isUniqueByDependants = isUniqueByDependants; 11211 caches.set(LEAF_KEY, cache); 11212 } 11213 11214 return caches.get(LEAF_KEY); 11215 } 11216 11217 /** 11218 * Resets root memoization cache. 11219 */ 11220 function clear() { 11221 rootCache = new WeakMap(); 11222 } 11223 11224 /* eslint-disable jsdoc/check-param-names */ 11225 /** 11226 * The augmented selector call, considering first whether dependants have 11227 * changed before passing it to underlying memoize function. 11228 * 11229 * @param {*} source Source object for derivation. 11230 * @param {...*} extraArgs Additional arguments to pass to selector. 11231 * 11232 * @return {*} Selector result. 11233 */ 11234 /* eslint-enable jsdoc/check-param-names */ 11235 function callSelector(/* source, ...extraArgs */) { 11236 var len = arguments.length, 11237 cache, 11238 node, 11239 i, 11240 args, 11241 dependants; 11242 11243 // Create copy of arguments (avoid leaking deoptimization). 11244 args = new Array(len); 11245 for (i = 0; i < len; i++) { 11246 args[i] = arguments[i]; 11247 } 11248 11249 dependants = normalizedGetDependants.apply(null, args); 11250 cache = getCache(dependants); 11251 11252 // If not guaranteed uniqueness by dependants (primitive type), shallow 11253 // compare against last dependants and, if references have changed, 11254 // destroy cache to recalculate result. 11255 if (!cache.isUniqueByDependants) { 11256 if ( 11257 cache.lastDependants && 11258 !isShallowEqual(dependants, cache.lastDependants, 0) 11259 ) { 11260 cache.clear(); 11261 } 11262 11263 cache.lastDependants = dependants; 11264 } 11265 11266 node = cache.head; 11267 while (node) { 11268 // Check whether node arguments match arguments 11269 if (!isShallowEqual(node.args, args, 1)) { 11270 node = node.next; 11271 continue; 11272 } 11273 11274 // At this point we can assume we've found a match 11275 11276 // Surface matched node to head if not already 11277 if (node !== cache.head) { 11278 // Adjust siblings to point to each other. 11279 /** @type {CacheNode} */ (node.prev).next = node.next; 11280 if (node.next) { 11281 node.next.prev = node.prev; 11282 } 11283 11284 node.next = cache.head; 11285 node.prev = null; 11286 /** @type {CacheNode} */ (cache.head).prev = node; 11287 cache.head = node; 11288 } 11289 11290 // Return immediately 11291 return node.val; 11292 } 11293 11294 // No cached value found. Continue to insertion phase: 11295 11296 node = /** @type {CacheNode} */ ({ 11297 // Generate the result from original function 11298 val: selector.apply(null, args), 11299 }); 11300 11301 // Avoid including the source object in the cache. 11302 args[0] = null; 11303 node.args = args; 11304 11305 // Don't need to check whether node is already head, since it would 11306 // have been returned above already if it was 11307 11308 // Shift existing head down list 11309 if (cache.head) { 11310 cache.head.prev = node; 11311 node.next = cache.head; 11312 } 11313 11314 cache.head = node; 11315 11316 return node.val; 11317 } 11318 11319 callSelector.getDependants = normalizedGetDependants; 11320 callSelector.clear = clear; 11321 clear(); 11322 11323 return /** @type {S & EnhancedSelector} */ (callSelector); 11324 } 11325 11326 ;// CONCATENATED MODULE: external ["wp","primitives"] 11327 const external_wp_primitives_namespaceObject = window["wp"]["primitives"]; 11328 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/symbol.js 11329 11330 /** 11331 * WordPress dependencies 11332 */ 11333 11334 const symbol = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 11335 xmlns: "http://www.w3.org/2000/svg", 11336 viewBox: "0 0 24 24" 11337 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 11338 d: "M21.3 10.8l-5.6-5.6c-.7-.7-1.8-.7-2.5 0l-5.6 5.6c-.7.7-.7 1.8 0 2.5l5.6 5.6c.3.3.8.5 1.2.5s.9-.2 1.2-.5l5.6-5.6c.8-.7.8-1.9.1-2.5zm-1 1.4l-5.6 5.6c-.1.1-.3.1-.4 0l-5.6-5.6c-.1-.1-.1-.3 0-.4l5.6-5.6s.1-.1.2-.1.1 0 .2.1l5.6 5.6c.1.1.1.3 0 .4zm-16.6-.4L10 5.5l-1-1-6.3 6.3c-.7.7-.7 1.8 0 2.5L9 19.5l1.1-1.1-6.3-6.3c-.2 0-.2-.2-.1-.3z" 11339 })); 11340 /* harmony default export */ const library_symbol = (symbol); 11341 11342 ;// CONCATENATED MODULE: external ["wp","richText"] 11343 const external_wp_richText_namespaceObject = window["wp"]["richText"]; 11344 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/store/private-keys.js 11345 const selectBlockPatternsKey = Symbol('selectBlockPatternsKey'); 11346 11347 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/store/utils.js 11348 /** 11349 * Internal dependencies 11350 */ 11351 11352 const checkAllowList = (list, item, defaultResult = null) => { 11353 if (typeof list === 'boolean') { 11354 return list; 11355 } 11356 if (Array.isArray(list)) { 11357 // TODO: when there is a canonical way to detect that we are editing a post 11358 // the following check should be changed to something like: 11359 // if ( list.includes( 'core/post-content' ) && getEditorMode() === 'post-content' && item === null ) 11360 if (list.includes('core/post-content') && item === null) { 11361 return true; 11362 } 11363 return list.includes(item); 11364 } 11365 return defaultResult; 11366 }; 11367 const checkAllowListRecursive = (blocks, allowedBlockTypes) => { 11368 if (typeof allowedBlockTypes === 'boolean') { 11369 return allowedBlockTypes; 11370 } 11371 const blocksQueue = [...blocks]; 11372 while (blocksQueue.length > 0) { 11373 const block = blocksQueue.shift(); 11374 const isAllowed = checkAllowList(allowedBlockTypes, block.name || block.blockName, true); 11375 if (!isAllowed) { 11376 return false; 11377 } 11378 block.innerBlocks?.forEach(innerBlock => { 11379 blocksQueue.push(innerBlock); 11380 }); 11381 } 11382 return true; 11383 }; 11384 const getAllPatternsDependants = select => state => { 11385 return [state.settings.__experimentalBlockPatterns, state.settings.__experimentalUserPatternCategories, state.settings.__experimentalReusableBlocks, state.settings[selectBlockPatternsKey]?.(select), state.blockPatterns]; 11386 }; 11387 11388 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/sorting.js 11389 /** 11390 * Recursive stable sorting comparator function. 11391 * 11392 * @param {string|Function} field Field to sort by. 11393 * @param {Array} items Items to sort. 11394 * @param {string} order Order, 'asc' or 'desc'. 11395 * @return {Function} Comparison function to be used in a `.sort()`. 11396 */ 11397 const comparator = (field, items, order) => { 11398 return (a, b) => { 11399 let cmpA, cmpB; 11400 if (typeof field === 'function') { 11401 cmpA = field(a); 11402 cmpB = field(b); 11403 } else { 11404 cmpA = a[field]; 11405 cmpB = b[field]; 11406 } 11407 if (cmpA > cmpB) { 11408 return order === 'asc' ? 1 : -1; 11409 } else if (cmpB > cmpA) { 11410 return order === 'asc' ? -1 : 1; 11411 } 11412 const orderA = items.findIndex(item => item === a); 11413 const orderB = items.findIndex(item => item === b); 11414 11415 // Stable sort: maintaining original array order 11416 if (orderA > orderB) { 11417 return 1; 11418 } else if (orderB > orderA) { 11419 return -1; 11420 } 11421 return 0; 11422 }; 11423 }; 11424 11425 /** 11426 * Order items by a certain key. 11427 * Supports decorator functions that allow complex picking of a comparison field. 11428 * Sorts in ascending order by default, but supports descending as well. 11429 * Stable sort - maintains original order of equal items. 11430 * 11431 * @param {Array} items Items to order. 11432 * @param {string|Function} field Field to order by. 11433 * @param {string} order Sorting order, `asc` or `desc`. 11434 * @return {Array} Sorted items. 11435 */ 11436 function orderBy(items, field, order = 'asc') { 11437 return items.concat().sort(comparator(field, items, order)); 11438 } 11439 11440 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/store/constants.js 11441 const STORE_NAME = 'core/block-editor'; 11442 11443 ;// CONCATENATED MODULE: external ["wp","privateApis"] 11444 const external_wp_privateApis_namespaceObject = window["wp"]["privateApis"]; 11445 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/lock-unlock.js 11446 /** 11447 * WordPress dependencies 11448 */ 11449 11450 const { 11451 lock, 11452 unlock 11453 } = (0,external_wp_privateApis_namespaceObject.__dangerousOptInToUnstableAPIsOnlyForCoreModules)('I know using unstable features means my theme or plugin will inevitably break in the next version of WordPress.', '@wordpress/block-editor'); 11454 11455 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/store/selectors.js 11456 /** 11457 * External dependencies 11458 */ 11459 11460 11461 /** 11462 * WordPress dependencies 11463 */ 11464 11465 11466 11467 11468 11469 11470 11471 11472 /** 11473 * Internal dependencies 11474 */ 11475 11476 11477 11478 11479 11480 /** 11481 * A block selection object. 11482 * 11483 * @typedef {Object} WPBlockSelection 11484 * 11485 * @property {string} clientId A block client ID. 11486 * @property {string} attributeKey A block attribute key. 11487 * @property {number} offset An attribute value offset, based on the rich 11488 * text value. See `wp.richText.create`. 11489 */ 11490 11491 // Module constants. 11492 const MILLISECONDS_PER_HOUR = 3600 * 1000; 11493 const MILLISECONDS_PER_DAY = 24 * 3600 * 1000; 11494 const MILLISECONDS_PER_WEEK = 7 * 24 * 3600 * 1000; 11495 11496 /** 11497 * Shared reference to an empty array for cases where it is important to avoid 11498 * returning a new array reference on every invocation, as in a connected or 11499 * other pure component which performs `shouldComponentUpdate` check on props. 11500 * This should be used as a last resort, since the normalized data should be 11501 * maintained by the reducer result in state. 11502 * 11503 * @type {Array} 11504 */ 11505 const EMPTY_ARRAY = []; 11506 11507 /** 11508 * Shared reference to an empty Set for cases where it is important to avoid 11509 * returning a new Set reference on every invocation, as in a connected or 11510 * other pure component which performs `shouldComponentUpdate` check on props. 11511 * This should be used as a last resort, since the normalized data should be 11512 * maintained by the reducer result in state. 11513 * 11514 * @type {Set} 11515 */ 11516 const EMPTY_SET = new Set(); 11517 11518 /** 11519 * Returns a block's name given its client ID, or null if no block exists with 11520 * the client ID. 11521 * 11522 * @param {Object} state Editor state. 11523 * @param {string} clientId Block client ID. 11524 * 11525 * @return {string} Block name. 11526 */ 11527 function getBlockName(state, clientId) { 11528 const block = state.blocks.byClientId.get(clientId); 11529 const socialLinkName = 'core/social-link'; 11530 if (external_wp_element_namespaceObject.Platform.OS !== 'web' && block?.name === socialLinkName) { 11531 const attributes = state.blocks.attributes.get(clientId); 11532 const { 11533 service 11534 } = attributes !== null && attributes !== void 0 ? attributes : {}; 11535 return service ? `$socialLinkName}-$service}` : socialLinkName; 11536 } 11537 return block ? block.name : null; 11538 } 11539 11540 /** 11541 * Returns whether a block is valid or not. 11542 * 11543 * @param {Object} state Editor state. 11544 * @param {string} clientId Block client ID. 11545 * 11546 * @return {boolean} Is Valid. 11547 */ 11548 function isBlockValid(state, clientId) { 11549 const block = state.blocks.byClientId.get(clientId); 11550 return !!block && block.isValid; 11551 } 11552 11553 /** 11554 * Returns a block's attributes given its client ID, or null if no block exists with 11555 * the client ID. 11556 * 11557 * @param {Object} state Editor state. 11558 * @param {string} clientId Block client ID. 11559 * 11560 * @return {Object?} Block attributes. 11561 */ 11562 function getBlockAttributes(state, clientId) { 11563 const block = state.blocks.byClientId.get(clientId); 11564 if (!block) { 11565 return null; 11566 } 11567 return state.blocks.attributes.get(clientId); 11568 } 11569 11570 /** 11571 * Returns a block given its client ID. This is a parsed copy of the block, 11572 * containing its `blockName`, `clientId`, and current `attributes` state. This 11573 * is not the block's registration settings, which must be retrieved from the 11574 * blocks module registration store. 11575 * 11576 * getBlock recurses through its inner blocks until all its children blocks have 11577 * been retrieved. Note that getBlock will not return the child inner blocks of 11578 * an inner block controller. This is because an inner block controller syncs 11579 * itself with its own entity, and should therefore not be included with the 11580 * blocks of a different entity. For example, say you call `getBlocks( TP )` to 11581 * get the blocks of a template part. If another template part is a child of TP, 11582 * then the nested template part's child blocks will not be returned. This way, 11583 * the template block itself is considered part of the parent, but the children 11584 * are not. 11585 * 11586 * @param {Object} state Editor state. 11587 * @param {string} clientId Block client ID. 11588 * 11589 * @return {Object} Parsed block object. 11590 */ 11591 function getBlock(state, clientId) { 11592 if (!state.blocks.byClientId.has(clientId)) { 11593 return null; 11594 } 11595 return state.blocks.tree.get(clientId); 11596 } 11597 const __unstableGetBlockWithoutInnerBlocks = rememo((state, clientId) => { 11598 const block = state.blocks.byClientId.get(clientId); 11599 if (!block) { 11600 return null; 11601 } 11602 return { 11603 ...block, 11604 attributes: getBlockAttributes(state, clientId) 11605 }; 11606 }, (state, clientId) => [state.blocks.byClientId.get(clientId), state.blocks.attributes.get(clientId)]); 11607 11608 /** 11609 * Returns all block objects for the current post being edited as an array in 11610 * the order they appear in the post. Note that this will exclude child blocks 11611 * of nested inner block controllers. 11612 * 11613 * @param {Object} state Editor state. 11614 * @param {?string} rootClientId Optional root client ID of block list. 11615 * 11616 * @return {Object[]} Post blocks. 11617 */ 11618 function getBlocks(state, rootClientId) { 11619 const treeKey = !rootClientId || !areInnerBlocksControlled(state, rootClientId) ? rootClientId || '' : 'controlled||' + rootClientId; 11620 return state.blocks.tree.get(treeKey)?.innerBlocks || EMPTY_ARRAY; 11621 } 11622 11623 /** 11624 * Returns a stripped down block object containing only its client ID, 11625 * and its inner blocks' client IDs. 11626 * 11627 * @deprecated 11628 * 11629 * @param {Object} state Editor state. 11630 * @param {string} clientId Client ID of the block to get. 11631 * 11632 * @return {Object} Client IDs of the post blocks. 11633 */ 11634 const __unstableGetClientIdWithClientIdsTree = rememo((state, clientId) => { 11635 external_wp_deprecated_default()("wp.data.select( 'core/block-editor' ).__unstableGetClientIdWithClientIdsTree", { 11636 since: '6.3', 11637 version: '6.5' 11638 }); 11639 return { 11640 clientId, 11641 innerBlocks: __unstableGetClientIdsTree(state, clientId) 11642 }; 11643 }, state => [state.blocks.order]); 11644 11645 /** 11646 * Returns the block tree represented in the block-editor store from the 11647 * given root, consisting of stripped down block objects containing only 11648 * their client IDs, and their inner blocks' client IDs. 11649 * 11650 * @deprecated 11651 * 11652 * @param {Object} state Editor state. 11653 * @param {?string} rootClientId Optional root client ID of block list. 11654 * 11655 * @return {Object[]} Client IDs of the post blocks. 11656 */ 11657 const __unstableGetClientIdsTree = rememo((state, rootClientId = '') => { 11658 external_wp_deprecated_default()("wp.data.select( 'core/block-editor' ).__unstableGetClientIdsTree", { 11659 since: '6.3', 11660 version: '6.5' 11661 }); 11662 return getBlockOrder(state, rootClientId).map(clientId => __unstableGetClientIdWithClientIdsTree(state, clientId)); 11663 }, state => [state.blocks.order]); 11664 11665 /** 11666 * Returns an array containing the clientIds of all descendants of the blocks 11667 * given. Returned ids are ordered first by the order of the ids given, then 11668 * by the order that they appear in the editor. 11669 * 11670 * @param {Object} state Global application state. 11671 * @param {string|string[]} rootIds Client ID(s) for which descendant blocks are to be returned. 11672 * 11673 * @return {Array} Client IDs of descendants. 11674 */ 11675 const getClientIdsOfDescendants = rememo((state, rootIds) => { 11676 rootIds = Array.isArray(rootIds) ? [...rootIds] : [rootIds]; 11677 const ids = []; 11678 11679 // Add the descendants of the root blocks first. 11680 for (const rootId of rootIds) { 11681 const order = state.blocks.order.get(rootId); 11682 if (order) { 11683 ids.push(...order); 11684 } 11685 } 11686 let index = 0; 11687 11688 // Add the descendants of the descendants, recursively. 11689 while (index < ids.length) { 11690 const id = ids[index]; 11691 const order = state.blocks.order.get(id); 11692 if (order) { 11693 ids.splice(index + 1, 0, ...order); 11694 } 11695 index++; 11696 } 11697 return ids; 11698 }, state => [state.blocks.order]); 11699 11700 /** 11701 * Returns an array containing the clientIds of the top-level blocks and 11702 * their descendants of any depth (for nested blocks). Ids are returned 11703 * in the same order that they appear in the editor. 11704 * 11705 * @param {Object} state Global application state. 11706 * 11707 * @return {Array} ids of top-level and descendant blocks. 11708 */ 11709 const getClientIdsWithDescendants = state => getClientIdsOfDescendants(state, ''); 11710 11711 /** 11712 * Returns the total number of blocks, or the total number of blocks with a specific name in a post. 11713 * The number returned includes nested blocks. 11714 * 11715 * @param {Object} state Global application state. 11716 * @param {?string} blockName Optional block name, if specified only blocks of that type will be counted. 11717 * 11718 * @return {number} Number of blocks in the post, or number of blocks with name equal to blockName. 11719 */ 11720 const getGlobalBlockCount = rememo((state, blockName) => { 11721 const clientIds = getClientIdsWithDescendants(state); 11722 if (!blockName) { 11723 return clientIds.length; 11724 } 11725 let count = 0; 11726 for (const clientId of clientIds) { 11727 const block = state.blocks.byClientId.get(clientId); 11728 if (block.name === blockName) { 11729 count++; 11730 } 11731 } 11732 return count; 11733 }, state => [state.blocks.order, state.blocks.byClientId]); 11734 11735 /** 11736 * Returns all blocks that match a blockName. Results include nested blocks. 11737 * 11738 * @param {Object} state Global application state. 11739 * @param {?string} blockName Optional block name, if not specified, returns an empty array. 11740 * 11741 * @return {Array} Array of clientIds of blocks with name equal to blockName. 11742 */ 11743 const getBlocksByName = rememo((state, blockName) => { 11744 if (!blockName) { 11745 return EMPTY_ARRAY; 11746 } 11747 const blockNames = Array.isArray(blockName) ? blockName : [blockName]; 11748 const clientIds = getClientIdsWithDescendants(state); 11749 const foundBlocks = clientIds.filter(clientId => { 11750 const block = state.blocks.byClientId.get(clientId); 11751 return blockNames.includes(block.name); 11752 }); 11753 return foundBlocks.length > 0 ? foundBlocks : EMPTY_ARRAY; 11754 }, state => [state.blocks.order, state.blocks.byClientId]); 11755 11756 /** 11757 * Returns all global blocks that match a blockName. Results include nested blocks. 11758 * 11759 * @deprecated 11760 * 11761 * @param {Object} state Global application state. 11762 * @param {?string} blockName Optional block name, if not specified, returns an empty array. 11763 * 11764 * @return {Array} Array of clientIds of blocks with name equal to blockName. 11765 */ 11766 function __experimentalGetGlobalBlocksByName(state, blockName) { 11767 external_wp_deprecated_default()("wp.data.select( 'core/block-editor' ).__experimentalGetGlobalBlocksByName", { 11768 since: '6.5', 11769 alternative: `wp.data.select( 'core/block-editor' ).getBlocksByName` 11770 }); 11771 return getBlocksByName(state, blockName); 11772 } 11773 11774 /** 11775 * Given an array of block client IDs, returns the corresponding array of block 11776 * objects. 11777 * 11778 * @param {Object} state Editor state. 11779 * @param {string[]} clientIds Client IDs for which blocks are to be returned. 11780 * 11781 * @return {WPBlock[]} Block objects. 11782 */ 11783 const getBlocksByClientId = rememo((state, clientIds) => (Array.isArray(clientIds) ? clientIds : [clientIds]).map(clientId => getBlock(state, clientId)), (state, clientIds) => (Array.isArray(clientIds) ? clientIds : [clientIds]).map(clientId => state.blocks.tree.get(clientId))); 11784 11785 /** 11786 * Given an array of block client IDs, returns the corresponding array of block 11787 * names. 11788 * 11789 * @param {Object} state Editor state. 11790 * @param {string[]} clientIds Client IDs for which block names are to be returned. 11791 * 11792 * @return {string[]} Block names. 11793 */ 11794 const getBlockNamesByClientId = rememo((state, clientIds) => getBlocksByClientId(state, clientIds).filter(Boolean).map(block => block.name), (state, clientIds) => getBlocksByClientId(state, clientIds)); 11795 11796 /** 11797 * Returns the number of blocks currently present in the post. 11798 * 11799 * @param {Object} state Editor state. 11800 * @param {?string} rootClientId Optional root client ID of block list. 11801 * 11802 * @return {number} Number of blocks in the post. 11803 */ 11804 function getBlockCount(state, rootClientId) { 11805 return getBlockOrder(state, rootClientId).length; 11806 } 11807 11808 /** 11809 * Returns the current selection start block client ID, attribute key and text 11810 * offset. 11811 * 11812 * @param {Object} state Block editor state. 11813 * 11814 * @return {WPBlockSelection} Selection start information. 11815 */ 11816 function getSelectionStart(state) { 11817 return state.selection.selectionStart; 11818 } 11819 11820 /** 11821 * Returns the current selection end block client ID, attribute key and text 11822 * offset. 11823 * 11824 * @param {Object} state Block editor state. 11825 * 11826 * @return {WPBlockSelection} Selection end information. 11827 */ 11828 function getSelectionEnd(state) { 11829 return state.selection.selectionEnd; 11830 } 11831 11832 /** 11833 * Returns the current block selection start. This value may be null, and it 11834 * may represent either a singular block selection or multi-selection start. 11835 * A selection is singular if its start and end match. 11836 * 11837 * @param {Object} state Global application state. 11838 * 11839 * @return {?string} Client ID of block selection start. 11840 */ 11841 function getBlockSelectionStart(state) { 11842 return state.selection.selectionStart.clientId; 11843 } 11844 11845 /** 11846 * Returns the current block selection end. This value may be null, and it 11847 * may represent either a singular block selection or multi-selection end. 11848 * A selection is singular if its start and end match. 11849 * 11850 * @param {Object} state Global application state. 11851 * 11852 * @return {?string} Client ID of block selection end. 11853 */ 11854 function getBlockSelectionEnd(state) { 11855 return state.selection.selectionEnd.clientId; 11856 } 11857 11858 /** 11859 * Returns the number of blocks currently selected in the post. 11860 * 11861 * @param {Object} state Global application state. 11862 * 11863 * @return {number} Number of blocks selected in the post. 11864 */ 11865 function getSelectedBlockCount(state) { 11866 const multiSelectedBlockCount = getMultiSelectedBlockClientIds(state).length; 11867 if (multiSelectedBlockCount) { 11868 return multiSelectedBlockCount; 11869 } 11870 return state.selection.selectionStart.clientId ? 1 : 0; 11871 } 11872 11873 /** 11874 * Returns true if there is a single selected block, or false otherwise. 11875 * 11876 * @param {Object} state Editor state. 11877 * 11878 * @return {boolean} Whether a single block is selected. 11879 */ 11880 function hasSelectedBlock(state) { 11881 const { 11882 selectionStart, 11883 selectionEnd 11884 } = state.selection; 11885 return !!selectionStart.clientId && selectionStart.clientId === selectionEnd.clientId; 11886 } 11887 11888 /** 11889 * Returns the currently selected block client ID, or null if there is no 11890 * selected block. 11891 * 11892 * @param {Object} state Editor state. 11893 * 11894 * @return {?string} Selected block client ID. 11895 */ 11896 function getSelectedBlockClientId(state) { 11897 const { 11898 selectionStart, 11899 selectionEnd 11900 } = state.selection; 11901 const { 11902 clientId 11903 } = selectionStart; 11904 if (!clientId || clientId !== selectionEnd.clientId) { 11905 return null; 11906 } 11907 return clientId; 11908 } 11909 11910 /** 11911 * Returns the currently selected block, or null if there is no selected block. 11912 * 11913 * @param {Object} state Global application state. 11914 * 11915 * @return {?Object} Selected block. 11916 */ 11917 function getSelectedBlock(state) { 11918 const clientId = getSelectedBlockClientId(state); 11919 return clientId ? getBlock(state, clientId) : null; 11920 } 11921 11922 /** 11923 * Given a block client ID, returns the root block from which the block is 11924 * nested, an empty string for top-level blocks, or null if the block does not 11925 * exist. 11926 * 11927 * @param {Object} state Editor state. 11928 * @param {string} clientId Block from which to find root client ID. 11929 * 11930 * @return {?string} Root client ID, if exists 11931 */ 11932 function getBlockRootClientId(state, clientId) { 11933 var _state$blocks$parents; 11934 return (_state$blocks$parents = state.blocks.parents.get(clientId)) !== null && _state$blocks$parents !== void 0 ? _state$blocks$parents : null; 11935 } 11936 11937 /** 11938 * Given a block client ID, returns the list of all its parents from top to bottom. 11939 * 11940 * @param {Object} state Editor state. 11941 * @param {string} clientId Block from which to find root client ID. 11942 * @param {boolean} ascending Order results from bottom to top (true) or top to bottom (false). 11943 * 11944 * @return {Array} ClientIDs of the parent blocks. 11945 */ 11946 const getBlockParents = rememo((state, clientId, ascending = false) => { 11947 const parents = []; 11948 let current = clientId; 11949 while (current = state.blocks.parents.get(current)) { 11950 parents.push(current); 11951 } 11952 if (!parents.length) { 11953 return EMPTY_ARRAY; 11954 } 11955 return ascending ? parents : parents.reverse(); 11956 }, state => [state.blocks.parents]); 11957 11958 /** 11959 * Given a block client ID and a block name, returns the list of all its parents 11960 * from top to bottom, filtered by the given name(s). For example, if passed 11961 * 'core/group' as the blockName, it will only return parents which are group 11962 * blocks. If passed `[ 'core/group', 'core/cover']`, as the blockName, it will 11963 * return parents which are group blocks and parents which are cover blocks. 11964 * 11965 * @param {Object} state Editor state. 11966 * @param {string} clientId Block from which to find root client ID. 11967 * @param {string|string[]} blockName Block name(s) to filter. 11968 * @param {boolean} ascending Order results from bottom to top (true) or top to bottom (false). 11969 * 11970 * @return {Array} ClientIDs of the parent blocks. 11971 */ 11972 const getBlockParentsByBlockName = rememo((state, clientId, blockName, ascending = false) => { 11973 const parents = getBlockParents(state, clientId, ascending); 11974 const hasName = Array.isArray(blockName) ? name => blockName.includes(name) : name => blockName === name; 11975 return parents.filter(id => hasName(getBlockName(state, id))); 11976 }, state => [state.blocks.parents]); 11977 /** 11978 * Given a block client ID, returns the root of the hierarchy from which the block is nested, return the block itself for root level blocks. 11979 * 11980 * @param {Object} state Editor state. 11981 * @param {string} clientId Block from which to find root client ID. 11982 * 11983 * @return {string} Root client ID 11984 */ 11985 function getBlockHierarchyRootClientId(state, clientId) { 11986 let current = clientId; 11987 let parent; 11988 do { 11989 parent = current; 11990 current = state.blocks.parents.get(current); 11991 } while (current); 11992 return parent; 11993 } 11994 11995 /** 11996 * Given a block client ID, returns the lowest common ancestor with selected client ID. 11997 * 11998 * @param {Object} state Editor state. 11999 * @param {string} clientId Block from which to find common ancestor client ID. 12000 * 12001 * @return {string} Common ancestor client ID or undefined 12002 */ 12003 function getLowestCommonAncestorWithSelectedBlock(state, clientId) { 12004 const selectedId = getSelectedBlockClientId(state); 12005 const clientParents = [...getBlockParents(state, clientId), clientId]; 12006 const selectedParents = [...getBlockParents(state, selectedId), selectedId]; 12007 let lowestCommonAncestor; 12008 const maxDepth = Math.min(clientParents.length, selectedParents.length); 12009 for (let index = 0; index < maxDepth; index++) { 12010 if (clientParents[index] === selectedParents[index]) { 12011 lowestCommonAncestor = clientParents[index]; 12012 } else { 12013 break; 12014 } 12015 } 12016 return lowestCommonAncestor; 12017 } 12018 12019 /** 12020 * Returns the client ID of the block adjacent one at the given reference 12021 * startClientId and modifier directionality. Defaults start startClientId to 12022 * the selected block, and direction as next block. Returns null if there is no 12023 * adjacent block. 12024 * 12025 * @param {Object} state Editor state. 12026 * @param {?string} startClientId Optional client ID of block from which to 12027 * search. 12028 * @param {?number} modifier Directionality multiplier (1 next, -1 12029 * previous). 12030 * 12031 * @return {?string} Return the client ID of the block, or null if none exists. 12032 */ 12033 function getAdjacentBlockClientId(state, startClientId, modifier = 1) { 12034 // Default to selected block. 12035 if (startClientId === undefined) { 12036 startClientId = getSelectedBlockClientId(state); 12037 } 12038 12039 // Try multi-selection starting at extent based on modifier. 12040 if (startClientId === undefined) { 12041 if (modifier < 0) { 12042 startClientId = getFirstMultiSelectedBlockClientId(state); 12043 } else { 12044 startClientId = getLastMultiSelectedBlockClientId(state); 12045 } 12046 } 12047 12048 // Validate working start client ID. 12049 if (!startClientId) { 12050 return null; 12051 } 12052 12053 // Retrieve start block root client ID, being careful to allow the falsey 12054 // empty string top-level root by explicitly testing against null. 12055 const rootClientId = getBlockRootClientId(state, startClientId); 12056 if (rootClientId === null) { 12057 return null; 12058 } 12059 const { 12060 order 12061 } = state.blocks; 12062 const orderSet = order.get(rootClientId); 12063 const index = orderSet.indexOf(startClientId); 12064 const nextIndex = index + 1 * modifier; 12065 12066 // Block was first in set and we're attempting to get previous. 12067 if (nextIndex < 0) { 12068 return null; 12069 } 12070 12071 // Block was last in set and we're attempting to get next. 12072 if (nextIndex === orderSet.length) { 12073 return null; 12074 } 12075 12076 // Assume incremented index is within the set. 12077 return orderSet[nextIndex]; 12078 } 12079 12080 /** 12081 * Returns the previous block's client ID from the given reference start ID. 12082 * Defaults start to the selected block. Returns null if there is no previous 12083 * block. 12084 * 12085 * @param {Object} state Editor state. 12086 * @param {?string} startClientId Optional client ID of block from which to 12087 * search. 12088 * 12089 * @return {?string} Adjacent block's client ID, or null if none exists. 12090 */ 12091 function getPreviousBlockClientId(state, startClientId) { 12092 return getAdjacentBlockClientId(state, startClientId, -1); 12093 } 12094 12095 /** 12096 * Returns the next block's client ID from the given reference start ID. 12097 * Defaults start to the selected block. Returns null if there is no next 12098 * block. 12099 * 12100 * @param {Object} state Editor state. 12101 * @param {?string} startClientId Optional client ID of block from which to 12102 * search. 12103 * 12104 * @return {?string} Adjacent block's client ID, or null if none exists. 12105 */ 12106 function getNextBlockClientId(state, startClientId) { 12107 return getAdjacentBlockClientId(state, startClientId, 1); 12108 } 12109 12110 /* eslint-disable jsdoc/valid-types */ 12111 /** 12112 * Returns the initial caret position for the selected block. 12113 * This position is to used to position the caret properly when the selected block changes. 12114 * If the current block is not a RichText, having initial position set to 0 means "focus block" 12115 * 12116 * @param {Object} state Global application state. 12117 * 12118 * @return {0|-1|null} Initial position. 12119 */ 12120 function getSelectedBlocksInitialCaretPosition(state) { 12121 /* eslint-enable jsdoc/valid-types */ 12122 return state.initialPosition; 12123 } 12124 12125 /** 12126 * Returns the current selection set of block client IDs (multiselection or single selection). 12127 * 12128 * @param {Object} state Editor state. 12129 * 12130 * @return {Array} Multi-selected block client IDs. 12131 */ 12132 const getSelectedBlockClientIds = rememo(state => { 12133 const { 12134 selectionStart, 12135 selectionEnd 12136 } = state.selection; 12137 if (!selectionStart.clientId || !selectionEnd.clientId) { 12138 return EMPTY_ARRAY; 12139 } 12140 if (selectionStart.clientId === selectionEnd.clientId) { 12141 return [selectionStart.clientId]; 12142 } 12143 12144 // Retrieve root client ID to aid in retrieving relevant nested block 12145 // order, being careful to allow the falsey empty string top-level root 12146 // by explicitly testing against null. 12147 const rootClientId = getBlockRootClientId(state, selectionStart.clientId); 12148 if (rootClientId === null) { 12149 return EMPTY_ARRAY; 12150 } 12151 const blockOrder = getBlockOrder(state, rootClientId); 12152 const startIndex = blockOrder.indexOf(selectionStart.clientId); 12153 const endIndex = blockOrder.indexOf(selectionEnd.clientId); 12154 if (startIndex > endIndex) { 12155 return blockOrder.slice(endIndex, startIndex + 1); 12156 } 12157 return blockOrder.slice(startIndex, endIndex + 1); 12158 }, state => [state.blocks.order, state.selection.selectionStart.clientId, state.selection.selectionEnd.clientId]); 12159 12160 /** 12161 * Returns the current multi-selection set of block client IDs, or an empty 12162 * array if there is no multi-selection. 12163 * 12164 * @param {Object} state Editor state. 12165 * 12166 * @return {Array} Multi-selected block client IDs. 12167 */ 12168 function getMultiSelectedBlockClientIds(state) { 12169 const { 12170 selectionStart, 12171 selectionEnd 12172 } = state.selection; 12173 if (selectionStart.clientId === selectionEnd.clientId) { 12174 return EMPTY_ARRAY; 12175 } 12176 return getSelectedBlockClientIds(state); 12177 } 12178 12179 /** 12180 * Returns the current multi-selection set of blocks, or an empty array if 12181 * there is no multi-selection. 12182 * 12183 * @param {Object} state Editor state. 12184 * 12185 * @return {Array} Multi-selected block objects. 12186 */ 12187 const getMultiSelectedBlocks = rememo(state => { 12188 const multiSelectedBlockClientIds = getMultiSelectedBlockClientIds(state); 12189 if (!multiSelectedBlockClientIds.length) { 12190 return EMPTY_ARRAY; 12191 } 12192 return multiSelectedBlockClientIds.map(clientId => getBlock(state, clientId)); 12193 }, state => [...getSelectedBlockClientIds.getDependants(state), state.blocks.byClientId, state.blocks.order, state.blocks.attributes]); 12194 12195 /** 12196 * Returns the client ID of the first block in the multi-selection set, or null 12197 * if there is no multi-selection. 12198 * 12199 * @param {Object} state Editor state. 12200 * 12201 * @return {?string} First block client ID in the multi-selection set. 12202 */ 12203 function getFirstMultiSelectedBlockClientId(state) { 12204 return getMultiSelectedBlockClientIds(state)[0] || null; 12205 } 12206 12207 /** 12208 * Returns the client ID of the last block in the multi-selection set, or null 12209 * if there is no multi-selection. 12210 * 12211 * @param {Object} state Editor state. 12212 * 12213 * @return {?string} Last block client ID in the multi-selection set. 12214 */ 12215 function getLastMultiSelectedBlockClientId(state) { 12216 const selectedClientIds = getMultiSelectedBlockClientIds(state); 12217 return selectedClientIds[selectedClientIds.length - 1] || null; 12218 } 12219 12220 /** 12221 * Returns true if a multi-selection exists, and the block corresponding to the 12222 * specified client ID is the first block of the multi-selection set, or false 12223 * otherwise. 12224 * 12225 * @param {Object} state Editor state. 12226 * @param {string} clientId Block client ID. 12227 * 12228 * @return {boolean} Whether block is first in multi-selection. 12229 */ 12230 function isFirstMultiSelectedBlock(state, clientId) { 12231 return getFirstMultiSelectedBlockClientId(state) === clientId; 12232 } 12233 12234 /** 12235 * Returns true if the client ID occurs within the block multi-selection, or 12236 * false otherwise. 12237 * 12238 * @param {Object} state Editor state. 12239 * @param {string} clientId Block client ID. 12240 * 12241 * @return {boolean} Whether block is in multi-selection set. 12242 */ 12243 function isBlockMultiSelected(state, clientId) { 12244 return getMultiSelectedBlockClientIds(state).indexOf(clientId) !== -1; 12245 } 12246 12247 /** 12248 * Returns true if an ancestor of the block is multi-selected, or false 12249 * otherwise. 12250 * 12251 * @param {Object} state Editor state. 12252 * @param {string} clientId Block client ID. 12253 * 12254 * @return {boolean} Whether an ancestor of the block is in multi-selection 12255 * set. 12256 */ 12257 const isAncestorMultiSelected = rememo((state, clientId) => { 12258 let ancestorClientId = clientId; 12259 let isMultiSelected = false; 12260 while (ancestorClientId && !isMultiSelected) { 12261 ancestorClientId = getBlockRootClientId(state, ancestorClientId); 12262 isMultiSelected = isBlockMultiSelected(state, ancestorClientId); 12263 } 12264 return isMultiSelected; 12265 }, state => [state.blocks.order, state.selection.selectionStart.clientId, state.selection.selectionEnd.clientId]); 12266 12267 /** 12268 * Returns the client ID of the block which begins the multi-selection set, or 12269 * null if there is no multi-selection. 12270 * 12271 * This is not necessarily the first client ID in the selection. 12272 * 12273 * @see getFirstMultiSelectedBlockClientId 12274 * 12275 * @param {Object} state Editor state. 12276 * 12277 * @return {?string} Client ID of block beginning multi-selection. 12278 */ 12279 function getMultiSelectedBlocksStartClientId(state) { 12280 const { 12281 selectionStart, 12282 selectionEnd 12283 } = state.selection; 12284 if (selectionStart.clientId === selectionEnd.clientId) { 12285 return null; 12286 } 12287 return selectionStart.clientId || null; 12288 } 12289 12290 /** 12291 * Returns the client ID of the block which ends the multi-selection set, or 12292 * null if there is no multi-selection. 12293 * 12294 * This is not necessarily the last client ID in the selection. 12295 * 12296 * @see getLastMultiSelectedBlockClientId 12297 * 12298 * @param {Object} state Editor state. 12299 * 12300 * @return {?string} Client ID of block ending multi-selection. 12301 */ 12302 function getMultiSelectedBlocksEndClientId(state) { 12303 const { 12304 selectionStart, 12305 selectionEnd 12306 } = state.selection; 12307 if (selectionStart.clientId === selectionEnd.clientId) { 12308 return null; 12309 } 12310 return selectionEnd.clientId || null; 12311 } 12312 12313 /** 12314 * Returns true if the selection is not partial. 12315 * 12316 * @param {Object} state Editor state. 12317 * 12318 * @return {boolean} Whether the selection is mergeable. 12319 */ 12320 function __unstableIsFullySelected(state) { 12321 const selectionAnchor = getSelectionStart(state); 12322 const selectionFocus = getSelectionEnd(state); 12323 return !selectionAnchor.attributeKey && !selectionFocus.attributeKey && typeof selectionAnchor.offset === 'undefined' && typeof selectionFocus.offset === 'undefined'; 12324 } 12325 12326 /** 12327 * Returns true if the selection is collapsed. 12328 * 12329 * @param {Object} state Editor state. 12330 * 12331 * @return {boolean} Whether the selection is collapsed. 12332 */ 12333 function __unstableIsSelectionCollapsed(state) { 12334 const selectionAnchor = getSelectionStart(state); 12335 const selectionFocus = getSelectionEnd(state); 12336 return !!selectionAnchor && !!selectionFocus && selectionAnchor.clientId === selectionFocus.clientId && selectionAnchor.attributeKey === selectionFocus.attributeKey && selectionAnchor.offset === selectionFocus.offset; 12337 } 12338 function __unstableSelectionHasUnmergeableBlock(state) { 12339 return getSelectedBlockClientIds(state).some(clientId => { 12340 const blockName = getBlockName(state, clientId); 12341 const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockName); 12342 return !blockType.merge; 12343 }); 12344 } 12345 12346 /** 12347 * Check whether the selection is mergeable. 12348 * 12349 * @param {Object} state Editor state. 12350 * @param {boolean} isForward Whether to merge forwards. 12351 * 12352 * @return {boolean} Whether the selection is mergeable. 12353 */ 12354 function __unstableIsSelectionMergeable(state, isForward) { 12355 const selectionAnchor = getSelectionStart(state); 12356 const selectionFocus = getSelectionEnd(state); 12357 12358 // It's not mergeable if the start and end are within the same block. 12359 if (selectionAnchor.clientId === selectionFocus.clientId) return false; 12360 12361 // It's not mergeable if there's no rich text selection. 12362 if (!selectionAnchor.attributeKey || !selectionFocus.attributeKey || typeof selectionAnchor.offset === 'undefined' || typeof selectionFocus.offset === 'undefined') return false; 12363 const anchorRootClientId = getBlockRootClientId(state, selectionAnchor.clientId); 12364 const focusRootClientId = getBlockRootClientId(state, selectionFocus.clientId); 12365 12366 // It's not mergeable if the selection doesn't start and end in the same 12367 // block list. Maybe in the future it should be allowed. 12368 if (anchorRootClientId !== focusRootClientId) { 12369 return false; 12370 } 12371 const blockOrder = getBlockOrder(state, anchorRootClientId); 12372 const anchorIndex = blockOrder.indexOf(selectionAnchor.clientId); 12373 const focusIndex = blockOrder.indexOf(selectionFocus.clientId); 12374 12375 // Reassign selection start and end based on order. 12376 let selectionStart, selectionEnd; 12377 if (anchorIndex > focusIndex) { 12378 selectionStart = selectionFocus; 12379 selectionEnd = selectionAnchor; 12380 } else { 12381 selectionStart = selectionAnchor; 12382 selectionEnd = selectionFocus; 12383 } 12384 const targetBlockClientId = isForward ? selectionEnd.clientId : selectionStart.clientId; 12385 const blockToMergeClientId = isForward ? selectionStart.clientId : selectionEnd.clientId; 12386 const targetBlockName = getBlockName(state, targetBlockClientId); 12387 const targetBlockType = (0,external_wp_blocks_namespaceObject.getBlockType)(targetBlockName); 12388 if (!targetBlockType.merge) return false; 12389 const blockToMerge = getBlock(state, blockToMergeClientId); 12390 12391 // It's mergeable if the blocks are of the same type. 12392 if (blockToMerge.name === targetBlockName) return true; 12393 12394 // If the blocks are of a different type, try to transform the block being 12395 // merged into the same type of block. 12396 const blocksToMerge = (0,external_wp_blocks_namespaceObject.switchToBlockType)(blockToMerge, targetBlockName); 12397 return blocksToMerge && blocksToMerge.length; 12398 } 12399 12400 /** 12401 * Get partial selected blocks with their content updated 12402 * based on the selection. 12403 * 12404 * @param {Object} state Editor state. 12405 * 12406 * @return {Object[]} Updated partial selected blocks. 12407 */ 12408 const __unstableGetSelectedBlocksWithPartialSelection = state => { 12409 const selectionAnchor = getSelectionStart(state); 12410 const selectionFocus = getSelectionEnd(state); 12411 if (selectionAnchor.clientId === selectionFocus.clientId) { 12412 return EMPTY_ARRAY; 12413 } 12414 12415 // Can't split if the selection is not set. 12416 if (!selectionAnchor.attributeKey || !selectionFocus.attributeKey || typeof selectionAnchor.offset === 'undefined' || typeof selectionFocus.offset === 'undefined') { 12417 return EMPTY_ARRAY; 12418 } 12419 const anchorRootClientId = getBlockRootClientId(state, selectionAnchor.clientId); 12420 const focusRootClientId = getBlockRootClientId(state, selectionFocus.clientId); 12421 12422 // It's not splittable if the selection doesn't start and end in the same 12423 // block list. Maybe in the future it should be allowed. 12424 if (anchorRootClientId !== focusRootClientId) { 12425 return EMPTY_ARRAY; 12426 } 12427 const blockOrder = getBlockOrder(state, anchorRootClientId); 12428 const anchorIndex = blockOrder.indexOf(selectionAnchor.clientId); 12429 const focusIndex = blockOrder.indexOf(selectionFocus.clientId); 12430 12431 // Reassign selection start and end based on order. 12432 const [selectionStart, selectionEnd] = anchorIndex > focusIndex ? [selectionFocus, selectionAnchor] : [selectionAnchor, selectionFocus]; 12433 const blockA = getBlock(state, selectionStart.clientId); 12434 const blockB = getBlock(state, selectionEnd.clientId); 12435 const htmlA = blockA.attributes[selectionStart.attributeKey]; 12436 const htmlB = blockB.attributes[selectionEnd.attributeKey]; 12437 let valueA = (0,external_wp_richText_namespaceObject.create)({ 12438 html: htmlA 12439 }); 12440 let valueB = (0,external_wp_richText_namespaceObject.create)({ 12441 html: htmlB 12442 }); 12443 valueA = (0,external_wp_richText_namespaceObject.remove)(valueA, 0, selectionStart.offset); 12444 valueB = (0,external_wp_richText_namespaceObject.remove)(valueB, selectionEnd.offset, valueB.text.length); 12445 return [{ 12446 ...blockA, 12447 attributes: { 12448 ...blockA.attributes, 12449 [selectionStart.attributeKey]: (0,external_wp_richText_namespaceObject.toHTMLString)({ 12450 value: valueA 12451 }) 12452 } 12453 }, { 12454 ...blockB, 12455 attributes: { 12456 ...blockB.attributes, 12457 [selectionEnd.attributeKey]: (0,external_wp_richText_namespaceObject.toHTMLString)({ 12458 value: valueB 12459 }) 12460 } 12461 }]; 12462 }; 12463 12464 /** 12465 * Returns an array containing all block client IDs in the editor in the order 12466 * they appear. Optionally accepts a root client ID of the block list for which 12467 * the order should be returned, defaulting to the top-level block order. 12468 * 12469 * @param {Object} state Editor state. 12470 * @param {?string} rootClientId Optional root client ID of block list. 12471 * 12472 * @return {Array} Ordered client IDs of editor blocks. 12473 */ 12474 function getBlockOrder(state, rootClientId) { 12475 return state.blocks.order.get(rootClientId || '') || EMPTY_ARRAY; 12476 } 12477 12478 /** 12479 * Returns the index at which the block corresponding to the specified client 12480 * ID occurs within the block order, or `-1` if the block does not exist. 12481 * 12482 * @param {Object} state Editor state. 12483 * @param {string} clientId Block client ID. 12484 * 12485 * @return {number} Index at which block exists in order. 12486 */ 12487 function getBlockIndex(state, clientId) { 12488 const rootClientId = getBlockRootClientId(state, clientId); 12489 return getBlockOrder(state, rootClientId).indexOf(clientId); 12490 } 12491 12492 /** 12493 * Returns true if the block corresponding to the specified client ID is 12494 * currently selected and no multi-selection exists, or false otherwise. 12495 * 12496 * @param {Object} state Editor state. 12497 * @param {string} clientId Block client ID. 12498 * 12499 * @return {boolean} Whether block is selected and multi-selection exists. 12500 */ 12501 function isBlockSelected(state, clientId) { 12502 const { 12503 selectionStart, 12504 selectionEnd 12505 } = state.selection; 12506 if (selectionStart.clientId !== selectionEnd.clientId) { 12507 return false; 12508 } 12509 return selectionStart.clientId === clientId; 12510 } 12511 12512 /** 12513 * Returns true if one of the block's inner blocks is selected. 12514 * 12515 * @param {Object} state Editor state. 12516 * @param {string} clientId Block client ID. 12517 * @param {boolean} deep Perform a deep check. 12518 * 12519 * @return {boolean} Whether the block has an inner block selected 12520 */ 12521 function hasSelectedInnerBlock(state, clientId, deep = false) { 12522 return getBlockOrder(state, clientId).some(innerClientId => isBlockSelected(state, innerClientId) || isBlockMultiSelected(state, innerClientId) || deep && hasSelectedInnerBlock(state, innerClientId, deep)); 12523 } 12524 12525 /** 12526 * Returns true if one of the block's inner blocks is dragged. 12527 * 12528 * @param {Object} state Editor state. 12529 * @param {string} clientId Block client ID. 12530 * @param {boolean} deep Perform a deep check. 12531 * 12532 * @return {boolean} Whether the block has an inner block dragged 12533 */ 12534 function hasDraggedInnerBlock(state, clientId, deep = false) { 12535 return getBlockOrder(state, clientId).some(innerClientId => isBlockBeingDragged(state, innerClientId) || deep && hasDraggedInnerBlock(state, innerClientId, deep)); 12536 } 12537 12538 /** 12539 * Returns true if the block corresponding to the specified client ID is 12540 * currently selected but isn't the last of the selected blocks. Here "last" 12541 * refers to the block sequence in the document, _not_ the sequence of 12542 * multi-selection, which is why `state.selectionEnd` isn't used. 12543 * 12544 * @param {Object} state Editor state. 12545 * @param {string} clientId Block client ID. 12546 * 12547 * @return {boolean} Whether block is selected and not the last in the 12548 * selection. 12549 */ 12550 function isBlockWithinSelection(state, clientId) { 12551 if (!clientId) { 12552 return false; 12553 } 12554 const clientIds = getMultiSelectedBlockClientIds(state); 12555 const index = clientIds.indexOf(clientId); 12556 return index > -1 && index < clientIds.length - 1; 12557 } 12558 12559 /** 12560 * Returns true if a multi-selection has been made, or false otherwise. 12561 * 12562 * @param {Object} state Editor state. 12563 * 12564 * @return {boolean} Whether multi-selection has been made. 12565 */ 12566 function hasMultiSelection(state) { 12567 const { 12568 selectionStart, 12569 selectionEnd 12570 } = state.selection; 12571 return selectionStart.clientId !== selectionEnd.clientId; 12572 } 12573 12574 /** 12575 * Whether in the process of multi-selecting or not. This flag is only true 12576 * while the multi-selection is being selected (by mouse move), and is false 12577 * once the multi-selection has been settled. 12578 * 12579 * @see hasMultiSelection 12580 * 12581 * @param {Object} state Global application state. 12582 * 12583 * @return {boolean} True if multi-selecting, false if not. 12584 */ 12585 function selectors_isMultiSelecting(state) { 12586 return state.isMultiSelecting; 12587 } 12588 12589 /** 12590 * Selector that returns if multi-selection is enabled or not. 12591 * 12592 * @param {Object} state Global application state. 12593 * 12594 * @return {boolean} True if it should be possible to multi-select blocks, false if multi-selection is disabled. 12595 */ 12596 function selectors_isSelectionEnabled(state) { 12597 return state.isSelectionEnabled; 12598 } 12599 12600 /** 12601 * Returns the block's editing mode, defaulting to "visual" if not explicitly 12602 * assigned. 12603 * 12604 * @param {Object} state Editor state. 12605 * @param {string} clientId Block client ID. 12606 * 12607 * @return {Object} Block editing mode. 12608 */ 12609 function getBlockMode(state, clientId) { 12610 return state.blocksMode[clientId] || 'visual'; 12611 } 12612 12613 /** 12614 * Returns true if the user is typing, or false otherwise. 12615 * 12616 * @param {Object} state Global application state. 12617 * 12618 * @return {boolean} Whether user is typing. 12619 */ 12620 function selectors_isTyping(state) { 12621 return state.isTyping; 12622 } 12623 12624 /** 12625 * Returns true if the user is dragging blocks, or false otherwise. 12626 * 12627 * @param {Object} state Global application state. 12628 * 12629 * @return {boolean} Whether user is dragging blocks. 12630 */ 12631 function isDraggingBlocks(state) { 12632 return !!state.draggedBlocks.length; 12633 } 12634 12635 /** 12636 * Returns the client ids of any blocks being directly dragged. 12637 * 12638 * This does not include children of a parent being dragged. 12639 * 12640 * @param {Object} state Global application state. 12641 * 12642 * @return {string[]} Array of dragged block client ids. 12643 */ 12644 function getDraggedBlockClientIds(state) { 12645 return state.draggedBlocks; 12646 } 12647 12648 /** 12649 * Returns whether the block is being dragged. 12650 * 12651 * Only returns true if the block is being directly dragged, 12652 * not if the block is a child of a parent being dragged. 12653 * See `isAncestorBeingDragged` for child blocks. 12654 * 12655 * @param {Object} state Global application state. 12656 * @param {string} clientId Client id for block to check. 12657 * 12658 * @return {boolean} Whether the block is being dragged. 12659 */ 12660 function isBlockBeingDragged(state, clientId) { 12661 return state.draggedBlocks.includes(clientId); 12662 } 12663 12664 /** 12665 * Returns whether a parent/ancestor of the block is being dragged. 12666 * 12667 * @param {Object} state Global application state. 12668 * @param {string} clientId Client id for block to check. 12669 * 12670 * @return {boolean} Whether the block's ancestor is being dragged. 12671 */ 12672 function isAncestorBeingDragged(state, clientId) { 12673 // Return early if no blocks are being dragged rather than 12674 // the more expensive check for parents. 12675 if (!isDraggingBlocks(state)) { 12676 return false; 12677 } 12678 const parents = getBlockParents(state, clientId); 12679 return parents.some(parentClientId => isBlockBeingDragged(state, parentClientId)); 12680 } 12681 12682 /** 12683 * Returns true if the caret is within formatted text, or false otherwise. 12684 * 12685 * @deprecated 12686 * 12687 * @return {boolean} Whether the caret is within formatted text. 12688 */ 12689 function isCaretWithinFormattedText() { 12690 external_wp_deprecated_default()('wp.data.select( "core/block-editor" ).isCaretWithinFormattedText', { 12691 since: '6.1', 12692 version: '6.3' 12693 }); 12694 return false; 12695 } 12696 12697 /** 12698 * Returns the insertion point, the index at which the new inserted block would 12699 * be placed. Defaults to the last index. 12700 * 12701 * @param {Object} state Editor state. 12702 * 12703 * @return {Object} Insertion point object with `rootClientId`, `index`. 12704 */ 12705 const getBlockInsertionPoint = rememo(state => { 12706 let rootClientId, index; 12707 const { 12708 insertionPoint, 12709 selection: { 12710 selectionEnd 12711 } 12712 } = state; 12713 if (insertionPoint !== null) { 12714 return insertionPoint; 12715 } 12716 const { 12717 clientId 12718 } = selectionEnd; 12719 if (clientId) { 12720 rootClientId = getBlockRootClientId(state, clientId) || undefined; 12721 index = getBlockIndex(state, selectionEnd.clientId) + 1; 12722 } else { 12723 index = getBlockOrder(state).length; 12724 } 12725 return { 12726 rootClientId, 12727 index 12728 }; 12729 }, state => [state.insertionPoint, state.selection.selectionEnd.clientId, state.blocks.parents, state.blocks.order]); 12730 12731 /** 12732 * Returns true if we should show the block insertion point. 12733 * 12734 * @param {Object} state Global application state. 12735 * 12736 * @return {?boolean} Whether the insertion point is visible or not. 12737 */ 12738 function isBlockInsertionPointVisible(state) { 12739 return state.insertionPoint !== null; 12740 } 12741 12742 /** 12743 * Returns whether the blocks matches the template or not. 12744 * 12745 * @param {boolean} state 12746 * @return {?boolean} Whether the template is valid or not. 12747 */ 12748 function isValidTemplate(state) { 12749 return state.template.isValid; 12750 } 12751 12752 /** 12753 * Returns the defined block template 12754 * 12755 * @param {boolean} state 12756 * 12757 * @return {?Array} Block Template. 12758 */ 12759 function getTemplate(state) { 12760 return state.settings.template; 12761 } 12762 12763 /** 12764 * Returns the defined block template lock. Optionally accepts a root block 12765 * client ID as context, otherwise defaulting to the global context. 12766 * 12767 * @param {Object} state Editor state. 12768 * @param {?string} rootClientId Optional block root client ID. 12769 * 12770 * @return {string|false} Block Template Lock 12771 */ 12772 function getTemplateLock(state, rootClientId) { 12773 var _getBlockListSettings; 12774 if (!rootClientId) { 12775 var _state$settings$templ; 12776 return (_state$settings$templ = state.settings.templateLock) !== null && _state$settings$templ !== void 0 ? _state$settings$templ : false; 12777 } 12778 return (_getBlockListSettings = getBlockListSettings(state, rootClientId)?.templateLock) !== null && _getBlockListSettings !== void 0 ? _getBlockListSettings : false; 12779 } 12780 12781 /** 12782 * Determines if the given block type is allowed to be inserted into the block list. 12783 * This function is not exported and not memoized because using a memoized selector 12784 * inside another memoized selector is just a waste of time. 12785 * 12786 * @param {Object} state Editor state. 12787 * @param {string|Object} blockName The block type object, e.g., the response 12788 * from the block directory; or a string name of 12789 * an installed block type, e.g.' core/paragraph'. 12790 * @param {?string} rootClientId Optional root client ID of block list. 12791 * 12792 * @return {boolean} Whether the given block type is allowed to be inserted. 12793 */ 12794 const canInsertBlockTypeUnmemoized = (state, blockName, rootClientId = null) => { 12795 let blockType; 12796 if (blockName && 'object' === typeof blockName) { 12797 blockType = blockName; 12798 blockName = blockType.name; 12799 } else { 12800 blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockName); 12801 } 12802 if (!blockType) { 12803 return false; 12804 } 12805 const { 12806 allowedBlockTypes 12807 } = getSettings(state); 12808 const isBlockAllowedInEditor = checkAllowList(allowedBlockTypes, blockName, true); 12809 if (!isBlockAllowedInEditor) { 12810 return false; 12811 } 12812 const isLocked = !!getTemplateLock(state, rootClientId); 12813 if (isLocked) { 12814 return false; 12815 } 12816 if (getBlockEditingMode(state, rootClientId !== null && rootClientId !== void 0 ? rootClientId : '') === 'disabled') { 12817 return false; 12818 } 12819 const parentBlockListSettings = getBlockListSettings(state, rootClientId); 12820 12821 // The parent block doesn't have settings indicating it doesn't support 12822 // inner blocks, return false. 12823 if (rootClientId && parentBlockListSettings === undefined) { 12824 return false; 12825 } 12826 const parentName = getBlockName(state, rootClientId); 12827 const parentBlockType = (0,external_wp_blocks_namespaceObject.getBlockType)(parentName); 12828 12829 // Look at the `blockType.allowedBlocks` field to determine whether this is an allowed child block. 12830 const parentAllowedChildBlocks = parentBlockType?.allowedBlocks; 12831 let hasParentAllowedBlock = checkAllowList(parentAllowedChildBlocks, blockName); 12832 12833 // The `allowedBlocks` block list setting can further limit which blocks are allowed children. 12834 if (hasParentAllowedBlock !== false) { 12835 const parentAllowedBlocks = parentBlockListSettings?.allowedBlocks; 12836 const hasParentListAllowedBlock = checkAllowList(parentAllowedBlocks, blockName); 12837 // Never downgrade the result from `true` to `null` 12838 if (hasParentListAllowedBlock !== null) { 12839 hasParentAllowedBlock = hasParentListAllowedBlock; 12840 } 12841 } 12842 const blockAllowedParentBlocks = blockType.parent; 12843 const hasBlockAllowedParent = checkAllowList(blockAllowedParentBlocks, parentName); 12844 let hasBlockAllowedAncestor = true; 12845 const blockAllowedAncestorBlocks = blockType.ancestor; 12846 if (blockAllowedAncestorBlocks) { 12847 const ancestors = [rootClientId, ...getBlockParents(state, rootClientId)]; 12848 hasBlockAllowedAncestor = ancestors.some(ancestorClientId => checkAllowList(blockAllowedAncestorBlocks, getBlockName(state, ancestorClientId))); 12849 } 12850 const canInsert = hasBlockAllowedAncestor && (hasParentAllowedBlock === null && hasBlockAllowedParent === null || hasParentAllowedBlock === true || hasBlockAllowedParent === true); 12851 if (!canInsert) { 12852 return canInsert; 12853 } 12854 12855 /** 12856 * This filter is an ad-hoc solution to prevent adding template parts inside post content. 12857 * Conceptually, having a filter inside a selector is bad pattern so this code will be 12858 * replaced by a declarative API that doesn't the following drawbacks: 12859 * 12860 * Filters are not reactive: Upon switching between "template mode" and non "template mode", 12861 * the filter and selector won't necessarily be executed again. For now, it doesn't matter much 12862 * because you can't switch between the two modes while the inserter stays open. 12863 * 12864 * Filters are global: Once they're defined, they will affect all editor instances and all registries. 12865 * An ideal API would only affect specific editor instances. 12866 */ 12867 return (0,external_wp_hooks_namespaceObject.applyFilters)('blockEditor.__unstableCanInsertBlockType', canInsert, blockType, rootClientId, { 12868 // Pass bound selectors of the current registry. If we're in a nested 12869 // context, the data will differ from the one selected from the root 12870 // registry. 12871 getBlock: getBlock.bind(null, state), 12872 getBlockParentsByBlockName: getBlockParentsByBlockName.bind(null, state) 12873 }); 12874 }; 12875 12876 /** 12877 * Determines if the given block type is allowed to be inserted into the block list. 12878 * 12879 * @param {Object} state Editor state. 12880 * @param {string} blockName The name of the block type, e.g.' core/paragraph'. 12881 * @param {?string} rootClientId Optional root client ID of block list. 12882 * 12883 * @return {boolean} Whether the given block type is allowed to be inserted. 12884 */ 12885 const canInsertBlockType = rememo(canInsertBlockTypeUnmemoized, (state, blockName, rootClientId) => [state.blockListSettings[rootClientId], state.blocks.byClientId.get(rootClientId), state.settings.allowedBlockTypes, state.settings.templateLock, state.blockEditingModes]); 12886 12887 /** 12888 * Determines if the given blocks are allowed to be inserted into the block 12889 * list. 12890 * 12891 * @param {Object} state Editor state. 12892 * @param {string} clientIds The block client IDs to be inserted. 12893 * @param {?string} rootClientId Optional root client ID of block list. 12894 * 12895 * @return {boolean} Whether the given blocks are allowed to be inserted. 12896 */ 12897 function canInsertBlocks(state, clientIds, rootClientId = null) { 12898 return clientIds.every(id => canInsertBlockType(state, getBlockName(state, id), rootClientId)); 12899 } 12900 12901 /** 12902 * Determines if the given block is allowed to be deleted. 12903 * 12904 * @param {Object} state Editor state. 12905 * @param {string} clientId The block client Id. 12906 * @param {?string} rootClientId Optional root client ID of block list. 12907 * 12908 * @return {boolean} Whether the given block is allowed to be removed. 12909 */ 12910 function canRemoveBlock(state, clientId, rootClientId = null) { 12911 const attributes = getBlockAttributes(state, clientId); 12912 if (attributes === null) { 12913 return true; 12914 } 12915 if (attributes.lock?.remove !== undefined) { 12916 return !attributes.lock.remove; 12917 } 12918 if (getTemplateLock(state, rootClientId)) { 12919 return false; 12920 } 12921 return getBlockEditingMode(state, rootClientId) !== 'disabled'; 12922 } 12923 12924 /** 12925 * Determines if the given blocks are allowed to be removed. 12926 * 12927 * @param {Object} state Editor state. 12928 * @param {string} clientIds The block client IDs to be removed. 12929 * @param {?string} rootClientId Optional root client ID of block list. 12930 * 12931 * @return {boolean} Whether the given blocks are allowed to be removed. 12932 */ 12933 function canRemoveBlocks(state, clientIds, rootClientId = null) { 12934 return clientIds.every(clientId => canRemoveBlock(state, clientId, rootClientId)); 12935 } 12936 12937 /** 12938 * Determines if the given block is allowed to be moved. 12939 * 12940 * @param {Object} state Editor state. 12941 * @param {string} clientId The block client Id. 12942 * @param {?string} rootClientId Optional root client ID of block list. 12943 * 12944 * @return {boolean | undefined} Whether the given block is allowed to be moved. 12945 */ 12946 function canMoveBlock(state, clientId, rootClientId = null) { 12947 const attributes = getBlockAttributes(state, clientId); 12948 if (attributes === null) { 12949 return true; 12950 } 12951 if (attributes.lock?.move !== undefined) { 12952 return !attributes.lock.move; 12953 } 12954 if (getTemplateLock(state, rootClientId) === 'all') { 12955 return false; 12956 } 12957 return getBlockEditingMode(state, rootClientId) !== 'disabled'; 12958 } 12959 12960 /** 12961 * Determines if the given blocks are allowed to be moved. 12962 * 12963 * @param {Object} state Editor state. 12964 * @param {string} clientIds The block client IDs to be moved. 12965 * @param {?string} rootClientId Optional root client ID of block list. 12966 * 12967 * @return {boolean} Whether the given blocks are allowed to be moved. 12968 */ 12969 function canMoveBlocks(state, clientIds, rootClientId = null) { 12970 return clientIds.every(clientId => canMoveBlock(state, clientId, rootClientId)); 12971 } 12972 12973 /** 12974 * Determines if the given block is allowed to be edited. 12975 * 12976 * @param {Object} state Editor state. 12977 * @param {string} clientId The block client Id. 12978 * 12979 * @return {boolean} Whether the given block is allowed to be edited. 12980 */ 12981 function canEditBlock(state, clientId) { 12982 const attributes = getBlockAttributes(state, clientId); 12983 if (attributes === null) { 12984 return true; 12985 } 12986 const { 12987 lock 12988 } = attributes; 12989 12990 // When the edit is true, we cannot edit the block. 12991 return !lock?.edit; 12992 } 12993 12994 /** 12995 * Determines if the given block type can be locked/unlocked by a user. 12996 * 12997 * @param {Object} state Editor state. 12998 * @param {(string|Object)} nameOrType Block name or type object. 12999 * 13000 * @return {boolean} Whether a given block type can be locked/unlocked. 13001 */ 13002 function canLockBlockType(state, nameOrType) { 13003 if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(nameOrType, 'lock', true)) { 13004 return false; 13005 } 13006 13007 // Use block editor settings as the default value. 13008 return !!state.settings?.canLockBlocks; 13009 } 13010 13011 /** 13012 * Returns information about how recently and frequently a block has been inserted. 13013 * 13014 * @param {Object} state Global application state. 13015 * @param {string} id A string which identifies the insert, e.g. 'core/block/12' 13016 * 13017 * @return {?{ time: number, count: number }} An object containing `time` which is when the last 13018 * insert occurred as a UNIX epoch, and `count` which is 13019 * the number of inserts that have occurred. 13020 */ 13021 function getInsertUsage(state, id) { 13022 var _state$preferences$in; 13023 return (_state$preferences$in = state.preferences.insertUsage?.[id]) !== null && _state$preferences$in !== void 0 ? _state$preferences$in : null; 13024 } 13025 13026 /** 13027 * Returns whether we can show a block type in the inserter 13028 * 13029 * @param {Object} state Global State 13030 * @param {Object} blockType BlockType 13031 * @param {?string} rootClientId Optional root client ID of block list. 13032 * 13033 * @return {boolean} Whether the given block type is allowed to be shown in the inserter. 13034 */ 13035 const canIncludeBlockTypeInInserter = (state, blockType, rootClientId) => { 13036 if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, 'inserter', true)) { 13037 return false; 13038 } 13039 return canInsertBlockTypeUnmemoized(state, blockType.name, rootClientId); 13040 }; 13041 13042 /** 13043 * Return a function to be used to tranform a block variation to an inserter item 13044 * 13045 * @param {Object} state Global State 13046 * @param {Object} item Denormalized inserter item 13047 * @return {Function} Function to transform a block variation to inserter item 13048 */ 13049 const getItemFromVariation = (state, item) => variation => { 13050 const variationId = `$item.id}/$variation.name}`; 13051 const { 13052 time, 13053 count = 0 13054 } = getInsertUsage(state, variationId) || {}; 13055 return { 13056 ...item, 13057 id: variationId, 13058 icon: variation.icon || item.icon, 13059 title: variation.title || item.title, 13060 description: variation.description || item.description, 13061 category: variation.category || item.category, 13062 // If `example` is explicitly undefined for the variation, the preview will not be shown. 13063 example: variation.hasOwnProperty('example') ? variation.example : item.example, 13064 initialAttributes: { 13065 ...item.initialAttributes, 13066 ...variation.attributes 13067 }, 13068 innerBlocks: variation.innerBlocks, 13069 keywords: variation.keywords || item.keywords, 13070 frecency: calculateFrecency(time, count) 13071 }; 13072 }; 13073 13074 /** 13075 * Returns the calculated frecency. 13076 * 13077 * 'frecency' is a heuristic (https://en.wikipedia.org/wiki/Frecency) 13078 * that combines block usage frequenty and recency. 13079 * 13080 * @param {number} time When the last insert occurred as a UNIX epoch 13081 * @param {number} count The number of inserts that have occurred. 13082 * 13083 * @return {number} The calculated frecency. 13084 */ 13085 const calculateFrecency = (time, count) => { 13086 if (!time) { 13087 return count; 13088 } 13089 // The selector is cached, which means Date.now() is the last time that the 13090 // relevant state changed. This suits our needs. 13091 const duration = Date.now() - time; 13092 switch (true) { 13093 case duration < MILLISECONDS_PER_HOUR: 13094 return count * 4; 13095 case duration < MILLISECONDS_PER_DAY: 13096 return count * 2; 13097 case duration < MILLISECONDS_PER_WEEK: 13098 return count / 2; 13099 default: 13100 return count / 4; 13101 } 13102 }; 13103 13104 /** 13105 * Returns a function that accepts a block type and builds an item to be shown 13106 * in a specific context. It's used for building items for Inserter and available 13107 * block Transfroms list. 13108 * 13109 * @param {Object} state Editor state. 13110 * @param {Object} options Options object for handling the building of a block type. 13111 * @param {string} options.buildScope The scope for which the item is going to be used. 13112 * @return {Function} Function returns an item to be shown in a specific context (Inserter|Transforms list). 13113 */ 13114 const buildBlockTypeItem = (state, { 13115 buildScope = 'inserter' 13116 }) => blockType => { 13117 const id = blockType.name; 13118 let isDisabled = false; 13119 if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType.name, 'multiple', true)) { 13120 isDisabled = getBlocksByClientId(state, getClientIdsWithDescendants(state)).some(({ 13121 name 13122 }) => name === blockType.name); 13123 } 13124 const { 13125 time, 13126 count = 0 13127 } = getInsertUsage(state, id) || {}; 13128 const blockItemBase = { 13129 id, 13130 name: blockType.name, 13131 title: blockType.title, 13132 icon: blockType.icon, 13133 isDisabled, 13134 frecency: calculateFrecency(time, count) 13135 }; 13136 if (buildScope === 'transform') return blockItemBase; 13137 const inserterVariations = (0,external_wp_blocks_namespaceObject.getBlockVariations)(blockType.name, 'inserter'); 13138 return { 13139 ...blockItemBase, 13140 initialAttributes: {}, 13141 description: blockType.description, 13142 category: blockType.category, 13143 keywords: blockType.keywords, 13144 variations: inserterVariations, 13145 example: blockType.example, 13146 utility: 1 // Deprecated. 13147 }; 13148 }; 13149 13150 /** 13151 * Determines the items that appear in the inserter. Includes both static 13152 * items (e.g. a regular block type) and dynamic items (e.g. a reusable block). 13153 * 13154 * Each item object contains what's necessary to display a button in the 13155 * inserter and handle its selection. 13156 * 13157 * The 'frecency' property is a heuristic (https://en.wikipedia.org/wiki/Frecency) 13158 * that combines block usage frequenty and recency. 13159 * 13160 * Items are returned ordered descendingly by their 'utility' and 'frecency'. 13161 * 13162 * @param {Object} state Editor state. 13163 * @param {?string} rootClientId Optional root client ID of block list. 13164 * 13165 * @return {WPEditorInserterItem[]} Items that appear in inserter. 13166 * 13167 * @typedef {Object} WPEditorInserterItem 13168 * @property {string} id Unique identifier for the item. 13169 * @property {string} name The type of block to create. 13170 * @property {Object} initialAttributes Attributes to pass to the newly created block. 13171 * @property {string} title Title of the item, as it appears in the inserter. 13172 * @property {string} icon Dashicon for the item, as it appears in the inserter. 13173 * @property {string} category Block category that the item is associated with. 13174 * @property {string[]} keywords Keywords that can be searched to find this item. 13175 * @property {boolean} isDisabled Whether or not the user should be prevented from inserting 13176 * this item. 13177 * @property {number} frecency Heuristic that combines frequency and recency. 13178 */ 13179 const getInserterItems = rememo((state, rootClientId = null) => { 13180 const buildReusableBlockInserterItem = reusableBlock => { 13181 const icon = !reusableBlock.wp_pattern_sync_status ? { 13182 src: library_symbol, 13183 foreground: 'var(--wp-block-synced-color)' 13184 } : library_symbol; 13185 const id = `core/block/$reusableBlock.id}`; 13186 const { 13187 time, 13188 count = 0 13189 } = getInsertUsage(state, id) || {}; 13190 const frecency = calculateFrecency(time, count); 13191 return { 13192 id, 13193 name: 'core/block', 13194 initialAttributes: { 13195 ref: reusableBlock.id 13196 }, 13197 title: reusableBlock.title?.raw, 13198 icon, 13199 category: 'reusable', 13200 keywords: ['reusable'], 13201 isDisabled: false, 13202 utility: 1, 13203 // Deprecated. 13204 frecency, 13205 content: reusableBlock.content?.raw, 13206 syncStatus: reusableBlock.wp_pattern_sync_status 13207 }; 13208 }; 13209 const syncedPatternInserterItems = canInsertBlockTypeUnmemoized(state, 'core/block', rootClientId) ? getReusableBlocks(state).map(buildReusableBlockInserterItem) : []; 13210 const buildBlockTypeInserterItem = buildBlockTypeItem(state, { 13211 buildScope: 'inserter' 13212 }); 13213 const blockTypeInserterItems = (0,external_wp_blocks_namespaceObject.getBlockTypes)().filter(blockType => canIncludeBlockTypeInInserter(state, blockType, rootClientId)).map(buildBlockTypeInserterItem); 13214 const items = blockTypeInserterItems.reduce((accumulator, item) => { 13215 const { 13216 variations = [] 13217 } = item; 13218 // Exclude any block type item that is to be replaced by a default variation. 13219 if (!variations.some(({ 13220 isDefault 13221 }) => isDefault)) { 13222 accumulator.push(item); 13223 } 13224 if (variations.length) { 13225 const variationMapper = getItemFromVariation(state, item); 13226 accumulator.push(...variations.map(variationMapper)); 13227 } 13228 return accumulator; 13229 }, []); 13230 13231 // Ensure core blocks are prioritized in the returned results, 13232 // because third party blocks can be registered earlier than 13233 // the core blocks (usually by using the `init` action), 13234 // thus affecting the display order. 13235 // We don't sort reusable blocks as they are handled differently. 13236 const groupByType = (blocks, block) => { 13237 const { 13238 core, 13239 noncore 13240 } = blocks; 13241 const type = block.name.startsWith('core/') ? core : noncore; 13242 type.push(block); 13243 return blocks; 13244 }; 13245 const { 13246 core: coreItems, 13247 noncore: nonCoreItems 13248 } = items.reduce(groupByType, { 13249 core: [], 13250 noncore: [] 13251 }); 13252 const sortedBlockTypes = [...coreItems, ...nonCoreItems]; 13253 return [...sortedBlockTypes, ...syncedPatternInserterItems]; 13254 }, (state, rootClientId) => [state.blockListSettings[rootClientId], state.blocks.byClientId.get(rootClientId), state.blocks.order, state.preferences.insertUsage, state.settings.allowedBlockTypes, state.settings.templateLock, getReusableBlocks(state), (0,external_wp_blocks_namespaceObject.getBlockTypes)()]); 13255 13256 /** 13257 * Determines the items that appear in the available block transforms list. 13258 * 13259 * Each item object contains what's necessary to display a menu item in the 13260 * transform list and handle its selection. 13261 * 13262 * The 'frecency' property is a heuristic (https://en.wikipedia.org/wiki/Frecency) 13263 * that combines block usage frequenty and recency. 13264 * 13265 * Items are returned ordered descendingly by their 'frecency'. 13266 * 13267 * @param {Object} state Editor state. 13268 * @param {Object|Object[]} blocks Block object or array objects. 13269 * @param {?string} rootClientId Optional root client ID of block list. 13270 * 13271 * @return {WPEditorTransformItem[]} Items that appear in inserter. 13272 * 13273 * @typedef {Object} WPEditorTransformItem 13274 * @property {string} id Unique identifier for the item. 13275 * @property {string} name The type of block to create. 13276 * @property {string} title Title of the item, as it appears in the inserter. 13277 * @property {string} icon Dashicon for the item, as it appears in the inserter. 13278 * @property {boolean} isDisabled Whether or not the user should be prevented from inserting 13279 * this item. 13280 * @property {number} frecency Heuristic that combines frequency and recency. 13281 */ 13282 const getBlockTransformItems = rememo((state, blocks, rootClientId = null) => { 13283 const normalizedBlocks = Array.isArray(blocks) ? blocks : [blocks]; 13284 const buildBlockTypeTransformItem = buildBlockTypeItem(state, { 13285 buildScope: 'transform' 13286 }); 13287 const blockTypeTransformItems = (0,external_wp_blocks_namespaceObject.getBlockTypes)().filter(blockType => canIncludeBlockTypeInInserter(state, blockType, rootClientId)).map(buildBlockTypeTransformItem); 13288 const itemsByName = Object.fromEntries(Object.entries(blockTypeTransformItems).map(([, value]) => [value.name, value])); 13289 const possibleTransforms = (0,external_wp_blocks_namespaceObject.getPossibleBlockTransformations)(normalizedBlocks).reduce((accumulator, block) => { 13290 if (itemsByName[block?.name]) { 13291 accumulator.push(itemsByName[block.name]); 13292 } 13293 return accumulator; 13294 }, []); 13295 return orderBy(possibleTransforms, block => itemsByName[block.name].frecency, 'desc'); 13296 }, (state, blocks, rootClientId) => [state.blockListSettings[rootClientId], state.blocks.byClientId.get(rootClientId), state.preferences.insertUsage, state.settings.allowedBlockTypes, state.settings.templateLock, (0,external_wp_blocks_namespaceObject.getBlockTypes)()]); 13297 13298 /** 13299 * Determines whether there are items to show in the inserter. 13300 * 13301 * @param {Object} state Editor state. 13302 * @param {?string} rootClientId Optional root client ID of block list. 13303 * 13304 * @return {boolean} Items that appear in inserter. 13305 */ 13306 const hasInserterItems = rememo((state, rootClientId = null) => { 13307 const hasBlockType = (0,external_wp_blocks_namespaceObject.getBlockTypes)().some(blockType => canIncludeBlockTypeInInserter(state, blockType, rootClientId)); 13308 if (hasBlockType) { 13309 return true; 13310 } 13311 const hasReusableBlock = canInsertBlockTypeUnmemoized(state, 'core/block', rootClientId) && getReusableBlocks(state).length > 0; 13312 return hasReusableBlock; 13313 }, (state, rootClientId) => [state.blockListSettings[rootClientId], state.blocks.byClientId.get(rootClientId), state.settings.allowedBlockTypes, state.settings.templateLock, getReusableBlocks(state), (0,external_wp_blocks_namespaceObject.getBlockTypes)()]); 13314 13315 /** 13316 * Returns the list of allowed inserter blocks for inner blocks children. 13317 * 13318 * @param {Object} state Editor state. 13319 * @param {?string} rootClientId Optional root client ID of block list. 13320 * 13321 * @return {Array?} The list of allowed block types. 13322 */ 13323 const getAllowedBlocks = rememo((state, rootClientId = null) => { 13324 if (!rootClientId) { 13325 return; 13326 } 13327 const blockTypes = (0,external_wp_blocks_namespaceObject.getBlockTypes)().filter(blockType => canIncludeBlockTypeInInserter(state, blockType, rootClientId)); 13328 const hasReusableBlock = canInsertBlockTypeUnmemoized(state, 'core/block', rootClientId) && getReusableBlocks(state).length > 0; 13329 if (hasReusableBlock) { 13330 blockTypes.push('core/block'); 13331 } 13332 return blockTypes; 13333 }, (state, rootClientId) => [state.blockListSettings[rootClientId], state.blocks.byClientId.get(rootClientId), state.settings.allowedBlockTypes, state.settings.templateLock, getReusableBlocks(state), (0,external_wp_blocks_namespaceObject.getBlockTypes)()]); 13334 const __experimentalGetAllowedBlocks = rememo((state, rootClientId = null) => { 13335 external_wp_deprecated_default()('wp.data.select( "core/block-editor" ).__experimentalGetAllowedBlocks', { 13336 alternative: 'wp.data.select( "core/block-editor" ).getAllowedBlocks', 13337 since: '6.2', 13338 version: '6.4' 13339 }); 13340 return getAllowedBlocks(state, rootClientId); 13341 }, (state, rootClientId) => [...getAllowedBlocks.getDependants(state, rootClientId)]); 13342 13343 /** 13344 * Returns the block to be directly inserted by the block appender. 13345 * 13346 * @param {Object} state Editor state. 13347 * @param {?string} rootClientId Optional root client ID of block list. 13348 * 13349 * @return {?WPDirectInsertBlock} The block type to be directly inserted. 13350 * 13351 * @typedef {Object} WPDirectInsertBlock 13352 * @property {string} name The type of block. 13353 * @property {?Object} attributes Attributes to pass to the newly created block. 13354 * @property {?Array<string>} attributesToCopy Attributes to be copied from adjecent blocks when inserted. 13355 */ 13356 const getDirectInsertBlock = rememo((state, rootClientId = null) => { 13357 if (!rootClientId) { 13358 return; 13359 } 13360 const defaultBlock = state.blockListSettings[rootClientId]?.defaultBlock; 13361 const directInsert = state.blockListSettings[rootClientId]?.directInsert; 13362 if (!defaultBlock || !directInsert) { 13363 return; 13364 } 13365 if (typeof directInsert === 'function') { 13366 return directInsert(getBlock(state, rootClientId)) ? defaultBlock : null; 13367 } 13368 return defaultBlock; 13369 }, (state, rootClientId) => [state.blockListSettings[rootClientId], state.blocks.tree.get(rootClientId)]); 13370 const __experimentalGetDirectInsertBlock = rememo((state, rootClientId = null) => { 13371 external_wp_deprecated_default()('wp.data.select( "core/block-editor" ).__experimentalGetDirectInsertBlock', { 13372 alternative: 'wp.data.select( "core/block-editor" ).getDirectInsertBlock', 13373 since: '6.3', 13374 version: '6.4' 13375 }); 13376 return getDirectInsertBlock(state, rootClientId); 13377 }, (state, rootClientId) => [state.blockListSettings[rootClientId], state.blocks.tree.get(rootClientId)]); 13378 const __experimentalGetParsedPattern = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => rememo((state, patternName) => { 13379 const { 13380 getAllPatterns 13381 } = unlock(select(STORE_NAME)); 13382 const patterns = getAllPatterns(); 13383 const pattern = patterns.find(({ 13384 name 13385 }) => name === patternName); 13386 if (!pattern) { 13387 return null; 13388 } 13389 return { 13390 ...pattern, 13391 blocks: (0,external_wp_blocks_namespaceObject.parse)(pattern.content, { 13392 __unstableSkipMigrationLogs: true 13393 }) 13394 }; 13395 }, getAllPatternsDependants(select))); 13396 const getAllowedPatternsDependants = select => (state, rootClientId) => { 13397 return [...getAllPatternsDependants(select)(state), state.settings.allowedBlockTypes, state.settings.templateLock, state.blockListSettings[rootClientId], state.blocks.byClientId.get(rootClientId)]; 13398 }; 13399 13400 /** 13401 * Returns the list of allowed patterns for inner blocks children. 13402 * 13403 * @param {Object} state Editor state. 13404 * @param {?string} rootClientId Optional target root client ID. 13405 * 13406 * @return {Array?} The list of allowed patterns. 13407 */ 13408 const __experimentalGetAllowedPatterns = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => { 13409 return rememo((state, rootClientId = null) => { 13410 const { 13411 getAllPatterns, 13412 __experimentalGetParsedPattern: getParsedPattern 13413 } = unlock(select(STORE_NAME)); 13414 const patterns = getAllPatterns(); 13415 const { 13416 allowedBlockTypes 13417 } = getSettings(state); 13418 const parsedPatterns = patterns.filter(({ 13419 inserter = true 13420 }) => !!inserter).map(({ 13421 name 13422 }) => getParsedPattern(name)); 13423 const availableParsedPatterns = parsedPatterns.filter(({ 13424 blocks 13425 }) => checkAllowListRecursive(blocks, allowedBlockTypes)); 13426 const patternsAllowed = availableParsedPatterns.filter(({ 13427 blocks 13428 }) => blocks.every(({ 13429 name 13430 }) => canInsertBlockType(state, name, rootClientId))); 13431 return patternsAllowed; 13432 }, getAllowedPatternsDependants(select)); 13433 }); 13434 13435 /** 13436 * Returns the list of patterns based on their declared `blockTypes` 13437 * and a block's name. 13438 * Patterns can use `blockTypes` to integrate in work flows like 13439 * suggesting appropriate patterns in a Placeholder state(during insertion) 13440 * or blocks transformations. 13441 * 13442 * @param {Object} state Editor state. 13443 * @param {string|string[]} blockNames Block's name or array of block names to find matching pattens. 13444 * @param {?string} rootClientId Optional target root client ID. 13445 * 13446 * @return {Array} The list of matched block patterns based on declared `blockTypes` and block name. 13447 */ 13448 const getPatternsByBlockTypes = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => rememo((state, blockNames, rootClientId = null) => { 13449 if (!blockNames) return EMPTY_ARRAY; 13450 const patterns = select(STORE_NAME).__experimentalGetAllowedPatterns(rootClientId); 13451 const normalizedBlockNames = Array.isArray(blockNames) ? blockNames : [blockNames]; 13452 const filteredPatterns = patterns.filter(pattern => pattern?.blockTypes?.some?.(blockName => normalizedBlockNames.includes(blockName))); 13453 if (filteredPatterns.length === 0) { 13454 return EMPTY_ARRAY; 13455 } 13456 return filteredPatterns; 13457 }, (state, blockNames, rootClientId) => getAllowedPatternsDependants(select)(state, rootClientId))); 13458 const __experimentalGetPatternsByBlockTypes = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => { 13459 external_wp_deprecated_default()('wp.data.select( "core/block-editor" ).__experimentalGetPatternsByBlockTypes', { 13460 alternative: 'wp.data.select( "core/block-editor" ).getPatternsByBlockTypes', 13461 since: '6.2', 13462 version: '6.4' 13463 }); 13464 return select(STORE_NAME).getPatternsByBlockTypes; 13465 }); 13466 13467 /** 13468 * Determines the items that appear in the available pattern transforms list. 13469 * 13470 * For now we only handle blocks without InnerBlocks and take into account 13471 * the `__experimentalRole` property of blocks' attributes for the transformation. 13472 * 13473 * We return the first set of possible eligible block patterns, 13474 * by checking the `blockTypes` property. We still have to recurse through 13475 * block pattern's blocks and try to find matches from the selected blocks. 13476 * Now this happens in the consumer to avoid heavy operations in the selector. 13477 * 13478 * @param {Object} state Editor state. 13479 * @param {Object[]} blocks The selected blocks. 13480 * @param {?string} rootClientId Optional root client ID of block list. 13481 * 13482 * @return {WPBlockPattern[]} Items that are eligible for a pattern transformation. 13483 */ 13484 const __experimentalGetPatternTransformItems = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => rememo((state, blocks, rootClientId = null) => { 13485 if (!blocks) return EMPTY_ARRAY; 13486 /** 13487 * For now we only handle blocks without InnerBlocks and take into account 13488 * the `__experimentalRole` property of blocks' attributes for the transformation. 13489 * Note that the blocks have been retrieved through `getBlock`, which doesn't 13490 * return the inner blocks of an inner block controller, so we still need 13491 * to check for this case too. 13492 */ 13493 if (blocks.some(({ 13494 clientId, 13495 innerBlocks 13496 }) => innerBlocks.length || areInnerBlocksControlled(state, clientId))) { 13497 return EMPTY_ARRAY; 13498 } 13499 13500 // Create a Set of the selected block names that is used in patterns filtering. 13501 const selectedBlockNames = Array.from(new Set(blocks.map(({ 13502 name 13503 }) => name))); 13504 /** 13505 * Here we will return first set of possible eligible block patterns, 13506 * by checking the `blockTypes` property. We still have to recurse through 13507 * block pattern's blocks and try to find matches from the selected blocks. 13508 * Now this happens in the consumer to avoid heavy operations in the selector. 13509 */ 13510 return select(STORE_NAME).getPatternsByBlockTypes(selectedBlockNames, rootClientId); 13511 }, (state, blocks, rootClientId) => getAllowedPatternsDependants(select)(state, rootClientId))); 13512 13513 /** 13514 * Returns the Block List settings of a block, if any exist. 13515 * 13516 * @param {Object} state Editor state. 13517 * @param {?string} clientId Block client ID. 13518 * 13519 * @return {?Object} Block settings of the block if set. 13520 */ 13521 function getBlockListSettings(state, clientId) { 13522 return state.blockListSettings[clientId]; 13523 } 13524 13525 /** 13526 * Returns the editor settings. 13527 * 13528 * @param {Object} state Editor state. 13529 * 13530 * @return {Object} The editor settings object. 13531 */ 13532 function getSettings(state) { 13533 return state.settings; 13534 } 13535 13536 /** 13537 * Returns true if the most recent block change is be considered persistent, or 13538 * false otherwise. A persistent change is one committed by BlockEditorProvider 13539 * via its `onChange` callback, in addition to `onInput`. 13540 * 13541 * @param {Object} state Block editor state. 13542 * 13543 * @return {boolean} Whether the most recent block change was persistent. 13544 */ 13545 function isLastBlockChangePersistent(state) { 13546 return state.blocks.isPersistentChange; 13547 } 13548 13549 /** 13550 * Returns the block list settings for an array of blocks, if any exist. 13551 * 13552 * @param {Object} state Editor state. 13553 * @param {Array} clientIds Block client IDs. 13554 * 13555 * @return {Object} An object where the keys are client ids and the values are 13556 * a block list setting object. 13557 */ 13558 const __experimentalGetBlockListSettingsForBlocks = rememo((state, clientIds = []) => { 13559 return clientIds.reduce((blockListSettingsForBlocks, clientId) => { 13560 if (!state.blockListSettings[clientId]) { 13561 return blockListSettingsForBlocks; 13562 } 13563 return { 13564 ...blockListSettingsForBlocks, 13565 [clientId]: state.blockListSettings[clientId] 13566 }; 13567 }, {}); 13568 }, state => [state.blockListSettings]); 13569 13570 /** 13571 * Returns the title of a given reusable block 13572 * 13573 * @param {Object} state Global application state. 13574 * @param {number|string} ref The shared block's ID. 13575 * 13576 * @return {string} The reusable block saved title. 13577 */ 13578 const __experimentalGetReusableBlockTitle = rememo((state, ref) => { 13579 const reusableBlock = getReusableBlocks(state).find(block => block.id === ref); 13580 if (!reusableBlock) { 13581 return null; 13582 } 13583 return reusableBlock.title?.raw; 13584 }, state => [getReusableBlocks(state)]); 13585 13586 /** 13587 * Returns true if the most recent block change is be considered ignored, or 13588 * false otherwise. An ignored change is one not to be committed by 13589 * BlockEditorProvider, neither via `onChange` nor `onInput`. 13590 * 13591 * @param {Object} state Block editor state. 13592 * 13593 * @return {boolean} Whether the most recent block change was ignored. 13594 */ 13595 function __unstableIsLastBlockChangeIgnored(state) { 13596 // TODO: Removal Plan: Changes incurred by RECEIVE_BLOCKS should not be 13597 // ignored if in-fact they result in a change in blocks state. The current 13598 // need to ignore changes not a result of user interaction should be 13599 // accounted for in the refactoring of reusable blocks as occurring within 13600 // their own separate block editor / state (#7119). 13601 return state.blocks.isIgnoredChange; 13602 } 13603 13604 /** 13605 * Returns the block attributes changed as a result of the last dispatched 13606 * action. 13607 * 13608 * @param {Object} state Block editor state. 13609 * 13610 * @return {Object<string,Object>} Subsets of block attributes changed, keyed 13611 * by block client ID. 13612 */ 13613 function __experimentalGetLastBlockAttributeChanges(state) { 13614 return state.lastBlockAttributesChange; 13615 } 13616 13617 /** 13618 * Returns the available reusable blocks 13619 * 13620 * @param {Object} state Global application state. 13621 * 13622 * @return {Array} Reusable blocks 13623 */ 13624 function getReusableBlocks(state) { 13625 var _state$settings$__exp; 13626 return (_state$settings$__exp = state.settings.__experimentalReusableBlocks) !== null && _state$settings$__exp !== void 0 ? _state$settings$__exp : EMPTY_ARRAY; 13627 } 13628 13629 /** 13630 * Returns whether the navigation mode is enabled. 13631 * 13632 * @param {Object} state Editor state. 13633 * 13634 * @return {boolean} Is navigation mode enabled. 13635 */ 13636 function isNavigationMode(state) { 13637 return state.editorMode === 'navigation'; 13638 } 13639 13640 /** 13641 * Returns the current editor mode. 13642 * 13643 * @param {Object} state Editor state. 13644 * 13645 * @return {string} the editor mode. 13646 */ 13647 function __unstableGetEditorMode(state) { 13648 return state.editorMode; 13649 } 13650 13651 /** 13652 * Returns whether block moving mode is enabled. 13653 * 13654 * @param {Object} state Editor state. 13655 * 13656 * @return {string} Client Id of moving block. 13657 */ 13658 function selectors_hasBlockMovingClientId(state) { 13659 return state.hasBlockMovingClientId; 13660 } 13661 13662 /** 13663 * Returns true if the last change was an automatic change, false otherwise. 13664 * 13665 * @param {Object} state Global application state. 13666 * 13667 * @return {boolean} Whether the last change was automatic. 13668 */ 13669 function didAutomaticChange(state) { 13670 return !!state.automaticChangeStatus; 13671 } 13672 13673 /** 13674 * Returns true if the current highlighted block matches the block clientId. 13675 * 13676 * @param {Object} state Global application state. 13677 * @param {string} clientId The block to check. 13678 * 13679 * @return {boolean} Whether the block is currently highlighted. 13680 */ 13681 function isBlockHighlighted(state, clientId) { 13682 return state.highlightedBlock === clientId; 13683 } 13684 13685 /** 13686 * Checks if a given block has controlled inner blocks. 13687 * 13688 * @param {Object} state Global application state. 13689 * @param {string} clientId The block to check. 13690 * 13691 * @return {boolean} True if the block has controlled inner blocks. 13692 */ 13693 function areInnerBlocksControlled(state, clientId) { 13694 return !!state.blocks.controlledInnerBlocks[clientId]; 13695 } 13696 13697 /** 13698 * Returns the clientId for the first 'active' block of a given array of block names. 13699 * A block is 'active' if it (or a child) is the selected block. 13700 * Returns the first match moving up the DOM from the selected block. 13701 * 13702 * @param {Object} state Global application state. 13703 * @param {string[]} validBlocksNames The names of block types to check for. 13704 * 13705 * @return {string} The matching block's clientId. 13706 */ 13707 const __experimentalGetActiveBlockIdByBlockNames = rememo((state, validBlockNames) => { 13708 if (!validBlockNames.length) { 13709 return null; 13710 } 13711 // Check if selected block is a valid entity area. 13712 const selectedBlockClientId = getSelectedBlockClientId(state); 13713 if (validBlockNames.includes(getBlockName(state, selectedBlockClientId))) { 13714 return selectedBlockClientId; 13715 } 13716 // Check if first selected block is a child of a valid entity area. 13717 const multiSelectedBlockClientIds = getMultiSelectedBlockClientIds(state); 13718 const entityAreaParents = getBlockParentsByBlockName(state, selectedBlockClientId || multiSelectedBlockClientIds[0], validBlockNames); 13719 if (entityAreaParents) { 13720 // Last parent closest/most interior. 13721 return entityAreaParents[entityAreaParents.length - 1]; 13722 } 13723 return null; 13724 }, (state, validBlockNames) => [state.selection.selectionStart.clientId, state.selection.selectionEnd.clientId, validBlockNames]); 13725 13726 /** 13727 * Tells if the block with the passed clientId was just inserted. 13728 * 13729 * @param {Object} state Global application state. 13730 * @param {Object} clientId Client Id of the block. 13731 * @param {?string} source Optional insertion source of the block. 13732 * @return {boolean} True if the block matches the last block inserted from the specified source. 13733 */ 13734 function wasBlockJustInserted(state, clientId, source) { 13735 const { 13736 lastBlockInserted 13737 } = state; 13738 return lastBlockInserted.clientIds?.includes(clientId) && lastBlockInserted.source === source; 13739 } 13740 13741 /** 13742 * Tells if the block is visible on the canvas or not. 13743 * 13744 * @param {Object} state Global application state. 13745 * @param {Object} clientId Client Id of the block. 13746 * @return {boolean} True if the block is visible. 13747 */ 13748 function isBlockVisible(state, clientId) { 13749 var _state$blockVisibilit; 13750 return (_state$blockVisibilit = state.blockVisibility?.[clientId]) !== null && _state$blockVisibilit !== void 0 ? _state$blockVisibilit : true; 13751 } 13752 13753 /** 13754 * Returns the list of all hidden blocks. 13755 * 13756 * @param {Object} state Global application state. 13757 * @return {[string]} List of hidden blocks. 13758 */ 13759 const __unstableGetVisibleBlocks = rememo(state => { 13760 const visibleBlocks = new Set(Object.keys(state.blockVisibility).filter(key => state.blockVisibility[key])); 13761 if (visibleBlocks.size === 0) { 13762 return EMPTY_SET; 13763 } 13764 return visibleBlocks; 13765 }, state => [state.blockVisibility]); 13766 13767 /** 13768 * DO-NOT-USE in production. 13769 * This selector is created for internal/experimental only usage and may be 13770 * removed anytime without any warning, causing breakage on any plugin or theme invoking it. 13771 */ 13772 const __unstableGetContentLockingParent = rememo((state, clientId) => { 13773 let current = clientId; 13774 let result; 13775 while (current = state.blocks.parents.get(current)) { 13776 if (getBlockName(state, current) === 'core/block' || getTemplateLock(state, current) === 'contentOnly') { 13777 result = current; 13778 } 13779 } 13780 return result; 13781 }, state => [state.blocks.parents, state.blockListSettings]); 13782 13783 /** 13784 * DO-NOT-USE in production. 13785 * This selector is created for internal/experimental only usage and may be 13786 * removed anytime without any warning, causing breakage on any plugin or theme invoking it. 13787 * 13788 * @param {Object} state Global application state. 13789 */ 13790 function __unstableGetTemporarilyEditingAsBlocks(state) { 13791 return state.temporarilyEditingAsBlocks; 13792 } 13793 13794 /** 13795 * DO-NOT-USE in production. 13796 * This selector is created for internal/experimental only usage and may be 13797 * removed anytime without any warning, causing breakage on any plugin or theme invoking it. 13798 * 13799 * @param {Object} state Global application state. 13800 */ 13801 function __unstableGetTemporarilyEditingFocusModeToRevert(state) { 13802 return state.temporarilyEditingFocusModeRevert; 13803 } 13804 function __unstableHasActiveBlockOverlayActive(state, clientId) { 13805 // Prevent overlay on blocks with a non-default editing mode. If the mdoe is 13806 // 'disabled' then the overlay is redundant since the block can't be 13807 // selected. If the mode is 'contentOnly' then the overlay is redundant 13808 // since there will be no controls to interact with once selected. 13809 if (getBlockEditingMode(state, clientId) !== 'default') { 13810 return false; 13811 } 13812 13813 // If the block editing is locked, the block overlay is always active. 13814 if (!canEditBlock(state, clientId)) { 13815 return true; 13816 } 13817 const editorMode = __unstableGetEditorMode(state); 13818 13819 // In zoom-out mode, the block overlay is always active for top level blocks. 13820 if (editorMode === 'zoom-out' && clientId && !getBlockRootClientId(state, clientId)) { 13821 return true; 13822 } 13823 13824 // In navigation mode, the block overlay is active when the block is not 13825 // selected (and doesn't contain a selected child). The same behavior is 13826 // also enabled in all modes for blocks that have controlled children 13827 // (reusable block, template part, navigation), unless explicitly disabled 13828 // with `supports.__experimentalDisableBlockOverlay`. 13829 const blockSupportDisable = (0,external_wp_blocks_namespaceObject.hasBlockSupport)(getBlockName(state, clientId), '__experimentalDisableBlockOverlay', false); 13830 const shouldEnableIfUnselected = editorMode === 'navigation' || (blockSupportDisable ? false : areInnerBlocksControlled(state, clientId)); 13831 return shouldEnableIfUnselected && !isBlockSelected(state, clientId) && !hasSelectedInnerBlock(state, clientId, true); 13832 } 13833 function __unstableIsWithinBlockOverlay(state, clientId) { 13834 let parent = state.blocks.parents.get(clientId); 13835 while (!!parent) { 13836 if (__unstableHasActiveBlockOverlayActive(state, parent)) { 13837 return true; 13838 } 13839 parent = state.blocks.parents.get(parent); 13840 } 13841 return false; 13842 } 13843 13844 /** 13845 * @typedef {import('../components/block-editing-mode').BlockEditingMode} BlockEditingMode 13846 */ 13847 13848 /** 13849 * Returns the block editing mode for a given block. 13850 * 13851 * The mode can be one of three options: 13852 * 13853 * - `'disabled'`: Prevents editing the block entirely, i.e. it cannot be 13854 * selected. 13855 * - `'contentOnly'`: Hides all non-content UI, e.g. auxiliary controls in the 13856 * toolbar, the block movers, block settings. 13857 * - `'default'`: Allows editing the block as normal. 13858 * 13859 * Blocks can set a mode using the `useBlockEditingMode` hook. 13860 * 13861 * The mode is inherited by all of the block's inner blocks, unless they have 13862 * their own mode. 13863 * 13864 * A template lock can also set a mode. If the template lock is `'contentOnly'`, 13865 * the block's mode is overridden to `'contentOnly'` if the block has a content 13866 * role attribute, or `'disabled'` otherwise. 13867 * 13868 * @see useBlockEditingMode 13869 * 13870 * @param {Object} state Global application state. 13871 * @param {string} clientId The block client ID, or `''` for the root container. 13872 * 13873 * @return {BlockEditingMode} The block editing mode. One of `'disabled'`, 13874 * `'contentOnly'`, or `'default'`. 13875 */ 13876 const getBlockEditingMode = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => (state, clientId = '') => { 13877 const blockEditingMode = state.blockEditingModes.get(clientId); 13878 if (blockEditingMode) { 13879 return blockEditingMode; 13880 } 13881 if (!clientId) { 13882 return 'default'; 13883 } 13884 const rootClientId = getBlockRootClientId(state, clientId); 13885 const templateLock = getTemplateLock(state, rootClientId); 13886 if (templateLock === 'contentOnly') { 13887 const name = getBlockName(state, clientId); 13888 const isContent = select(external_wp_blocks_namespaceObject.store).__experimentalHasContentRoleAttribute(name); 13889 return isContent ? 'contentOnly' : 'disabled'; 13890 } 13891 const parentMode = getBlockEditingMode(state, rootClientId); 13892 return parentMode === 'contentOnly' ? 'default' : parentMode; 13893 }); 13894 13895 /** 13896 * Indicates if a block is ungroupable. 13897 * A block is ungroupable if it is a single grouping block with inner blocks. 13898 * If a block has an `ungroup` transform, it is also ungroupable, without the 13899 * requirement of being the default grouping block. 13900 * Additionally a block can only be ungrouped if it has inner blocks and can 13901 * be removed. 13902 * 13903 * @param {Object} state Global application state. 13904 * @param {string} clientId Client Id of the block. If not passed the selected block's client id will be used. 13905 * @return {boolean} True if the block is ungroupable. 13906 */ 13907 const isUngroupable = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => (state, clientId = '') => { 13908 const _clientId = clientId || getSelectedBlockClientId(state); 13909 if (!_clientId) { 13910 return false; 13911 } 13912 const { 13913 getGroupingBlockName 13914 } = select(external_wp_blocks_namespaceObject.store); 13915 const block = getBlock(state, _clientId); 13916 const groupingBlockName = getGroupingBlockName(); 13917 const _isUngroupable = block && (block.name === groupingBlockName || (0,external_wp_blocks_namespaceObject.getBlockType)(block.name)?.transforms?.ungroup) && !!block.innerBlocks.length; 13918 return _isUngroupable && canRemoveBlock(state, _clientId); 13919 }); 13920 13921 /** 13922 * Indicates if the provided blocks(by client ids) are groupable. 13923 * We need to have at least one block, have a grouping block name set and 13924 * be able to remove these blocks. 13925 * 13926 * @param {Object} state Global application state. 13927 * @param {string[]} clientIds Block client ids. If not passed the selected blocks client ids will be used. 13928 * @return {boolean} True if the blocks are groupable. 13929 */ 13930 const isGroupable = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => (state, clientIds = EMPTY_ARRAY) => { 13931 const { 13932 getGroupingBlockName 13933 } = select(external_wp_blocks_namespaceObject.store); 13934 const groupingBlockName = getGroupingBlockName(); 13935 const _clientIds = clientIds?.length ? clientIds : getSelectedBlockClientIds(state); 13936 const rootClientId = _clientIds?.length ? getBlockRootClientId(state, _clientIds[0]) : undefined; 13937 const groupingBlockAvailable = canInsertBlockType(state, groupingBlockName, rootClientId); 13938 const _isGroupable = groupingBlockAvailable && _clientIds.length; 13939 return _isGroupable && canRemoveBlocks(state, _clientIds, rootClientId); 13940 }); 13941 13942 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/store/undo-ignore.js 13943 // Keep track of the blocks that should not be pushing an additional 13944 // undo stack when editing the entity. 13945 // See the implementation of `syncDerivedUpdates` and `useBlockSync`. 13946 const undoIgnoreBlocks = new WeakSet(); 13947 13948 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/store/private-actions.js 13949 /** 13950 * WordPress dependencies 13951 */ 13952 13953 13954 /** 13955 * Internal dependencies 13956 */ 13957 13958 const castArray = maybeArray => Array.isArray(maybeArray) ? maybeArray : [maybeArray]; 13959 13960 /** 13961 * A list of private/experimental block editor settings that 13962 * should not become a part of the WordPress public API. 13963 * BlockEditorProvider will remove these settings from the 13964 * settings object it receives. 13965 * 13966 * @see https://github.com/WordPress/gutenberg/pull/46131 13967 */ 13968 const privateSettings = ['inserterMediaCategories', 'blockInspectorAnimation']; 13969 13970 /** 13971 * Action that updates the block editor settings and 13972 * conditionally preserves the experimental ones. 13973 * 13974 * @param {Object} settings Updated settings 13975 * @param {Object} options Options object. 13976 * @param {boolean} options.stripExperimentalSettings Whether to strip experimental settings. 13977 * @param {boolean} options.reset Whether to reset the settings. 13978 * @return {Object} Action object 13979 */ 13980 function __experimentalUpdateSettings(settings, { 13981 stripExperimentalSettings = false, 13982 reset = false 13983 } = {}) { 13984 let cleanSettings = settings; 13985 // There are no plugins in the mobile apps, so there is no 13986 // need to strip the experimental settings: 13987 if (stripExperimentalSettings && external_wp_element_namespaceObject.Platform.OS === 'web') { 13988 cleanSettings = {}; 13989 for (const key in settings) { 13990 if (!privateSettings.includes(key)) { 13991 cleanSettings[key] = settings[key]; 13992 } 13993 } 13994 } 13995 return { 13996 type: 'UPDATE_SETTINGS', 13997 settings: cleanSettings, 13998 reset 13999 }; 14000 } 14001 14002 /** 14003 * Hides the block interface (eg. toolbar, outline, etc.) 14004 * 14005 * @return {Object} Action object. 14006 */ 14007 function hideBlockInterface() { 14008 return { 14009 type: 'HIDE_BLOCK_INTERFACE' 14010 }; 14011 } 14012 14013 /** 14014 * Shows the block interface (eg. toolbar, outline, etc.) 14015 * 14016 * @return {Object} Action object. 14017 */ 14018 function showBlockInterface() { 14019 return { 14020 type: 'SHOW_BLOCK_INTERFACE' 14021 }; 14022 } 14023 14024 /** 14025 * Yields action objects used in signalling that the blocks corresponding to 14026 * the set of specified client IDs are to be removed. 14027 * 14028 * Compared to `removeBlocks`, this private interface exposes an additional 14029 * parameter; see `forceRemove`. 14030 * 14031 * @param {string|string[]} clientIds Client IDs of blocks to remove. 14032 * @param {boolean} selectPrevious True if the previous block 14033 * or the immediate parent 14034 * (if no previous block exists) 14035 * should be selected 14036 * when a block is removed. 14037 * @param {boolean} forceRemove Whether to force the operation, 14038 * bypassing any checks for certain 14039 * block types. 14040 */ 14041 const privateRemoveBlocks = (clientIds, selectPrevious = true, forceRemove = false) => ({ 14042 select, 14043 dispatch, 14044 registry 14045 }) => { 14046 if (!clientIds || !clientIds.length) { 14047 return; 14048 } 14049 clientIds = castArray(clientIds); 14050 const rootClientId = select.getBlockRootClientId(clientIds[0]); 14051 const canRemoveBlocks = select.canRemoveBlocks(clientIds, rootClientId); 14052 if (!canRemoveBlocks) { 14053 return; 14054 } 14055 14056 // In certain editing contexts, we'd like to prevent accidental removal 14057 // of important blocks. For example, in the site editor, the Query Loop 14058 // block is deemed important. In such cases, we'll ask the user for 14059 // confirmation that they intended to remove such block(s). However, 14060 // the editor instance is responsible for presenting those confirmation 14061 // prompts to the user. Any instance opting into removal prompts must 14062 // register using `setBlockRemovalRules()`. 14063 // 14064 // @see https://github.com/WordPress/gutenberg/pull/51145 14065 const rules = !forceRemove && select.getBlockRemovalRules(); 14066 if (rules) { 14067 const blockNamesForPrompt = new Set(); 14068 14069 // Given a list of client IDs of blocks that the user intended to 14070 // remove, perform a tree search (BFS) to find all block names 14071 // corresponding to "important" blocks, i.e. blocks that require a 14072 // removal prompt. 14073 const queue = [...clientIds]; 14074 let messageType = 'templates'; 14075 while (queue.length) { 14076 const clientId = queue.shift(); 14077 const blockName = select.getBlockName(clientId); 14078 if (rules[blockName]) { 14079 blockNamesForPrompt.add(blockName); 14080 } 14081 if (rules['bindings/core/pattern-overrides']) { 14082 const parentPatternBlocks = select.getBlockParentsByBlockName(clientId, 'core/block'); 14083 // We only need to run this check when editing the original pattern, not pattern instances. 14084 if (parentPatternBlocks?.length > 0) { 14085 continue; 14086 } 14087 const blockAttributes = select.getBlockAttributes(clientId); 14088 if (blockAttributes?.metadata?.bindings && JSON.stringify(blockAttributes.metadata.bindings).includes('core/pattern-overrides')) { 14089 blockNamesForPrompt.add(blockName); 14090 messageType = 'patternOverrides'; 14091 } 14092 } 14093 const innerBlocks = select.getBlockOrder(clientId); 14094 queue.push(...innerBlocks); 14095 } 14096 14097 // If any such blocks were found, trigger the removal prompt and 14098 // skip any other steps (thus postponing actual removal). 14099 if (blockNamesForPrompt.size) { 14100 dispatch(displayBlockRemovalPrompt(clientIds, selectPrevious, Array.from(blockNamesForPrompt), messageType)); 14101 return; 14102 } 14103 } 14104 if (selectPrevious) { 14105 dispatch.selectPreviousBlock(clientIds[0], selectPrevious); 14106 } 14107 14108 // We're batching these two actions because an extra `undo/redo` step can 14109 // be created, based on whether we insert a default block or not. 14110 registry.batch(() => { 14111 dispatch({ 14112 type: 'REMOVE_BLOCKS', 14113 clientIds 14114 }); 14115 // To avoid a focus loss when removing the last block, assure there is 14116 // always a default block if the last of the blocks have been removed. 14117 dispatch(ensureDefaultBlock()); 14118 }); 14119 }; 14120 14121 /** 14122 * Action which will insert a default block insert action if there 14123 * are no other blocks at the root of the editor. This action should be used 14124 * in actions which may result in no blocks remaining in the editor (removal, 14125 * replacement, etc). 14126 */ 14127 const ensureDefaultBlock = () => ({ 14128 select, 14129 dispatch 14130 }) => { 14131 // To avoid a focus loss when removing the last block, assure there is 14132 // always a default block if the last of the blocks have been removed. 14133 const count = select.getBlockCount(); 14134 if (count > 0) { 14135 return; 14136 } 14137 14138 // If there's an custom appender, don't insert default block. 14139 // We have to remember to manually move the focus elsewhere to 14140 // prevent it from being lost though. 14141 const { 14142 __unstableHasCustomAppender 14143 } = select.getSettings(); 14144 if (__unstableHasCustomAppender) { 14145 return; 14146 } 14147 dispatch.insertDefaultBlock(); 14148 }; 14149 14150 /** 14151 * Returns an action object used in signalling that a block removal prompt must 14152 * be displayed. 14153 * 14154 * Contrast with `setBlockRemovalRules`. 14155 * 14156 * @param {string|string[]} clientIds Client IDs of blocks to remove. 14157 * @param {boolean} selectPrevious True if the previous block 14158 * or the immediate parent 14159 * (if no previous block exists) 14160 * should be selected 14161 * when a block is removed. 14162 * @param {string[]} blockNamesForPrompt Names of the blocks that 14163 * triggered the need for 14164 * confirmation before removal. 14165 * @param {string} messageType The type of message to display. 14166 * 14167 * @return {Object} Action object. 14168 */ 14169 function displayBlockRemovalPrompt(clientIds, selectPrevious, blockNamesForPrompt, messageType) { 14170 return { 14171 type: 'DISPLAY_BLOCK_REMOVAL_PROMPT', 14172 clientIds, 14173 selectPrevious, 14174 blockNamesForPrompt, 14175 messageType 14176 }; 14177 } 14178 14179 /** 14180 * Returns an action object used in signalling that a block removal prompt must 14181 * be cleared, either be cause the user has confirmed or canceled the request 14182 * for removal. 14183 * 14184 * @return {Object} Action object. 14185 */ 14186 function clearBlockRemovalPrompt() { 14187 return { 14188 type: 'CLEAR_BLOCK_REMOVAL_PROMPT' 14189 }; 14190 } 14191 14192 /** 14193 * Returns an action object used to set up any rules that a block editor may 14194 * provide in order to prevent a user from accidentally removing certain 14195 * blocks. These rules are then used to display a confirmation prompt to the 14196 * user. For instance, in the Site Editor, the Query Loop block is important 14197 * enough to warrant such confirmation. 14198 * 14199 * IMPORTANT: Registering rules implicitly signals to the `privateRemoveBlocks` 14200 * action that the editor will be responsible for displaying block removal 14201 * prompts and confirming deletions. This action is meant to be used by 14202 * component `BlockRemovalWarningModal` only. 14203 * 14204 * The data is a record whose keys are block types (e.g. 'core/query') and 14205 * whose values are the explanation to be shown to users (e.g. 'Query Loop 14206 * displays a list of posts or pages.'). 14207 * 14208 * Contrast with `displayBlockRemovalPrompt`. 14209 * 14210 * @param {Record<string,string>|false} rules Block removal rules. 14211 * @return {Object} Action object. 14212 */ 14213 function setBlockRemovalRules(rules = false) { 14214 return { 14215 type: 'SET_BLOCK_REMOVAL_RULES', 14216 rules 14217 }; 14218 } 14219 14220 /** 14221 * Sets the client ID of the block settings menu that is currently open. 14222 * 14223 * @param {?string} clientId The block client ID. 14224 * @return {Object} Action object. 14225 */ 14226 function setOpenedBlockSettingsMenu(clientId) { 14227 return { 14228 type: 'SET_OPENED_BLOCK_SETTINGS_MENU', 14229 clientId 14230 }; 14231 } 14232 function setStyleOverride(id, style) { 14233 return { 14234 type: 'SET_STYLE_OVERRIDE', 14235 id, 14236 style 14237 }; 14238 } 14239 function deleteStyleOverride(id) { 14240 return { 14241 type: 'DELETE_STYLE_OVERRIDE', 14242 id 14243 }; 14244 } 14245 14246 /** 14247 * A higher-order action that mark every change inside a callback as "non-persistent" 14248 * and ignore pushing to the undo history stack. It's primarily used for synchronized 14249 * derived updates from the block editor without affecting the undo history. 14250 * 14251 * @param {() => void} callback The synchronous callback to derive updates. 14252 */ 14253 function syncDerivedUpdates(callback) { 14254 return ({ 14255 dispatch, 14256 select, 14257 registry 14258 }) => { 14259 registry.batch(() => { 14260 // Mark every change in the `callback` as non-persistent. 14261 dispatch({ 14262 type: 'SET_EXPLICIT_PERSISTENT', 14263 isPersistentChange: false 14264 }); 14265 callback(); 14266 dispatch({ 14267 type: 'SET_EXPLICIT_PERSISTENT', 14268 isPersistentChange: undefined 14269 }); 14270 14271 // Ignore pushing undo stack for the updated blocks. 14272 const updatedBlocks = select.getBlocks(); 14273 undoIgnoreBlocks.add(updatedBlocks); 14274 }); 14275 }; 14276 } 14277 14278 /** 14279 * Action that sets the element that had focus when focus leaves the editor canvas. 14280 * 14281 * @param {Object} lastFocus The last focused element. 14282 * 14283 * 14284 * @return {Object} Action object. 14285 */ 14286 function setLastFocus(lastFocus = null) { 14287 return { 14288 type: 'LAST_FOCUS', 14289 lastFocus 14290 }; 14291 } 14292 14293 /** 14294 * Action that stops temporarily editing as blocks. 14295 * 14296 * @param {string} clientId The block's clientId. 14297 */ 14298 function stopEditingAsBlocks(clientId) { 14299 return ({ 14300 select, 14301 dispatch 14302 }) => { 14303 const focusModeToRevert = select.__unstableGetTemporarilyEditingFocusModeToRevert(); 14304 dispatch.__unstableMarkNextChangeAsNotPersistent(); 14305 dispatch.updateBlockAttributes(clientId, { 14306 templateLock: 'contentOnly' 14307 }); 14308 dispatch.updateBlockListSettings(clientId, { 14309 ...select.getBlockListSettings(clientId), 14310 templateLock: 'contentOnly' 14311 }); 14312 dispatch.updateSettings({ 14313 focusMode: focusModeToRevert 14314 }); 14315 dispatch.__unstableSetTemporarilyEditingAsBlocks(); 14316 }; 14317 } 14318 14319 /** 14320 * Returns an action object used in signalling that the user has begun to drag. 14321 * 14322 * @return {Object} Action object. 14323 */ 14324 function startDragging() { 14325 return { 14326 type: 'START_DRAGGING' 14327 }; 14328 } 14329 14330 /** 14331 * Returns an action object used in signalling that the user has stopped dragging. 14332 * 14333 * @return {Object} Action object. 14334 */ 14335 function stopDragging() { 14336 return { 14337 type: 'STOP_DRAGGING' 14338 }; 14339 } 14340 14341 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/block-patterns-tab/utils.js 14342 /** 14343 * WordPress dependencies 14344 */ 14345 14346 14347 const INSERTER_PATTERN_TYPES = { 14348 user: 'user', 14349 theme: 'theme', 14350 directory: 'directory' 14351 }; 14352 const INSERTER_SYNC_TYPES = { 14353 full: 'fully', 14354 unsynced: 'unsynced' 14355 }; 14356 const allPatternsCategory = { 14357 name: 'allPatterns', 14358 label: (0,external_wp_i18n_namespaceObject._x)('All', 'patterns') 14359 }; 14360 const myPatternsCategory = { 14361 name: 'myPatterns', 14362 label: (0,external_wp_i18n_namespaceObject.__)('My patterns') 14363 }; 14364 function isPatternFiltered(pattern, sourceFilter, syncFilter) { 14365 const isUserPattern = pattern.name.startsWith('core/block'); 14366 const isDirectoryPattern = pattern.source === 'core' || pattern.source?.startsWith('pattern-directory'); 14367 14368 // If theme source selected, filter out user created patterns and those from 14369 // the core patterns directory. 14370 if (sourceFilter === INSERTER_PATTERN_TYPES.theme && (isUserPattern || isDirectoryPattern)) { 14371 return true; 14372 } 14373 14374 // If the directory source is selected, filter out user created patterns 14375 // and those bundled with the theme. 14376 if (sourceFilter === INSERTER_PATTERN_TYPES.directory && (isUserPattern || !isDirectoryPattern)) { 14377 return true; 14378 } 14379 14380 // If user source selected, filter out theme patterns. 14381 if (sourceFilter === INSERTER_PATTERN_TYPES.user && pattern.type !== INSERTER_PATTERN_TYPES.user) { 14382 return true; 14383 } 14384 14385 // Filter by sync status. 14386 if (syncFilter === INSERTER_SYNC_TYPES.full && pattern.syncStatus !== '') { 14387 return true; 14388 } 14389 if (syncFilter === INSERTER_SYNC_TYPES.unsynced && pattern.syncStatus !== 'unsynced' && isUserPattern) { 14390 return true; 14391 } 14392 return false; 14393 } 14394 14395 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/object.js 14396 /** 14397 * Immutably sets a value inside an object. Like `lodash#set`, but returning a 14398 * new object. Treats nullish initial values as empty objects. Clones any 14399 * nested objects. Supports arrays, too. 14400 * 14401 * @param {Object} object Object to set a value in. 14402 * @param {number|string|Array} path Path in the object to modify. 14403 * @param {*} value New value to set. 14404 * @return {Object} Cloned object with the new value set. 14405 */ 14406 function setImmutably(object, path, value) { 14407 // Normalize path 14408 path = Array.isArray(path) ? [...path] : [path]; 14409 14410 // Shallowly clone the base of the object 14411 object = Array.isArray(object) ? [...object] : { 14412 ...object 14413 }; 14414 const leaf = path.pop(); 14415 14416 // Traverse object from root to leaf, shallowly cloning at each level 14417 let prev = object; 14418 for (const key of path) { 14419 const lvl = prev[key]; 14420 prev = prev[key] = Array.isArray(lvl) ? [...lvl] : { 14421 ...lvl 14422 }; 14423 } 14424 prev[leaf] = value; 14425 return object; 14426 } 14427 14428 /** 14429 * Helper util to return a value from a certain path of the object. 14430 * Path is specified as either: 14431 * - a string of properties, separated by dots, for example: "x.y". 14432 * - an array of properties, for example `[ 'x', 'y' ]`. 14433 * You can also specify a default value in case the result is nullish. 14434 * 14435 * @param {Object} object Input object. 14436 * @param {string|Array} path Path to the object property. 14437 * @param {*} defaultValue Default value if the value at the specified path is nullish. 14438 * @return {*} Value of the object property at the specified path. 14439 */ 14440 const getValueFromObjectPath = (object, path, defaultValue) => { 14441 var _value; 14442 const arrayPath = Array.isArray(path) ? path : path.split('.'); 14443 let value = object; 14444 arrayPath.forEach(fieldName => { 14445 value = value?.[fieldName]; 14446 }); 14447 return (_value = value) !== null && _value !== void 0 ? _value : defaultValue; 14448 }; 14449 14450 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/store/get-block-settings.js 14451 /** 14452 * WordPress dependencies 14453 */ 14454 14455 14456 14457 /** 14458 * Internal dependencies 14459 */ 14460 14461 14462 const blockedPaths = ['color', 'border', 'dimensions', 'typography', 'spacing']; 14463 const deprecatedFlags = { 14464 'color.palette': settings => settings.colors, 14465 'color.gradients': settings => settings.gradients, 14466 'color.custom': settings => settings.disableCustomColors === undefined ? undefined : !settings.disableCustomColors, 14467 'color.customGradient': settings => settings.disableCustomGradients === undefined ? undefined : !settings.disableCustomGradients, 14468 'typography.fontSizes': settings => settings.fontSizes, 14469 'typography.customFontSize': settings => settings.disableCustomFontSizes === undefined ? undefined : !settings.disableCustomFontSizes, 14470 'typography.lineHeight': settings => settings.enableCustomLineHeight, 14471 'spacing.units': settings => { 14472 if (settings.enableCustomUnits === undefined) { 14473 return; 14474 } 14475 if (settings.enableCustomUnits === true) { 14476 return ['px', 'em', 'rem', 'vh', 'vw', '%']; 14477 } 14478 return settings.enableCustomUnits; 14479 }, 14480 'spacing.padding': settings => settings.enableCustomSpacing 14481 }; 14482 const prefixedFlags = { 14483 /* 14484 * These were only available in the plugin 14485 * and can be removed when the minimum WordPress version 14486 * for the plugin is 5.9. 14487 */ 14488 'border.customColor': 'border.color', 14489 'border.customStyle': 'border.style', 14490 'border.customWidth': 'border.width', 14491 'typography.customFontStyle': 'typography.fontStyle', 14492 'typography.customFontWeight': 'typography.fontWeight', 14493 'typography.customLetterSpacing': 'typography.letterSpacing', 14494 'typography.customTextDecorations': 'typography.textDecoration', 14495 'typography.customTextTransforms': 'typography.textTransform', 14496 /* 14497 * These were part of WordPress 5.8 and we need to keep them. 14498 */ 14499 'border.customRadius': 'border.radius', 14500 'spacing.customMargin': 'spacing.margin', 14501 'spacing.customPadding': 'spacing.padding', 14502 'typography.customLineHeight': 'typography.lineHeight' 14503 }; 14504 14505 /** 14506 * Remove `custom` prefixes for flags that did not land in 5.8. 14507 * 14508 * This provides continued support for `custom` prefixed properties. It will 14509 * be removed once third party devs have had sufficient time to update themes, 14510 * plugins, etc. 14511 * 14512 * @see https://github.com/WordPress/gutenberg/pull/34485 14513 * 14514 * @param {string} path Path to desired value in settings. 14515 * @return {string} The value for defined setting. 14516 */ 14517 const removeCustomPrefixes = path => { 14518 return prefixedFlags[path] || path; 14519 }; 14520 14521 /** 14522 * For settings like `color.palette`, which have a value that is an object 14523 * with `default`, `theme`, `custom`, with field values that are arrays of 14524 * items, merge these three arrays into one and return it. The calculation 14525 * is memoized so that identical input values produce identical output. 14526 * @param {Object} value Object to merge 14527 * @return {Array} Array of merged items 14528 */ 14529 function mergeOrigins(value) { 14530 let result = mergeCache.get(value); 14531 if (!result) { 14532 result = ['default', 'theme', 'custom'].flatMap(key => { 14533 var _value$key; 14534 return (_value$key = value[key]) !== null && _value$key !== void 0 ? _value$key : []; 14535 }); 14536 mergeCache.set(value, result); 14537 } 14538 return result; 14539 } 14540 const mergeCache = new WeakMap(); 14541 14542 /** 14543 * For settings like `color.palette`, which have a value that is an object 14544 * with `default`, `theme`, `custom`, with field values that are arrays of 14545 * items, returns the one with the highest priority among these three arrays. 14546 * @param {Object} value Object to extract from 14547 * @return {Array} Array of items extracted from the three origins 14548 */ 14549 function overrideOrigins(value) { 14550 var _ref, _value$custom; 14551 return (_ref = (_value$custom = value.custom) !== null && _value$custom !== void 0 ? _value$custom : value.theme) !== null && _ref !== void 0 ? _ref : value.default; 14552 } 14553 14554 /** 14555 * For settings like `color.palette`, which have a value that is an object 14556 * with `default`, `theme`, `custom`, with field values that are arrays of 14557 * items, see if any of the three origins have values. 14558 * 14559 * @param {Object} value Object to check 14560 * @return {boolean} Whether the object has values in any of the three origins 14561 */ 14562 function hasOriginValue(value) { 14563 return ['default', 'theme', 'custom'].some(key => value?.[key]?.length); 14564 } 14565 function getBlockSettings(state, clientId, ...paths) { 14566 const blockName = getBlockName(state, clientId); 14567 const candidates = []; 14568 if (clientId) { 14569 let id = clientId; 14570 do { 14571 const name = getBlockName(state, id); 14572 if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, '__experimentalSettings', false)) { 14573 candidates.push(id); 14574 } 14575 } while (id = state.blocks.parents.get(id)); 14576 } 14577 return paths.map(path => { 14578 if (blockedPaths.includes(path)) { 14579 // eslint-disable-next-line no-console 14580 console.warn('Top level useSetting paths are disabled. Please use a subpath to query the information needed.'); 14581 return undefined; 14582 } 14583 14584 // 0. Allow third parties to filter the block's settings at runtime. 14585 let result = (0,external_wp_hooks_namespaceObject.applyFilters)('blockEditor.useSetting.before', undefined, path, clientId, blockName); 14586 if (undefined !== result) { 14587 return result; 14588 } 14589 const normalizedPath = removeCustomPrefixes(path); 14590 14591 // 1. Take settings from the block instance or its ancestors. 14592 // Start from the current block and work our way up the ancestors. 14593 for (const candidateClientId of candidates) { 14594 var _getValueFromObjectPa; 14595 const candidateAtts = getBlockAttributes(state, candidateClientId); 14596 result = (_getValueFromObjectPa = getValueFromObjectPath(candidateAtts.settings?.blocks?.[blockName], normalizedPath)) !== null && _getValueFromObjectPa !== void 0 ? _getValueFromObjectPa : getValueFromObjectPath(candidateAtts.settings, normalizedPath); 14597 if (result !== undefined) { 14598 // Stop the search for more distant ancestors and move on. 14599 break; 14600 } 14601 } 14602 14603 // 2. Fall back to the settings from the block editor store (__experimentalFeatures). 14604 const settings = getSettings(state); 14605 if (result === undefined && blockName) { 14606 result = getValueFromObjectPath(settings.__experimentalFeatures?.blocks?.[blockName], normalizedPath); 14607 } 14608 if (result === undefined) { 14609 result = getValueFromObjectPath(settings.__experimentalFeatures, normalizedPath); 14610 } 14611 14612 // Return if the setting was found in either the block instance or the store. 14613 if (result !== undefined) { 14614 if (external_wp_blocks_namespaceObject.__EXPERIMENTAL_PATHS_WITH_OVERRIDE[normalizedPath]) { 14615 return overrideOrigins(result); 14616 } 14617 return result; 14618 } 14619 14620 // 3. Otherwise, use deprecated settings. 14621 const deprecatedSettingsValue = deprecatedFlags[normalizedPath]?.(settings); 14622 if (deprecatedSettingsValue !== undefined) { 14623 return deprecatedSettingsValue; 14624 } 14625 14626 // 4. Fallback for typography.dropCap: 14627 // This is only necessary to support typography.dropCap. 14628 // when __experimentalFeatures are not present (core without plugin). 14629 // To remove when __experimentalFeatures are ported to core. 14630 return normalizedPath === 'typography.dropCap' ? true : undefined; 14631 }); 14632 } 14633 14634 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/store/private-selectors.js 14635 /** 14636 * External dependencies 14637 */ 14638 14639 14640 /** 14641 * WordPress dependencies 14642 */ 14643 14644 14645 /** 14646 * Internal dependencies 14647 */ 14648 14649 14650 14651 14652 14653 14654 14655 14656 /** 14657 * Returns true if the block interface is hidden, or false otherwise. 14658 * 14659 * @param {Object} state Global application state. 14660 * 14661 * @return {boolean} Whether the block toolbar is hidden. 14662 */ 14663 function private_selectors_isBlockInterfaceHidden(state) { 14664 return state.isBlockInterfaceHidden; 14665 } 14666 14667 /** 14668 * Gets the client ids of the last inserted blocks. 14669 * 14670 * @param {Object} state Global application state. 14671 * @return {Array|undefined} Client Ids of the last inserted block(s). 14672 */ 14673 function getLastInsertedBlocksClientIds(state) { 14674 return state?.lastBlockInserted?.clientIds; 14675 } 14676 function getBlockWithoutAttributes(state, clientId) { 14677 return state.blocks.byClientId.get(clientId); 14678 } 14679 14680 /** 14681 * Returns true if all of the descendants of a block with the given client ID 14682 * have an editing mode of 'disabled', or false otherwise. 14683 * 14684 * @param {Object} state Global application state. 14685 * @param {string} clientId The block client ID. 14686 * 14687 * @return {boolean} Whether the block descendants are disabled. 14688 */ 14689 const isBlockSubtreeDisabled = (state, clientId) => { 14690 const isChildSubtreeDisabled = childClientId => { 14691 return getBlockEditingMode(state, childClientId) === 'disabled' && getBlockOrder(state, childClientId).every(isChildSubtreeDisabled); 14692 }; 14693 return getBlockOrder(state, clientId).every(isChildSubtreeDisabled); 14694 }; 14695 function getEnabledClientIdsTreeUnmemoized(state, rootClientId) { 14696 const blockOrder = getBlockOrder(state, rootClientId); 14697 const result = []; 14698 for (const clientId of blockOrder) { 14699 const innerBlocks = getEnabledClientIdsTreeUnmemoized(state, clientId); 14700 if (getBlockEditingMode(state, clientId) !== 'disabled') { 14701 result.push({ 14702 clientId, 14703 innerBlocks 14704 }); 14705 } else { 14706 result.push(...innerBlocks); 14707 } 14708 } 14709 return result; 14710 } 14711 14712 /** 14713 * Returns a tree of block objects with only clientID and innerBlocks set. 14714 * Blocks with a 'disabled' editing mode are not included. 14715 * 14716 * @param {Object} state Global application state. 14717 * @param {?string} rootClientId Optional root client ID of block list. 14718 * 14719 * @return {Object[]} Tree of block objects with only clientID and innerBlocks set. 14720 */ 14721 const getEnabledClientIdsTree = rememo(getEnabledClientIdsTreeUnmemoized, state => [state.blocks.order, state.blockEditingModes, state.settings.templateLock, state.blockListSettings]); 14722 14723 /** 14724 * Returns a list of a given block's ancestors, from top to bottom. Blocks with 14725 * a 'disabled' editing mode are excluded. 14726 * 14727 * @see getBlockParents 14728 * 14729 * @param {Object} state Global application state. 14730 * @param {string} clientId The block client ID. 14731 * @param {boolean} ascending Order results from bottom to top (true) or top 14732 * to bottom (false). 14733 */ 14734 const getEnabledBlockParents = rememo((state, clientId, ascending = false) => { 14735 return getBlockParents(state, clientId, ascending).filter(parent => getBlockEditingMode(state, parent) !== 'disabled'); 14736 }, state => [state.blocks.parents, state.blockEditingModes, state.settings.templateLock, state.blockListSettings]); 14737 14738 /** 14739 * Selector that returns the data needed to display a prompt when certain 14740 * blocks are removed, or `false` if no such prompt is requested. 14741 * 14742 * @param {Object} state Global application state. 14743 * 14744 * @return {Object|false} Data for removal prompt display, if any. 14745 */ 14746 function getRemovalPromptData(state) { 14747 return state.removalPromptData; 14748 } 14749 14750 /** 14751 * Returns true if removal prompt exists, or false otherwise. 14752 * 14753 * @param {Object} state Global application state. 14754 * 14755 * @return {boolean} Whether removal prompt exists. 14756 */ 14757 function getBlockRemovalRules(state) { 14758 return state.blockRemovalRules; 14759 } 14760 14761 /** 14762 * Returns the client ID of the block settings menu that is currently open. 14763 * 14764 * @param {Object} state Global application state. 14765 * @return {string|null} The client ID of the block menu that is currently open. 14766 */ 14767 function getOpenedBlockSettingsMenu(state) { 14768 return state.openedBlockSettingsMenu; 14769 } 14770 14771 /** 14772 * Returns all style overrides, intended to be merged with global editor styles. 14773 * 14774 * @param {Object} state Global application state. 14775 * 14776 * @return {Map} A map of style IDs to style overrides. 14777 */ 14778 function getStyleOverrides(state) { 14779 return state.styleOverrides; 14780 } 14781 14782 /** @typedef {import('./actions').InserterMediaCategory} InserterMediaCategory */ 14783 /** 14784 * Returns the registered inserter media categories through the public API. 14785 * 14786 * @param {Object} state Editor state. 14787 * 14788 * @return {InserterMediaCategory[]} Inserter media categories. 14789 */ 14790 function getRegisteredInserterMediaCategories(state) { 14791 return state.registeredInserterMediaCategories; 14792 } 14793 14794 /** 14795 * Returns an array containing the allowed inserter media categories. 14796 * It merges the registered media categories from extenders with the 14797 * core ones. It also takes into account the allowed `mime_types`, which 14798 * can be altered by `upload_mimes` filter and restrict some of them. 14799 * 14800 * @param {Object} state Global application state. 14801 * 14802 * @return {InserterMediaCategory[]} Client IDs of descendants. 14803 */ 14804 const getInserterMediaCategories = rememo(state => { 14805 const { 14806 settings: { 14807 inserterMediaCategories, 14808 allowedMimeTypes, 14809 enableOpenverseMediaCategory 14810 }, 14811 registeredInserterMediaCategories 14812 } = state; 14813 // The allowed `mime_types` can be altered by `upload_mimes` filter and restrict 14814 // some of them. In this case we shouldn't add the category to the available media 14815 // categories list in the inserter. 14816 if (!inserterMediaCategories && !registeredInserterMediaCategories.length || !allowedMimeTypes) { 14817 return; 14818 } 14819 const coreInserterMediaCategoriesNames = inserterMediaCategories?.map(({ 14820 name 14821 }) => name) || []; 14822 const mergedCategories = [...(inserterMediaCategories || []), ...(registeredInserterMediaCategories || []).filter(({ 14823 name 14824 }) => !coreInserterMediaCategoriesNames.includes(name))]; 14825 return mergedCategories.filter(category => { 14826 // Check if Openverse category is enabled. 14827 if (!enableOpenverseMediaCategory && category.name === 'openverse') { 14828 return false; 14829 } 14830 return Object.values(allowedMimeTypes).some(mimeType => mimeType.startsWith(`$category.mediaType}/`)); 14831 }); 14832 }, state => [state.settings.inserterMediaCategories, state.settings.allowedMimeTypes, state.settings.enableOpenverseMediaCategory, state.registeredInserterMediaCategories]); 14833 14834 /** 14835 * Returns whether there is at least one allowed pattern for inner blocks children. 14836 * This is useful for deferring the parsing of all patterns until needed. 14837 * 14838 * @param {Object} state Editor state. 14839 * @param {string} [rootClientId=null] Target root client ID. 14840 * 14841 * @return {boolean} If there is at least one allowed pattern. 14842 */ 14843 const hasAllowedPatterns = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => rememo((state, rootClientId = null) => { 14844 const { 14845 getAllPatterns, 14846 __experimentalGetParsedPattern 14847 } = unlock(select(STORE_NAME)); 14848 const patterns = getAllPatterns(); 14849 const { 14850 allowedBlockTypes 14851 } = getSettings(state); 14852 return patterns.some(({ 14853 name, 14854 inserter = true 14855 }) => { 14856 if (!inserter) { 14857 return false; 14858 } 14859 const { 14860 blocks 14861 } = __experimentalGetParsedPattern(name); 14862 return checkAllowListRecursive(blocks, allowedBlockTypes) && blocks.every(({ 14863 name: blockName 14864 }) => canInsertBlockType(state, blockName, rootClientId)); 14865 }); 14866 }, (state, rootClientId) => [getAllPatternsDependants(select)(state), state.settings.allowedBlockTypes, state.settings.templateLock, state.blockListSettings[rootClientId], state.blocks.byClientId.get(rootClientId)])); 14867 const getAllPatterns = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => rememo(state => { 14868 var _state$settings$selec; 14869 // This setting is left for back compat. 14870 const { 14871 __experimentalBlockPatterns = [], 14872 __experimentalUserPatternCategories = [], 14873 __experimentalReusableBlocks = [] 14874 } = state.settings; 14875 const userPatterns = (__experimentalReusableBlocks !== null && __experimentalReusableBlocks !== void 0 ? __experimentalReusableBlocks : []).map(userPattern => { 14876 return { 14877 name: `core/block/$userPattern.id}`, 14878 id: userPattern.id, 14879 type: INSERTER_PATTERN_TYPES.user, 14880 title: userPattern.title.raw, 14881 categories: userPattern.wp_pattern_category.map(catId => { 14882 const category = (__experimentalUserPatternCategories !== null && __experimentalUserPatternCategories !== void 0 ? __experimentalUserPatternCategories : []).find(({ 14883 id 14884 }) => id === catId); 14885 return category ? category.slug : catId; 14886 }), 14887 content: userPattern.content.raw, 14888 syncStatus: userPattern.wp_pattern_sync_status 14889 }; 14890 }); 14891 return [...userPatterns, ...__experimentalBlockPatterns, ...((_state$settings$selec = state.settings[selectBlockPatternsKey]?.(select)) !== null && _state$settings$selec !== void 0 ? _state$settings$selec : [])].filter((x, index, arr) => index === arr.findIndex(y => x.name === y.name)); 14892 }, getAllPatternsDependants(select))); 14893 14894 /** 14895 * Returns the element of the last element that had focus when focus left the editor canvas. 14896 * 14897 * @param {Object} state Block editor state. 14898 * 14899 * @return {Object} Element. 14900 */ 14901 function getLastFocus(state) { 14902 return state.lastFocus; 14903 } 14904 14905 /** 14906 * Returns true if the user is dragging anything, or false otherwise. It is possible for a 14907 * user to be dragging data from outside of the editor, so this selector is separate from 14908 * the `isDraggingBlocks` selector which only returns true if the user is dragging blocks. 14909 * 14910 * @param {Object} state Global application state. 14911 * 14912 * @return {boolean} Whether user is dragging. 14913 */ 14914 function private_selectors_isDragging(state) { 14915 return state.isDragging; 14916 } 14917 14918 ;// CONCATENATED MODULE: external ["wp","a11y"] 14919 const external_wp_a11y_namespaceObject = window["wp"]["a11y"]; 14920 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/selection.js 14921 /** 14922 * WordPress dependencies 14923 */ 14924 14925 14926 /** 14927 * A robust way to retain selection position through various 14928 * transforms is to insert a special character at the position and 14929 * then recover it. 14930 */ 14931 const START_OF_SELECTED_AREA = '\u0086'; 14932 14933 /** 14934 * Retrieve the block attribute that contains the selection position. 14935 * 14936 * @param {Object} blockAttributes Block attributes. 14937 * @return {string|void} The name of the block attribute that was previously selected. 14938 */ 14939 function retrieveSelectedAttribute(blockAttributes) { 14940 if (!blockAttributes) { 14941 return; 14942 } 14943 return Object.keys(blockAttributes).find(name => { 14944 const value = blockAttributes[name]; 14945 return (typeof value === 'string' || value instanceof external_wp_richText_namespaceObject.RichTextData) && 14946 // To do: refactor this to use rich text's selection instead, so we 14947 // no longer have to use on this hack inserting a special character. 14948 value.toString().indexOf(START_OF_SELECTED_AREA) !== -1; 14949 }); 14950 } 14951 14952 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/store/actions.js 14953 /* eslint no-console: [ 'error', { allow: [ 'error', 'warn' ] } ] */ 14954 /** 14955 * WordPress dependencies 14956 */ 14957 14958 14959 14960 14961 14962 14963 /** 14964 * Internal dependencies 14965 */ 14966 14967 14968 14969 /** @typedef {import('../components/use-on-block-drop/types').WPDropOperation} WPDropOperation */ 14970 14971 const actions_castArray = maybeArray => Array.isArray(maybeArray) ? maybeArray : [maybeArray]; 14972 14973 /** 14974 * Action that resets blocks state to the specified array of blocks, taking precedence 14975 * over any other content reflected as an edit in state. 14976 * 14977 * @param {Array} blocks Array of blocks. 14978 */ 14979 const resetBlocks = blocks => ({ 14980 dispatch 14981 }) => { 14982 dispatch({ 14983 type: 'RESET_BLOCKS', 14984 blocks 14985 }); 14986 dispatch(validateBlocksToTemplate(blocks)); 14987 }; 14988 14989 /** 14990 * Block validity is a function of blocks state (at the point of a 14991 * reset) and the template setting. As a compromise to its placement 14992 * across distinct parts of state, it is implemented here as a side 14993 * effect of the block reset action. 14994 * 14995 * @param {Array} blocks Array of blocks. 14996 */ 14997 const validateBlocksToTemplate = blocks => ({ 14998 select, 14999 dispatch 15000 }) => { 15001 const template = select.getTemplate(); 15002 const templateLock = select.getTemplateLock(); 15003 15004 // Unlocked templates are considered always valid because they act 15005 // as default values only. 15006 const isBlocksValidToTemplate = !template || templateLock !== 'all' || (0,external_wp_blocks_namespaceObject.doBlocksMatchTemplate)(blocks, template); 15007 15008 // Update if validity has changed. 15009 const isValidTemplate = select.isValidTemplate(); 15010 if (isBlocksValidToTemplate !== isValidTemplate) { 15011 dispatch.setTemplateValidity(isBlocksValidToTemplate); 15012 return isBlocksValidToTemplate; 15013 } 15014 }; 15015 15016 /** 15017 * A block selection object. 15018 * 15019 * @typedef {Object} WPBlockSelection 15020 * 15021 * @property {string} clientId A block client ID. 15022 * @property {string} attributeKey A block attribute key. 15023 * @property {number} offset An attribute value offset, based on the rich 15024 * text value. See `wp.richText.create`. 15025 */ 15026 15027 /** 15028 * A selection object. 15029 * 15030 * @typedef {Object} WPSelection 15031 * 15032 * @property {WPBlockSelection} start The selection start. 15033 * @property {WPBlockSelection} end The selection end. 15034 */ 15035 15036 /* eslint-disable jsdoc/valid-types */ 15037 /** 15038 * Returns an action object used in signalling that selection state should be 15039 * reset to the specified selection. 15040 * 15041 * @param {WPBlockSelection} selectionStart The selection start. 15042 * @param {WPBlockSelection} selectionEnd The selection end. 15043 * @param {0|-1|null} initialPosition Initial block position. 15044 * 15045 * @return {Object} Action object. 15046 */ 15047 function resetSelection(selectionStart, selectionEnd, initialPosition) { 15048 /* eslint-enable jsdoc/valid-types */ 15049 return { 15050 type: 'RESET_SELECTION', 15051 selectionStart, 15052 selectionEnd, 15053 initialPosition 15054 }; 15055 } 15056 15057 /** 15058 * Returns an action object used in signalling that blocks have been received. 15059 * Unlike resetBlocks, these should be appended to the existing known set, not 15060 * replacing. 15061 * 15062 * @deprecated 15063 * 15064 * @param {Object[]} blocks Array of block objects. 15065 * 15066 * @return {Object} Action object. 15067 */ 15068 function receiveBlocks(blocks) { 15069 external_wp_deprecated_default()('wp.data.dispatch( "core/block-editor" ).receiveBlocks', { 15070 since: '5.9', 15071 alternative: 'resetBlocks or insertBlocks' 15072 }); 15073 return { 15074 type: 'RECEIVE_BLOCKS', 15075 blocks 15076 }; 15077 } 15078 15079 /** 15080 * Action that updates attributes of multiple blocks with the specified client IDs. 15081 * 15082 * @param {string|string[]} clientIds Block client IDs. 15083 * @param {Object} attributes Block attributes to be merged. Should be keyed by clientIds if 15084 * uniqueByBlock is true. 15085 * @param {boolean} uniqueByBlock true if each block in clientIds array has a unique set of attributes 15086 * @return {Object} Action object. 15087 */ 15088 function updateBlockAttributes(clientIds, attributes, uniqueByBlock = false) { 15089 return { 15090 type: 'UPDATE_BLOCK_ATTRIBUTES', 15091 clientIds: actions_castArray(clientIds), 15092 attributes, 15093 uniqueByBlock 15094 }; 15095 } 15096 15097 /** 15098 * Action that updates the block with the specified client ID. 15099 * 15100 * @param {string} clientId Block client ID. 15101 * @param {Object} updates Block attributes to be merged. 15102 * 15103 * @return {Object} Action object. 15104 */ 15105 function updateBlock(clientId, updates) { 15106 return { 15107 type: 'UPDATE_BLOCK', 15108 clientId, 15109 updates 15110 }; 15111 } 15112 15113 /* eslint-disable jsdoc/valid-types */ 15114 /** 15115 * Returns an action object used in signalling that the block with the 15116 * specified client ID has been selected, optionally accepting a position 15117 * value reflecting its selection directionality. An initialPosition of -1 15118 * reflects a reverse selection. 15119 * 15120 * @param {string} clientId Block client ID. 15121 * @param {0|-1|null} initialPosition Optional initial position. Pass as -1 to 15122 * reflect reverse selection. 15123 * 15124 * @return {Object} Action object. 15125 */ 15126 function selectBlock(clientId, initialPosition = 0) { 15127 /* eslint-enable jsdoc/valid-types */ 15128 return { 15129 type: 'SELECT_BLOCK', 15130 initialPosition, 15131 clientId 15132 }; 15133 } 15134 15135 /** 15136 * Yields action objects used in signalling that the block preceding the given 15137 * clientId (or optionally, its first parent from bottom to top) 15138 * should be selected. 15139 * 15140 * @param {string} clientId Block client ID. 15141 * @param {boolean} fallbackToParent If true, select the first parent if there is no previous block. 15142 */ 15143 const selectPreviousBlock = (clientId, fallbackToParent = false) => ({ 15144 select, 15145 dispatch 15146 }) => { 15147 const previousBlockClientId = select.getPreviousBlockClientId(clientId); 15148 if (previousBlockClientId) { 15149 dispatch.selectBlock(previousBlockClientId, -1); 15150 } else if (fallbackToParent) { 15151 const firstParentClientId = select.getBlockRootClientId(clientId); 15152 if (firstParentClientId) { 15153 dispatch.selectBlock(firstParentClientId, -1); 15154 } 15155 } 15156 }; 15157 15158 /** 15159 * Yields action objects used in signalling that the block following the given 15160 * clientId should be selected. 15161 * 15162 * @param {string} clientId Block client ID. 15163 */ 15164 const selectNextBlock = clientId => ({ 15165 select, 15166 dispatch 15167 }) => { 15168 const nextBlockClientId = select.getNextBlockClientId(clientId); 15169 if (nextBlockClientId) { 15170 dispatch.selectBlock(nextBlockClientId); 15171 } 15172 }; 15173 15174 /** 15175 * Action that starts block multi-selection. 15176 * 15177 * @return {Object} Action object. 15178 */ 15179 function startMultiSelect() { 15180 return { 15181 type: 'START_MULTI_SELECT' 15182 }; 15183 } 15184 15185 /** 15186 * Action that stops block multi-selection. 15187 * 15188 * @return {Object} Action object. 15189 */ 15190 function stopMultiSelect() { 15191 return { 15192 type: 'STOP_MULTI_SELECT' 15193 }; 15194 } 15195 15196 /** 15197 * Action that changes block multi-selection. 15198 * 15199 * @param {string} start First block of the multi selection. 15200 * @param {string} end Last block of the multiselection. 15201 * @param {number|null} __experimentalInitialPosition Optional initial position. Pass as null to skip focus within editor canvas. 15202 */ 15203 const multiSelect = (start, end, __experimentalInitialPosition = 0) => ({ 15204 select, 15205 dispatch 15206 }) => { 15207 const startBlockRootClientId = select.getBlockRootClientId(start); 15208 const endBlockRootClientId = select.getBlockRootClientId(end); 15209 15210 // Only allow block multi-selections at the same level. 15211 if (startBlockRootClientId !== endBlockRootClientId) { 15212 return; 15213 } 15214 dispatch({ 15215 type: 'MULTI_SELECT', 15216 start, 15217 end, 15218 initialPosition: __experimentalInitialPosition 15219 }); 15220 const blockCount = select.getSelectedBlockCount(); 15221 (0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: number of selected blocks */ 15222 (0,external_wp_i18n_namespaceObject._n)('%s block selected.', '%s blocks selected.', blockCount), blockCount), 'assertive'); 15223 }; 15224 15225 /** 15226 * Action that clears the block selection. 15227 * 15228 * @return {Object} Action object. 15229 */ 15230 function clearSelectedBlock() { 15231 return { 15232 type: 'CLEAR_SELECTED_BLOCK' 15233 }; 15234 } 15235 15236 /** 15237 * Action that enables or disables block selection. 15238 * 15239 * @param {boolean} [isSelectionEnabled=true] Whether block selection should 15240 * be enabled. 15241 * 15242 * @return {Object} Action object. 15243 */ 15244 function toggleSelection(isSelectionEnabled = true) { 15245 return { 15246 type: 'TOGGLE_SELECTION', 15247 isSelectionEnabled 15248 }; 15249 } 15250 function getBlocksWithDefaultStylesApplied(blocks, blockEditorSettings) { 15251 var _blockEditorSettings$; 15252 const preferredStyleVariations = (_blockEditorSettings$ = blockEditorSettings?.__experimentalPreferredStyleVariations?.value) !== null && _blockEditorSettings$ !== void 0 ? _blockEditorSettings$ : {}; 15253 return blocks.map(block => { 15254 const blockName = block.name; 15255 if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockName, 'defaultStylePicker', true)) { 15256 return block; 15257 } 15258 if (!preferredStyleVariations[blockName]) { 15259 return block; 15260 } 15261 const className = block.attributes?.className; 15262 if (className?.includes('is-style-')) { 15263 return block; 15264 } 15265 const { 15266 attributes = {} 15267 } = block; 15268 const blockStyle = preferredStyleVariations[blockName]; 15269 return { 15270 ...block, 15271 attributes: { 15272 ...attributes, 15273 className: `$className || ''} is-style-$blockStyle}`.trim() 15274 } 15275 }; 15276 }); 15277 } 15278 15279 /* eslint-disable jsdoc/valid-types */ 15280 /** 15281 * Action that replaces given blocks with one or more replacement blocks. 15282 * 15283 * @param {(string|string[])} clientIds Block client ID(s) to replace. 15284 * @param {(Object|Object[])} blocks Replacement block(s). 15285 * @param {number} indexToSelect Index of replacement block to select. 15286 * @param {0|-1|null} initialPosition Index of caret after in the selected block after the operation. 15287 * @param {?Object} meta Optional Meta values to be passed to the action object. 15288 * 15289 * @return {Object} Action object. 15290 */ 15291 const replaceBlocks = (clientIds, blocks, indexToSelect, initialPosition = 0, meta) => ({ 15292 select, 15293 dispatch, 15294 registry 15295 }) => { 15296 /* eslint-enable jsdoc/valid-types */ 15297 clientIds = actions_castArray(clientIds); 15298 blocks = getBlocksWithDefaultStylesApplied(actions_castArray(blocks), select.getSettings()); 15299 const rootClientId = select.getBlockRootClientId(clientIds[0]); 15300 // Replace is valid if the new blocks can be inserted in the root block. 15301 for (let index = 0; index < blocks.length; index++) { 15302 const block = blocks[index]; 15303 const canInsertBlock = select.canInsertBlockType(block.name, rootClientId); 15304 if (!canInsertBlock) { 15305 return; 15306 } 15307 } 15308 // We're batching these two actions because an extra `undo/redo` step can 15309 // be created, based on whether we insert a default block or not. 15310 registry.batch(() => { 15311 dispatch({ 15312 type: 'REPLACE_BLOCKS', 15313 clientIds, 15314 blocks, 15315 time: Date.now(), 15316 indexToSelect, 15317 initialPosition, 15318 meta 15319 }); 15320 // To avoid a focus loss when removing the last block, assure there is 15321 // always a default block if the last of the blocks have been removed. 15322 dispatch.ensureDefaultBlock(); 15323 }); 15324 }; 15325 15326 /** 15327 * Action that replaces a single block with one or more replacement blocks. 15328 * 15329 * @param {(string|string[])} clientId Block client ID to replace. 15330 * @param {(Object|Object[])} block Replacement block(s). 15331 * 15332 * @return {Object} Action object. 15333 */ 15334 function replaceBlock(clientId, block) { 15335 return replaceBlocks(clientId, block); 15336 } 15337 15338 /** 15339 * Higher-order action creator which, given the action type to dispatch creates 15340 * an action creator for managing block movement. 15341 * 15342 * @param {string} type Action type to dispatch. 15343 * 15344 * @return {Function} Action creator. 15345 */ 15346 const createOnMove = type => (clientIds, rootClientId) => ({ 15347 select, 15348 dispatch 15349 }) => { 15350 // If one of the blocks is locked or the parent is locked, we cannot move any block. 15351 const canMoveBlocks = select.canMoveBlocks(clientIds, rootClientId); 15352 if (!canMoveBlocks) { 15353 return; 15354 } 15355 dispatch({ 15356 type, 15357 clientIds: actions_castArray(clientIds), 15358 rootClientId 15359 }); 15360 }; 15361 const moveBlocksDown = createOnMove('MOVE_BLOCKS_DOWN'); 15362 const moveBlocksUp = createOnMove('MOVE_BLOCKS_UP'); 15363 15364 /** 15365 * Action that moves given blocks to a new position. 15366 * 15367 * @param {?string} clientIds The client IDs of the blocks. 15368 * @param {?string} fromRootClientId Root client ID source. 15369 * @param {?string} toRootClientId Root client ID destination. 15370 * @param {number} index The index to move the blocks to. 15371 */ 15372 const moveBlocksToPosition = (clientIds, fromRootClientId = '', toRootClientId = '', index) => ({ 15373 select, 15374 dispatch 15375 }) => { 15376 const canMoveBlocks = select.canMoveBlocks(clientIds, fromRootClientId); 15377 15378 // If one of the blocks is locked or the parent is locked, we cannot move any block. 15379 if (!canMoveBlocks) { 15380 return; 15381 } 15382 15383 // If moving inside the same root block the move is always possible. 15384 if (fromRootClientId !== toRootClientId) { 15385 const canRemoveBlocks = select.canRemoveBlocks(clientIds, fromRootClientId); 15386 15387 // If we're moving to another block, it means we're deleting blocks from 15388 // the original block, so we need to check if removing is possible. 15389 if (!canRemoveBlocks) { 15390 return; 15391 } 15392 const canInsertBlocks = select.canInsertBlocks(clientIds, toRootClientId); 15393 15394 // If moving to other parent block, the move is possible if we can insert a block of the same type inside the new parent block. 15395 if (!canInsertBlocks) { 15396 return; 15397 } 15398 } 15399 dispatch({ 15400 type: 'MOVE_BLOCKS_TO_POSITION', 15401 fromRootClientId, 15402 toRootClientId, 15403 clientIds, 15404 index 15405 }); 15406 }; 15407 15408 /** 15409 * Action that moves given block to a new position. 15410 * 15411 * @param {?string} clientId The client ID of the block. 15412 * @param {?string} fromRootClientId Root client ID source. 15413 * @param {?string} toRootClientId Root client ID destination. 15414 * @param {number} index The index to move the block to. 15415 */ 15416 function moveBlockToPosition(clientId, fromRootClientId = '', toRootClientId = '', index) { 15417 return moveBlocksToPosition([clientId], fromRootClientId, toRootClientId, index); 15418 } 15419 15420 /** 15421 * Action that inserts a single block, optionally at a specific index respective a root block list. 15422 * 15423 * Only allowed blocks are inserted. The action may fail silently for blocks that are not allowed or if 15424 * a templateLock is active on the block list. 15425 * 15426 * @param {Object} block Block object to insert. 15427 * @param {?number} index Index at which block should be inserted. 15428 * @param {?string} rootClientId Optional root client ID of block list on which to insert. 15429 * @param {?boolean} updateSelection If true block selection will be updated. If false, block selection will not change. Defaults to true. 15430 * @param {?Object} meta Optional Meta values to be passed to the action object. 15431 * 15432 * @return {Object} Action object. 15433 */ 15434 function insertBlock(block, index, rootClientId, updateSelection, meta) { 15435 return insertBlocks([block], index, rootClientId, updateSelection, 0, meta); 15436 } 15437 15438 /* eslint-disable jsdoc/valid-types */ 15439 /** 15440 * Action that inserts an array of blocks, optionally at a specific index respective a root block list. 15441 * 15442 * Only allowed blocks are inserted. The action may fail silently for blocks that are not allowed or if 15443 * a templateLock is active on the block list. 15444 * 15445 * @param {Object[]} blocks Block objects to insert. 15446 * @param {?number} index Index at which block should be inserted. 15447 * @param {?string} rootClientId Optional root client ID of block list on which to insert. 15448 * @param {?boolean} updateSelection If true block selection will be updated. If false, block selection will not change. Defaults to true. 15449 * @param {0|-1|null} initialPosition Initial focus position. Setting it to null prevent focusing the inserted block. 15450 * @param {?Object} meta Optional Meta values to be passed to the action object. 15451 * 15452 * @return {Object} Action object. 15453 */ 15454 const insertBlocks = (blocks, index, rootClientId, updateSelection = true, initialPosition = 0, meta) => ({ 15455 select, 15456 dispatch 15457 }) => { 15458 /* eslint-enable jsdoc/valid-types */ 15459 if (initialPosition !== null && typeof initialPosition === 'object') { 15460 meta = initialPosition; 15461 initialPosition = 0; 15462 external_wp_deprecated_default()("meta argument in wp.data.dispatch('core/block-editor')", { 15463 since: '5.8', 15464 hint: 'The meta argument is now the 6th argument of the function' 15465 }); 15466 } 15467 blocks = getBlocksWithDefaultStylesApplied(actions_castArray(blocks), select.getSettings()); 15468 const allowedBlocks = []; 15469 for (const block of blocks) { 15470 const isValid = select.canInsertBlockType(block.name, rootClientId); 15471 if (isValid) { 15472 allowedBlocks.push(block); 15473 } 15474 } 15475 if (allowedBlocks.length) { 15476 dispatch({ 15477 type: 'INSERT_BLOCKS', 15478 blocks: allowedBlocks, 15479 index, 15480 rootClientId, 15481 time: Date.now(), 15482 updateSelection, 15483 initialPosition: updateSelection ? initialPosition : null, 15484 meta 15485 }); 15486 } 15487 }; 15488 15489 /** 15490 * Action that shows the insertion point. 15491 * 15492 * @param {?string} rootClientId Optional root client ID of block list on 15493 * which to insert. 15494 * @param {?number} index Index at which block should be inserted. 15495 * @param {?Object} __unstableOptions Additional options. 15496 * @property {boolean} __unstableWithInserter Whether or not to show an inserter button. 15497 * @property {WPDropOperation} operation The operation to perform when applied, 15498 * either 'insert' or 'replace' for now. 15499 * 15500 * @return {Object} Action object. 15501 */ 15502 function showInsertionPoint(rootClientId, index, __unstableOptions = {}) { 15503 const { 15504 __unstableWithInserter, 15505 operation, 15506 nearestSide 15507 } = __unstableOptions; 15508 return { 15509 type: 'SHOW_INSERTION_POINT', 15510 rootClientId, 15511 index, 15512 __unstableWithInserter, 15513 operation, 15514 nearestSide 15515 }; 15516 } 15517 /** 15518 * Action that hides the insertion point. 15519 */ 15520 const hideInsertionPoint = () => ({ 15521 select, 15522 dispatch 15523 }) => { 15524 if (!select.isBlockInsertionPointVisible()) { 15525 return; 15526 } 15527 dispatch({ 15528 type: 'HIDE_INSERTION_POINT' 15529 }); 15530 }; 15531 15532 /** 15533 * Action that resets the template validity. 15534 * 15535 * @param {boolean} isValid template validity flag. 15536 * 15537 * @return {Object} Action object. 15538 */ 15539 function setTemplateValidity(isValid) { 15540 return { 15541 type: 'SET_TEMPLATE_VALIDITY', 15542 isValid 15543 }; 15544 } 15545 15546 /** 15547 * Action that synchronizes the template with the list of blocks. 15548 * 15549 * @return {Object} Action object. 15550 */ 15551 const synchronizeTemplate = () => ({ 15552 select, 15553 dispatch 15554 }) => { 15555 dispatch({ 15556 type: 'SYNCHRONIZE_TEMPLATE' 15557 }); 15558 const blocks = select.getBlocks(); 15559 const template = select.getTemplate(); 15560 const updatedBlockList = (0,external_wp_blocks_namespaceObject.synchronizeBlocksWithTemplate)(blocks, template); 15561 dispatch.resetBlocks(updatedBlockList); 15562 }; 15563 15564 /** 15565 * Delete the current selection. 15566 * 15567 * @param {boolean} isForward 15568 */ 15569 const __unstableDeleteSelection = isForward => ({ 15570 registry, 15571 select, 15572 dispatch 15573 }) => { 15574 const selectionAnchor = select.getSelectionStart(); 15575 const selectionFocus = select.getSelectionEnd(); 15576 if (selectionAnchor.clientId === selectionFocus.clientId) return; 15577 15578 // It's not mergeable if there's no rich text selection. 15579 if (!selectionAnchor.attributeKey || !selectionFocus.attributeKey || typeof selectionAnchor.offset === 'undefined' || typeof selectionFocus.offset === 'undefined') return false; 15580 const anchorRootClientId = select.getBlockRootClientId(selectionAnchor.clientId); 15581 const focusRootClientId = select.getBlockRootClientId(selectionFocus.clientId); 15582 15583 // It's not mergeable if the selection doesn't start and end in the same 15584 // block list. Maybe in the future it should be allowed. 15585 if (anchorRootClientId !== focusRootClientId) { 15586 return; 15587 } 15588 const blockOrder = select.getBlockOrder(anchorRootClientId); 15589 const anchorIndex = blockOrder.indexOf(selectionAnchor.clientId); 15590 const focusIndex = blockOrder.indexOf(selectionFocus.clientId); 15591 15592 // Reassign selection start and end based on order. 15593 let selectionStart, selectionEnd; 15594 if (anchorIndex > focusIndex) { 15595 selectionStart = selectionFocus; 15596 selectionEnd = selectionAnchor; 15597 } else { 15598 selectionStart = selectionAnchor; 15599 selectionEnd = selectionFocus; 15600 } 15601 const targetSelection = isForward ? selectionEnd : selectionStart; 15602 const targetBlock = select.getBlock(targetSelection.clientId); 15603 const targetBlockType = (0,external_wp_blocks_namespaceObject.getBlockType)(targetBlock.name); 15604 if (!targetBlockType.merge) { 15605 return; 15606 } 15607 const selectionA = selectionStart; 15608 const selectionB = selectionEnd; 15609 const blockA = select.getBlock(selectionA.clientId); 15610 const blockB = select.getBlock(selectionB.clientId); 15611 const htmlA = blockA.attributes[selectionA.attributeKey]; 15612 const htmlB = blockB.attributes[selectionB.attributeKey]; 15613 let valueA = (0,external_wp_richText_namespaceObject.create)({ 15614 html: htmlA 15615 }); 15616 let valueB = (0,external_wp_richText_namespaceObject.create)({ 15617 html: htmlB 15618 }); 15619 valueA = (0,external_wp_richText_namespaceObject.remove)(valueA, selectionA.offset, valueA.text.length); 15620 valueB = (0,external_wp_richText_namespaceObject.insert)(valueB, START_OF_SELECTED_AREA, 0, selectionB.offset); 15621 15622 // Clone the blocks so we don't manipulate the original. 15623 const cloneA = (0,external_wp_blocks_namespaceObject.cloneBlock)(blockA, { 15624 [selectionA.attributeKey]: (0,external_wp_richText_namespaceObject.toHTMLString)({ 15625 value: valueA 15626 }) 15627 }); 15628 const cloneB = (0,external_wp_blocks_namespaceObject.cloneBlock)(blockB, { 15629 [selectionB.attributeKey]: (0,external_wp_richText_namespaceObject.toHTMLString)({ 15630 value: valueB 15631 }) 15632 }); 15633 const followingBlock = isForward ? cloneA : cloneB; 15634 15635 // We can only merge blocks with similar types 15636 // thus, we transform the block to merge first 15637 const blocksWithTheSameType = blockA.name === blockB.name ? [followingBlock] : (0,external_wp_blocks_namespaceObject.switchToBlockType)(followingBlock, targetBlockType.name); 15638 15639 // If the block types can not match, do nothing 15640 if (!blocksWithTheSameType || !blocksWithTheSameType.length) { 15641 return; 15642 } 15643 let updatedAttributes; 15644 if (isForward) { 15645 const blockToMerge = blocksWithTheSameType.pop(); 15646 updatedAttributes = targetBlockType.merge(blockToMerge.attributes, cloneB.attributes); 15647 } else { 15648 const blockToMerge = blocksWithTheSameType.shift(); 15649 updatedAttributes = targetBlockType.merge(cloneA.attributes, blockToMerge.attributes); 15650 } 15651 const newAttributeKey = retrieveSelectedAttribute(updatedAttributes); 15652 const convertedHtml = updatedAttributes[newAttributeKey]; 15653 const convertedValue = (0,external_wp_richText_namespaceObject.create)({ 15654 html: convertedHtml 15655 }); 15656 const newOffset = convertedValue.text.indexOf(START_OF_SELECTED_AREA); 15657 const newValue = (0,external_wp_richText_namespaceObject.remove)(convertedValue, newOffset, newOffset + 1); 15658 const newHtml = (0,external_wp_richText_namespaceObject.toHTMLString)({ 15659 value: newValue 15660 }); 15661 updatedAttributes[newAttributeKey] = newHtml; 15662 const selectedBlockClientIds = select.getSelectedBlockClientIds(); 15663 const replacement = [...(isForward ? blocksWithTheSameType : []), { 15664 // Preserve the original client ID. 15665 ...targetBlock, 15666 attributes: { 15667 ...targetBlock.attributes, 15668 ...updatedAttributes 15669 } 15670 }, ...(isForward ? [] : blocksWithTheSameType)]; 15671 registry.batch(() => { 15672 dispatch.selectionChange(targetBlock.clientId, newAttributeKey, newOffset, newOffset); 15673 dispatch.replaceBlocks(selectedBlockClientIds, replacement, 0, 15674 // If we don't pass the `indexToSelect` it will default to the last block. 15675 select.getSelectedBlocksInitialCaretPosition()); 15676 }); 15677 }; 15678 15679 /** 15680 * Split the current selection. 15681 */ 15682 const __unstableSplitSelection = () => ({ 15683 select, 15684 dispatch 15685 }) => { 15686 const selectionAnchor = select.getSelectionStart(); 15687 const selectionFocus = select.getSelectionEnd(); 15688 if (selectionAnchor.clientId === selectionFocus.clientId) return; 15689 15690 // Can't split if the selection is not set. 15691 if (!selectionAnchor.attributeKey || !selectionFocus.attributeKey || typeof selectionAnchor.offset === 'undefined' || typeof selectionFocus.offset === 'undefined') return; 15692 const anchorRootClientId = select.getBlockRootClientId(selectionAnchor.clientId); 15693 const focusRootClientId = select.getBlockRootClientId(selectionFocus.clientId); 15694 15695 // It's not splittable if the selection doesn't start and end in the same 15696 // block list. Maybe in the future it should be allowed. 15697 if (anchorRootClientId !== focusRootClientId) { 15698 return; 15699 } 15700 const blockOrder = select.getBlockOrder(anchorRootClientId); 15701 const anchorIndex = blockOrder.indexOf(selectionAnchor.clientId); 15702 const focusIndex = blockOrder.indexOf(selectionFocus.clientId); 15703 15704 // Reassign selection start and end based on order. 15705 let selectionStart, selectionEnd; 15706 if (anchorIndex > focusIndex) { 15707 selectionStart = selectionFocus; 15708 selectionEnd = selectionAnchor; 15709 } else { 15710 selectionStart = selectionAnchor; 15711 selectionEnd = selectionFocus; 15712 } 15713 const selectionA = selectionStart; 15714 const selectionB = selectionEnd; 15715 const blockA = select.getBlock(selectionA.clientId); 15716 const blockB = select.getBlock(selectionB.clientId); 15717 const htmlA = blockA.attributes[selectionA.attributeKey]; 15718 const htmlB = blockB.attributes[selectionB.attributeKey]; 15719 let valueA = (0,external_wp_richText_namespaceObject.create)({ 15720 html: htmlA 15721 }); 15722 let valueB = (0,external_wp_richText_namespaceObject.create)({ 15723 html: htmlB 15724 }); 15725 valueA = (0,external_wp_richText_namespaceObject.remove)(valueA, selectionA.offset, valueA.text.length); 15726 valueB = (0,external_wp_richText_namespaceObject.remove)(valueB, 0, selectionB.offset); 15727 dispatch.replaceBlocks(select.getSelectedBlockClientIds(), [{ 15728 // Preserve the original client ID. 15729 ...blockA, 15730 attributes: { 15731 ...blockA.attributes, 15732 [selectionA.attributeKey]: (0,external_wp_richText_namespaceObject.toHTMLString)({ 15733 value: valueA 15734 }) 15735 } 15736 }, { 15737 // Preserve the original client ID. 15738 ...blockB, 15739 attributes: { 15740 ...blockB.attributes, 15741 [selectionB.attributeKey]: (0,external_wp_richText_namespaceObject.toHTMLString)({ 15742 value: valueB 15743 }) 15744 } 15745 }]); 15746 }; 15747 15748 /** 15749 * Expand the selection to cover the entire blocks, removing partial selection. 15750 */ 15751 const __unstableExpandSelection = () => ({ 15752 select, 15753 dispatch 15754 }) => { 15755 const selectionAnchor = select.getSelectionStart(); 15756 const selectionFocus = select.getSelectionEnd(); 15757 dispatch.selectionChange({ 15758 start: { 15759 clientId: selectionAnchor.clientId 15760 }, 15761 end: { 15762 clientId: selectionFocus.clientId 15763 } 15764 }); 15765 }; 15766 15767 /** 15768 * Action that merges two blocks. 15769 * 15770 * @param {string} firstBlockClientId Client ID of the first block to merge. 15771 * @param {string} secondBlockClientId Client ID of the second block to merge. 15772 */ 15773 const mergeBlocks = (firstBlockClientId, secondBlockClientId) => ({ 15774 registry, 15775 select, 15776 dispatch 15777 }) => { 15778 const blocks = [firstBlockClientId, secondBlockClientId]; 15779 dispatch({ 15780 type: 'MERGE_BLOCKS', 15781 blocks 15782 }); 15783 const [clientIdA, clientIdB] = blocks; 15784 const blockA = select.getBlock(clientIdA); 15785 const blockAType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockA.name); 15786 if (!blockAType) return; 15787 const blockB = select.getBlock(clientIdB); 15788 if (!blockAType.merge && (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockA.name, '__experimentalOnMerge')) { 15789 // If there's no merge function defined, attempt merging inner 15790 // blocks. 15791 const blocksWithTheSameType = (0,external_wp_blocks_namespaceObject.switchToBlockType)(blockB, blockAType.name); 15792 // Only focus the previous block if it's not mergeable. 15793 if (blocksWithTheSameType?.length !== 1) { 15794 dispatch.selectBlock(blockA.clientId); 15795 return; 15796 } 15797 const [blockWithSameType] = blocksWithTheSameType; 15798 if (blockWithSameType.innerBlocks.length < 1) { 15799 dispatch.selectBlock(blockA.clientId); 15800 return; 15801 } 15802 registry.batch(() => { 15803 dispatch.insertBlocks(blockWithSameType.innerBlocks, undefined, clientIdA); 15804 dispatch.removeBlock(clientIdB); 15805 dispatch.selectBlock(blockWithSameType.innerBlocks[0].clientId); 15806 15807 // Attempt to merge the next block if it's the same type and 15808 // same attributes. This is useful when merging a paragraph into 15809 // a list, and the next block is also a list. If we don't merge, 15810 // it looks like one list, but it's actually two lists. The same 15811 // applies to other blocks such as a group with the same 15812 // attributes. 15813 const nextBlockClientId = select.getNextBlockClientId(clientIdA); 15814 if (nextBlockClientId && select.getBlockName(clientIdA) === select.getBlockName(nextBlockClientId)) { 15815 const rootAttributes = select.getBlockAttributes(clientIdA); 15816 const previousRootAttributes = select.getBlockAttributes(nextBlockClientId); 15817 if (Object.keys(rootAttributes).every(key => rootAttributes[key] === previousRootAttributes[key])) { 15818 dispatch.moveBlocksToPosition(select.getBlockOrder(nextBlockClientId), nextBlockClientId, clientIdA); 15819 dispatch.removeBlock(nextBlockClientId, false); 15820 } 15821 } 15822 }); 15823 return; 15824 } 15825 if ((0,external_wp_blocks_namespaceObject.isUnmodifiedDefaultBlock)(blockA)) { 15826 dispatch.removeBlock(clientIdA, select.isBlockSelected(clientIdA)); 15827 return; 15828 } 15829 if ((0,external_wp_blocks_namespaceObject.isUnmodifiedDefaultBlock)(blockB)) { 15830 dispatch.removeBlock(clientIdB, select.isBlockSelected(clientIdB)); 15831 return; 15832 } 15833 if (!blockAType.merge) { 15834 dispatch.selectBlock(blockA.clientId); 15835 return; 15836 } 15837 const blockBType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockB.name); 15838 const { 15839 clientId, 15840 attributeKey, 15841 offset 15842 } = select.getSelectionStart(); 15843 const selectedBlockType = clientId === clientIdA ? blockAType : blockBType; 15844 const attributeDefinition = selectedBlockType.attributes[attributeKey]; 15845 const canRestoreTextSelection = (clientId === clientIdA || clientId === clientIdB) && attributeKey !== undefined && offset !== undefined && 15846 // We cannot restore text selection if the RichText identifier 15847 // is not a defined block attribute key. This can be the case if the 15848 // fallback intance ID is used to store selection (and no RichText 15849 // identifier is set), or when the identifier is wrong. 15850 !!attributeDefinition; 15851 if (!attributeDefinition) { 15852 if (typeof attributeKey === 'number') { 15853 window.console.error(`RichText needs an identifier prop that is the block attribute key of the attribute it controls. Its type is expected to be a string, but was $typeof attributeKey}`); 15854 } else { 15855 window.console.error('The RichText identifier prop does not match any attributes defined by the block.'); 15856 } 15857 } 15858 15859 // Clone the blocks so we don't insert the character in a "live" block. 15860 const cloneA = (0,external_wp_blocks_namespaceObject.cloneBlock)(blockA); 15861 const cloneB = (0,external_wp_blocks_namespaceObject.cloneBlock)(blockB); 15862 if (canRestoreTextSelection) { 15863 const selectedBlock = clientId === clientIdA ? cloneA : cloneB; 15864 const html = selectedBlock.attributes[attributeKey]; 15865 const value = (0,external_wp_richText_namespaceObject.insert)((0,external_wp_richText_namespaceObject.create)({ 15866 html 15867 }), START_OF_SELECTED_AREA, offset, offset); 15868 selectedBlock.attributes[attributeKey] = (0,external_wp_richText_namespaceObject.toHTMLString)({ 15869 value 15870 }); 15871 } 15872 15873 // We can only merge blocks with similar types 15874 // thus, we transform the block to merge first. 15875 const blocksWithTheSameType = blockA.name === blockB.name ? [cloneB] : (0,external_wp_blocks_namespaceObject.switchToBlockType)(cloneB, blockA.name); 15876 15877 // If the block types can not match, do nothing. 15878 if (!blocksWithTheSameType || !blocksWithTheSameType.length) { 15879 return; 15880 } 15881 15882 // Calling the merge to update the attributes and remove the block to be merged. 15883 const updatedAttributes = blockAType.merge(cloneA.attributes, blocksWithTheSameType[0].attributes); 15884 if (canRestoreTextSelection) { 15885 const newAttributeKey = retrieveSelectedAttribute(updatedAttributes); 15886 const convertedHtml = updatedAttributes[newAttributeKey]; 15887 const convertedValue = (0,external_wp_richText_namespaceObject.create)({ 15888 html: convertedHtml 15889 }); 15890 const newOffset = convertedValue.text.indexOf(START_OF_SELECTED_AREA); 15891 const newValue = (0,external_wp_richText_namespaceObject.remove)(convertedValue, newOffset, newOffset + 1); 15892 const newHtml = (0,external_wp_richText_namespaceObject.toHTMLString)({ 15893 value: newValue 15894 }); 15895 updatedAttributes[newAttributeKey] = newHtml; 15896 dispatch.selectionChange(blockA.clientId, newAttributeKey, newOffset, newOffset); 15897 } 15898 dispatch.replaceBlocks([blockA.clientId, blockB.clientId], [{ 15899 ...blockA, 15900 attributes: { 15901 ...blockA.attributes, 15902 ...updatedAttributes 15903 } 15904 }, ...blocksWithTheSameType.slice(1)], 0 // If we don't pass the `indexToSelect` it will default to the last block. 15905 ); 15906 }; 15907 15908 /** 15909 * Yields action objects used in signalling that the blocks corresponding to 15910 * the set of specified client IDs are to be removed. 15911 * 15912 * @param {string|string[]} clientIds Client IDs of blocks to remove. 15913 * @param {boolean} selectPrevious True if the previous block 15914 * or the immediate parent 15915 * (if no previous block exists) 15916 * should be selected 15917 * when a block is removed. 15918 */ 15919 const removeBlocks = (clientIds, selectPrevious = true) => privateRemoveBlocks(clientIds, selectPrevious); 15920 15921 /** 15922 * Returns an action object used in signalling that the block with the 15923 * specified client ID is to be removed. 15924 * 15925 * @param {string} clientId Client ID of block to remove. 15926 * @param {boolean} selectPrevious True if the previous block should be 15927 * selected when a block is removed. 15928 * 15929 * @return {Object} Action object. 15930 */ 15931 function removeBlock(clientId, selectPrevious) { 15932 return removeBlocks([clientId], selectPrevious); 15933 } 15934 15935 /* eslint-disable jsdoc/valid-types */ 15936 /** 15937 * Returns an action object used in signalling that the inner blocks with the 15938 * specified client ID should be replaced. 15939 * 15940 * @param {string} rootClientId Client ID of the block whose InnerBlocks will re replaced. 15941 * @param {Object[]} blocks Block objects to insert as new InnerBlocks 15942 * @param {?boolean} updateSelection If true block selection will be updated. If false, block selection will not change. Defaults to false. 15943 * @param {0|-1|null} initialPosition Initial block position. 15944 * @return {Object} Action object. 15945 */ 15946 function replaceInnerBlocks(rootClientId, blocks, updateSelection = false, initialPosition = 0) { 15947 /* eslint-enable jsdoc/valid-types */ 15948 return { 15949 type: 'REPLACE_INNER_BLOCKS', 15950 rootClientId, 15951 blocks, 15952 updateSelection, 15953 initialPosition: updateSelection ? initialPosition : null, 15954 time: Date.now() 15955 }; 15956 } 15957 15958 /** 15959 * Returns an action object used to toggle the block editing mode between 15960 * visual and HTML modes. 15961 * 15962 * @param {string} clientId Block client ID. 15963 * 15964 * @return {Object} Action object. 15965 */ 15966 function toggleBlockMode(clientId) { 15967 return { 15968 type: 'TOGGLE_BLOCK_MODE', 15969 clientId 15970 }; 15971 } 15972 15973 /** 15974 * Returns an action object used in signalling that the user has begun to type. 15975 * 15976 * @return {Object} Action object. 15977 */ 15978 function startTyping() { 15979 return { 15980 type: 'START_TYPING' 15981 }; 15982 } 15983 15984 /** 15985 * Returns an action object used in signalling that the user has stopped typing. 15986 * 15987 * @return {Object} Action object. 15988 */ 15989 function stopTyping() { 15990 return { 15991 type: 'STOP_TYPING' 15992 }; 15993 } 15994 15995 /** 15996 * Returns an action object used in signalling that the user has begun to drag blocks. 15997 * 15998 * @param {string[]} clientIds An array of client ids being dragged 15999 * 16000 * @return {Object} Action object. 16001 */ 16002 function startDraggingBlocks(clientIds = []) { 16003 return { 16004 type: 'START_DRAGGING_BLOCKS', 16005 clientIds 16006 }; 16007 } 16008 16009 /** 16010 * Returns an action object used in signalling that the user has stopped dragging blocks. 16011 * 16012 * @return {Object} Action object. 16013 */ 16014 function stopDraggingBlocks() { 16015 return { 16016 type: 'STOP_DRAGGING_BLOCKS' 16017 }; 16018 } 16019 16020 /** 16021 * Returns an action object used in signalling that the caret has entered formatted text. 16022 * 16023 * @deprecated 16024 * 16025 * @return {Object} Action object. 16026 */ 16027 function enterFormattedText() { 16028 external_wp_deprecated_default()('wp.data.dispatch( "core/block-editor" ).enterFormattedText', { 16029 since: '6.1', 16030 version: '6.3' 16031 }); 16032 return { 16033 type: 'DO_NOTHING' 16034 }; 16035 } 16036 16037 /** 16038 * Returns an action object used in signalling that the user caret has exited formatted text. 16039 * 16040 * @deprecated 16041 * 16042 * @return {Object} Action object. 16043 */ 16044 function exitFormattedText() { 16045 external_wp_deprecated_default()('wp.data.dispatch( "core/block-editor" ).exitFormattedText', { 16046 since: '6.1', 16047 version: '6.3' 16048 }); 16049 return { 16050 type: 'DO_NOTHING' 16051 }; 16052 } 16053 16054 /** 16055 * Action that changes the position of the user caret. 16056 * 16057 * @param {string|WPSelection} clientId The selected block client ID. 16058 * @param {string} attributeKey The selected block attribute key. 16059 * @param {number} startOffset The start offset. 16060 * @param {number} endOffset The end offset. 16061 * 16062 * @return {Object} Action object. 16063 */ 16064 function selectionChange(clientId, attributeKey, startOffset, endOffset) { 16065 if (typeof clientId === 'string') { 16066 return { 16067 type: 'SELECTION_CHANGE', 16068 clientId, 16069 attributeKey, 16070 startOffset, 16071 endOffset 16072 }; 16073 } 16074 return { 16075 type: 'SELECTION_CHANGE', 16076 ...clientId 16077 }; 16078 } 16079 16080 /** 16081 * Action that adds a new block of the default type to the block list. 16082 * 16083 * @param {?Object} attributes Optional attributes of the block to assign. 16084 * @param {?string} rootClientId Optional root client ID of block list on which 16085 * to append. 16086 * @param {?number} index Optional index where to insert the default block. 16087 */ 16088 const insertDefaultBlock = (attributes, rootClientId, index) => ({ 16089 dispatch 16090 }) => { 16091 // Abort if there is no default block type (if it has been unregistered). 16092 const defaultBlockName = (0,external_wp_blocks_namespaceObject.getDefaultBlockName)(); 16093 if (!defaultBlockName) { 16094 return; 16095 } 16096 const block = (0,external_wp_blocks_namespaceObject.createBlock)(defaultBlockName, attributes); 16097 return dispatch.insertBlock(block, index, rootClientId); 16098 }; 16099 16100 /** 16101 * Action that changes the nested settings of a given block. 16102 * 16103 * @param {string} clientId Client ID of the block whose nested setting are 16104 * being received. 16105 * @param {Object} settings Object with the new settings for the nested block. 16106 * 16107 * @return {Object} Action object 16108 */ 16109 function updateBlockListSettings(clientId, settings) { 16110 return { 16111 type: 'UPDATE_BLOCK_LIST_SETTINGS', 16112 clientId, 16113 settings 16114 }; 16115 } 16116 16117 /** 16118 * Action that updates the block editor settings. 16119 * 16120 * @param {Object} settings Updated settings 16121 * 16122 * @return {Object} Action object 16123 */ 16124 function updateSettings(settings) { 16125 return __experimentalUpdateSettings(settings, { 16126 stripExperimentalSettings: true 16127 }); 16128 } 16129 16130 /** 16131 * Action that signals that a temporary reusable block has been saved 16132 * in order to switch its temporary id with the real id. 16133 * 16134 * @param {string} id Reusable block's id. 16135 * @param {string} updatedId Updated block's id. 16136 * 16137 * @return {Object} Action object. 16138 */ 16139 function __unstableSaveReusableBlock(id, updatedId) { 16140 return { 16141 type: 'SAVE_REUSABLE_BLOCK_SUCCESS', 16142 id, 16143 updatedId 16144 }; 16145 } 16146 16147 /** 16148 * Action that marks the last block change explicitly as persistent. 16149 * 16150 * @return {Object} Action object. 16151 */ 16152 function __unstableMarkLastChangeAsPersistent() { 16153 return { 16154 type: 'MARK_LAST_CHANGE_AS_PERSISTENT' 16155 }; 16156 } 16157 16158 /** 16159 * Action that signals that the next block change should be marked explicitly as not persistent. 16160 * 16161 * @return {Object} Action object. 16162 */ 16163 function __unstableMarkNextChangeAsNotPersistent() { 16164 return { 16165 type: 'MARK_NEXT_CHANGE_AS_NOT_PERSISTENT' 16166 }; 16167 } 16168 16169 /** 16170 * Action that marks the last block change as an automatic change, meaning it was not 16171 * performed by the user, and can be undone using the `Escape` and `Backspace` keys. 16172 * This action must be called after the change was made, and any actions that are a 16173 * consequence of it, so it is recommended to be called at the next idle period to ensure all 16174 * selection changes have been recorded. 16175 */ 16176 const __unstableMarkAutomaticChange = () => ({ 16177 dispatch 16178 }) => { 16179 dispatch({ 16180 type: 'MARK_AUTOMATIC_CHANGE' 16181 }); 16182 const { 16183 requestIdleCallback = cb => setTimeout(cb, 100) 16184 } = window; 16185 requestIdleCallback(() => { 16186 dispatch({ 16187 type: 'MARK_AUTOMATIC_CHANGE_FINAL' 16188 }); 16189 }); 16190 }; 16191 16192 /** 16193 * Action that enables or disables the navigation mode. 16194 * 16195 * @param {boolean} isNavigationMode Enable/Disable navigation mode. 16196 */ 16197 const setNavigationMode = (isNavigationMode = true) => ({ 16198 dispatch 16199 }) => { 16200 dispatch.__unstableSetEditorMode(isNavigationMode ? 'navigation' : 'edit'); 16201 }; 16202 16203 /** 16204 * Action that sets the editor mode 16205 * 16206 * @param {string} mode Editor mode 16207 */ 16208 const __unstableSetEditorMode = mode => ({ 16209 dispatch, 16210 select 16211 }) => { 16212 // When switching to zoom-out mode, we need to select the root block 16213 if (mode === 'zoom-out') { 16214 const firstSelectedClientId = select.getBlockSelectionStart(); 16215 if (firstSelectedClientId) { 16216 dispatch.selectBlock(select.getBlockHierarchyRootClientId(firstSelectedClientId)); 16217 } 16218 } 16219 dispatch({ 16220 type: 'SET_EDITOR_MODE', 16221 mode 16222 }); 16223 if (mode === 'navigation') { 16224 (0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.__)('You are currently in navigation mode. Navigate blocks using the Tab key and Arrow keys. Use Left and Right Arrow keys to move between nesting levels. To exit navigation mode and edit the selected block, press Enter.')); 16225 } else if (mode === 'edit') { 16226 (0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.__)('You are currently in edit mode. To return to the navigation mode, press Escape.')); 16227 } else if (mode === 'zoom-out') { 16228 (0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.__)('You are currently in zoom-out mode.')); 16229 } 16230 }; 16231 16232 /** 16233 * Action that enables or disables the block moving mode. 16234 * 16235 * @param {string|null} hasBlockMovingClientId Enable/Disable block moving mode. 16236 */ 16237 const setBlockMovingClientId = (hasBlockMovingClientId = null) => ({ 16238 dispatch 16239 }) => { 16240 dispatch({ 16241 type: 'SET_BLOCK_MOVING_MODE', 16242 hasBlockMovingClientId 16243 }); 16244 if (hasBlockMovingClientId) { 16245 (0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.__)('Use the Tab key and Arrow keys to choose new block location. Use Left and Right Arrow keys to move between nesting levels. Once location is selected press Enter or Space to move the block.')); 16246 } 16247 }; 16248 16249 /** 16250 * Action that duplicates a list of blocks. 16251 * 16252 * @param {string[]} clientIds 16253 * @param {boolean} updateSelection 16254 */ 16255 const duplicateBlocks = (clientIds, updateSelection = true) => ({ 16256 select, 16257 dispatch 16258 }) => { 16259 if (!clientIds || !clientIds.length) { 16260 return; 16261 } 16262 16263 // Return early if blocks don't exist. 16264 const blocks = select.getBlocksByClientId(clientIds); 16265 if (blocks.some(block => !block)) { 16266 return; 16267 } 16268 16269 // Return early if blocks don't support multiple usage. 16270 const blockNames = blocks.map(block => block.name); 16271 if (blockNames.some(blockName => !(0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockName, 'multiple', true))) { 16272 return; 16273 } 16274 const rootClientId = select.getBlockRootClientId(clientIds[0]); 16275 const clientIdsArray = actions_castArray(clientIds); 16276 const lastSelectedIndex = select.getBlockIndex(clientIdsArray[clientIdsArray.length - 1]); 16277 const clonedBlocks = blocks.map(block => (0,external_wp_blocks_namespaceObject.__experimentalCloneSanitizedBlock)(block)); 16278 dispatch.insertBlocks(clonedBlocks, lastSelectedIndex + 1, rootClientId, updateSelection); 16279 if (clonedBlocks.length > 1 && updateSelection) { 16280 dispatch.multiSelect(clonedBlocks[0].clientId, clonedBlocks[clonedBlocks.length - 1].clientId); 16281 } 16282 return clonedBlocks.map(block => block.clientId); 16283 }; 16284 16285 /** 16286 * Action that inserts a default block before a given block. 16287 * 16288 * @param {string} clientId 16289 */ 16290 const insertBeforeBlock = clientId => ({ 16291 select, 16292 dispatch 16293 }) => { 16294 if (!clientId) { 16295 return; 16296 } 16297 const rootClientId = select.getBlockRootClientId(clientId); 16298 const isLocked = select.getTemplateLock(rootClientId); 16299 if (isLocked) { 16300 return; 16301 } 16302 const blockIndex = select.getBlockIndex(clientId); 16303 const directInsertBlock = rootClientId ? select.getDirectInsertBlock(rootClientId) : null; 16304 if (!directInsertBlock) { 16305 return dispatch.insertDefaultBlock({}, rootClientId, blockIndex); 16306 } 16307 const copiedAttributes = {}; 16308 if (directInsertBlock.attributesToCopy) { 16309 const attributes = select.getBlockAttributes(clientId); 16310 directInsertBlock.attributesToCopy.forEach(key => { 16311 if (attributes[key]) { 16312 copiedAttributes[key] = attributes[key]; 16313 } 16314 }); 16315 } 16316 const block = (0,external_wp_blocks_namespaceObject.createBlock)(directInsertBlock.name, { 16317 ...directInsertBlock.attributes, 16318 ...copiedAttributes 16319 }); 16320 return dispatch.insertBlock(block, blockIndex, rootClientId); 16321 }; 16322 16323 /** 16324 * Action that inserts a default block after a given block. 16325 * 16326 * @param {string} clientId 16327 */ 16328 const insertAfterBlock = clientId => ({ 16329 select, 16330 dispatch 16331 }) => { 16332 if (!clientId) { 16333 return; 16334 } 16335 const rootClientId = select.getBlockRootClientId(clientId); 16336 const isLocked = select.getTemplateLock(rootClientId); 16337 if (isLocked) { 16338 return; 16339 } 16340 const blockIndex = select.getBlockIndex(clientId); 16341 const directInsertBlock = rootClientId ? select.getDirectInsertBlock(rootClientId) : null; 16342 if (!directInsertBlock) { 16343 return dispatch.insertDefaultBlock({}, rootClientId, blockIndex + 1); 16344 } 16345 const copiedAttributes = {}; 16346 if (directInsertBlock.attributesToCopy) { 16347 const attributes = select.getBlockAttributes(clientId); 16348 directInsertBlock.attributesToCopy.forEach(key => { 16349 if (attributes[key]) { 16350 copiedAttributes[key] = attributes[key]; 16351 } 16352 }); 16353 } 16354 const block = (0,external_wp_blocks_namespaceObject.createBlock)(directInsertBlock.name, { 16355 ...directInsertBlock.attributes, 16356 ...copiedAttributes 16357 }); 16358 return dispatch.insertBlock(block, blockIndex + 1, rootClientId); 16359 }; 16360 16361 /** 16362 * Action that toggles the highlighted block state. 16363 * 16364 * @param {string} clientId The block's clientId. 16365 * @param {boolean} isHighlighted The highlight state. 16366 */ 16367 function toggleBlockHighlight(clientId, isHighlighted) { 16368 return { 16369 type: 'TOGGLE_BLOCK_HIGHLIGHT', 16370 clientId, 16371 isHighlighted 16372 }; 16373 } 16374 16375 /** 16376 * Action that "flashes" the block with a given `clientId` by rhythmically highlighting it. 16377 * 16378 * @param {string} clientId Target block client ID. 16379 */ 16380 const flashBlock = clientId => async ({ 16381 dispatch 16382 }) => { 16383 dispatch(toggleBlockHighlight(clientId, true)); 16384 await new Promise(resolve => setTimeout(resolve, 150)); 16385 dispatch(toggleBlockHighlight(clientId, false)); 16386 }; 16387 16388 /** 16389 * Action that sets whether a block has controlled inner blocks. 16390 * 16391 * @param {string} clientId The block's clientId. 16392 * @param {boolean} hasControlledInnerBlocks True if the block's inner blocks are controlled. 16393 */ 16394 function setHasControlledInnerBlocks(clientId, hasControlledInnerBlocks) { 16395 return { 16396 type: 'SET_HAS_CONTROLLED_INNER_BLOCKS', 16397 hasControlledInnerBlocks, 16398 clientId 16399 }; 16400 } 16401 16402 /** 16403 * Action that sets whether given blocks are visible on the canvas. 16404 * 16405 * @param {Record<string,boolean>} updates For each block's clientId, its new visibility setting. 16406 */ 16407 function setBlockVisibility(updates) { 16408 return { 16409 type: 'SET_BLOCK_VISIBILITY', 16410 updates 16411 }; 16412 } 16413 16414 /** 16415 * Action that sets whether a block is being temporarily edited as blocks. 16416 * 16417 * DO-NOT-USE in production. 16418 * This action is created for internal/experimental only usage and may be 16419 * removed anytime without any warning, causing breakage on any plugin or theme invoking it. 16420 * 16421 * @param {?string} temporarilyEditingAsBlocks The block's clientId being temporarily edited as blocks. 16422 * @param {?string} focusModeToRevert The focus mode to revert after temporarily edit as blocks finishes. 16423 */ 16424 function __unstableSetTemporarilyEditingAsBlocks(temporarilyEditingAsBlocks, focusModeToRevert) { 16425 return { 16426 type: 'SET_TEMPORARILY_EDITING_AS_BLOCKS', 16427 temporarilyEditingAsBlocks, 16428 focusModeToRevert 16429 }; 16430 } 16431 16432 /** 16433 * Interface for inserter media requests. 16434 * 16435 * @typedef {Object} InserterMediaRequest 16436 * @property {number} per_page How many items to fetch per page. 16437 * @property {string} search The search term to use for filtering the results. 16438 */ 16439 16440 /** 16441 * Interface for inserter media responses. Any media resource should 16442 * map their response to this interface, in order to create the core 16443 * WordPress media blocks (image, video, audio). 16444 * 16445 * @typedef {Object} InserterMediaItem 16446 * @property {string} title The title of the media item. 16447 * @property {string} url The source url of the media item. 16448 * @property {string} [previewUrl] The preview source url of the media item to display in the media list. 16449 * @property {number} [id] The WordPress id of the media item. 16450 * @property {number|string} [sourceId] The id of the media item from external source. 16451 * @property {string} [alt] The alt text of the media item. 16452 * @property {string} [caption] The caption of the media item. 16453 */ 16454 16455 /** 16456 * Registers a new inserter media category. Once registered, the media category is 16457 * available in the inserter's media tab. 16458 * 16459 * The following interfaces are used: 16460 * 16461 * _Type Definition_ 16462 * 16463 * - _InserterMediaRequest_ `Object`: Interface for inserter media requests. 16464 * 16465 * _Properties_ 16466 * 16467 * - _per_page_ `number`: How many items to fetch per page. 16468 * - _search_ `string`: The search term to use for filtering the results. 16469 * 16470 * _Type Definition_ 16471 * 16472 * - _InserterMediaItem_ `Object`: Interface for inserter media responses. Any media resource should 16473 * map their response to this interface, in order to create the core 16474 * WordPress media blocks (image, video, audio). 16475 * 16476 * _Properties_ 16477 * 16478 * - _title_ `string`: The title of the media item. 16479 * - _url_ `string: The source url of the media item. 16480 * - _previewUrl_ `[string]`: The preview source url of the media item to display in the media list. 16481 * - _id_ `[number]`: The WordPress id of the media item. 16482 * - _sourceId_ `[number|string]`: The id of the media item from external source. 16483 * - _alt_ `[string]`: The alt text of the media item. 16484 * - _caption_ `[string]`: The caption of the media item. 16485 * 16486 * @param {InserterMediaCategory} category The inserter media category to register. 16487 * 16488 * @example 16489 * ```js 16490 * 16491 * wp.data.dispatch('core/block-editor').registerInserterMediaCategory( { 16492 * name: 'openverse', 16493 * labels: { 16494 * name: 'Openverse', 16495 * search_items: 'Search Openverse', 16496 * }, 16497 * mediaType: 'image', 16498 * async fetch( query = {} ) { 16499 * const defaultArgs = { 16500 * mature: false, 16501 * excluded_source: 'flickr,inaturalist,wikimedia', 16502 * license: 'pdm,cc0', 16503 * }; 16504 * const finalQuery = { ...query, ...defaultArgs }; 16505 * // Sometimes you might need to map the supported request params according to `InserterMediaRequest`. 16506 * // interface. In this example the `search` query param is named `q`. 16507 * const mapFromInserterMediaRequest = { 16508 * per_page: 'page_size', 16509 * search: 'q', 16510 * }; 16511 * const url = new URL( 'https://api.openverse.engineering/v1/images/' ); 16512 * Object.entries( finalQuery ).forEach( ( [ key, value ] ) => { 16513 * const queryKey = mapFromInserterMediaRequest[ key ] || key; 16514 * url.searchParams.set( queryKey, value ); 16515 * } ); 16516 * const response = await window.fetch( url, { 16517 * headers: { 16518 * 'User-Agent': 'WordPress/inserter-media-fetch', 16519 * }, 16520 * } ); 16521 * const jsonResponse = await response.json(); 16522 * const results = jsonResponse.results; 16523 * return results.map( ( result ) => ( { 16524 * ...result, 16525 * // If your response result includes an `id` prop that you want to access later, it should 16526 * // be mapped to `InserterMediaItem`'s `sourceId` prop. This can be useful if you provide 16527 * // a report URL getter. 16528 * // Additionally you should always clear the `id` value of your response results because 16529 * // it is used to identify WordPress media items. 16530 * sourceId: result.id, 16531 * id: undefined, 16532 * caption: result.caption, 16533 * previewUrl: result.thumbnail, 16534 * } ) ); 16535 * }, 16536 * getReportUrl: ( { sourceId } ) => 16537 * `https://wordpress.org/openverse/image/${ sourceId }/report/`, 16538 * isExternalResource: true, 16539 * } ); 16540 * ``` 16541 * 16542 * @typedef {Object} InserterMediaCategory Interface for inserter media category. 16543 * @property {string} name The name of the media category, that should be unique among all media categories. 16544 * @property {Object} labels Labels for the media category. 16545 * @property {string} labels.name General name of the media category. It's used in the inserter media items list. 16546 * @property {string} [labels.search_items='Search'] Label for searching items. Default is ‘Search Posts’ / ‘Search Pages’. 16547 * @property {('image'|'audio'|'video')} mediaType The media type of the media category. 16548 * @property {(InserterMediaRequest) => Promise<InserterMediaItem[]>} fetch The function to fetch media items for the category. 16549 * @property {(InserterMediaItem) => string} [getReportUrl] If the media category supports reporting media items, this function should return 16550 * the report url for the media item. It accepts the `InserterMediaItem` as an argument. 16551 * @property {boolean} [isExternalResource] If the media category is an external resource, this should be set to true. 16552 * This is used to avoid making a request to the external resource when the user 16553 */ 16554 const registerInserterMediaCategory = category => ({ 16555 select, 16556 dispatch 16557 }) => { 16558 if (!category || typeof category !== 'object') { 16559 console.error('Category should be an `InserterMediaCategory` object.'); 16560 return; 16561 } 16562 if (!category.name) { 16563 console.error('Category should have a `name` that should be unique among all media categories.'); 16564 return; 16565 } 16566 if (!category.labels?.name) { 16567 console.error('Category should have a `labels.name`.'); 16568 return; 16569 } 16570 if (!['image', 'audio', 'video'].includes(category.mediaType)) { 16571 console.error('Category should have `mediaType` property that is one of `image|audio|video`.'); 16572 return; 16573 } 16574 if (!category.fetch || typeof category.fetch !== 'function') { 16575 console.error('Category should have a `fetch` function defined with the following signature `(InserterMediaRequest) => Promise<InserterMediaItem[]>`.'); 16576 return; 16577 } 16578 const registeredInserterMediaCategories = select.getRegisteredInserterMediaCategories(); 16579 if (registeredInserterMediaCategories.some(({ 16580 name 16581 }) => name === category.name)) { 16582 console.error(`A category is already registered with the same name: "$category.name}".`); 16583 return; 16584 } 16585 if (registeredInserterMediaCategories.some(({ 16586 labels: { 16587 name 16588 } = {} 16589 }) => name === category.labels?.name)) { 16590 console.error(`A category is already registered with the same labels.name: "$category.labels.name}".`); 16591 return; 16592 } 16593 // `inserterMediaCategories` is a private block editor setting, which means it cannot 16594 // be updated through the public `updateSettings` action. We preserve this setting as 16595 // private, so extenders can only add new inserter media categories and don't have any 16596 // control over the core media categories. 16597 dispatch({ 16598 type: 'REGISTER_INSERTER_MEDIA_CATEGORY', 16599 category: { 16600 ...category, 16601 isExternalResource: true 16602 } 16603 }); 16604 }; 16605 16606 /** 16607 * @typedef {import('../components/block-editing-mode').BlockEditingMode} BlockEditingMode 16608 */ 16609 16610 /** 16611 * Sets the block editing mode for a given block. 16612 * 16613 * @see useBlockEditingMode 16614 * 16615 * @param {string} clientId The block client ID, or `''` for the root container. 16616 * @param {BlockEditingMode} mode The block editing mode. One of `'disabled'`, 16617 * `'contentOnly'`, or `'default'`. 16618 * 16619 * @return {Object} Action object. 16620 */ 16621 function setBlockEditingMode(clientId = '', mode) { 16622 return { 16623 type: 'SET_BLOCK_EDITING_MODE', 16624 clientId, 16625 mode 16626 }; 16627 } 16628 16629 /** 16630 * Clears the block editing mode for a given block. 16631 * 16632 * @see useBlockEditingMode 16633 * 16634 * @param {string} clientId The block client ID, or `''` for the root container. 16635 * 16636 * @return {Object} Action object. 16637 */ 16638 function unsetBlockEditingMode(clientId = '') { 16639 return { 16640 type: 'UNSET_BLOCK_EDITING_MODE', 16641 clientId 16642 }; 16643 } 16644 16645 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/store/index.js 16646 /** 16647 * WordPress dependencies 16648 */ 16649 16650 16651 /** 16652 * Internal dependencies 16653 */ 16654 16655 16656 16657 16658 16659 16660 16661 16662 /** 16663 * Block editor data store configuration. 16664 * 16665 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#registerStore 16666 */ 16667 const storeConfig = { 16668 reducer: reducer, 16669 selectors: selectors_namespaceObject, 16670 actions: actions_namespaceObject 16671 }; 16672 16673 /** 16674 * Store definition for the block editor namespace. 16675 * 16676 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore 16677 */ 16678 const store = (0,external_wp_data_namespaceObject.createReduxStore)(STORE_NAME, { 16679 ...storeConfig, 16680 persist: ['preferences'] 16681 }); 16682 16683 // We will be able to use the `register` function once we switch 16684 // the "preferences" persistence to use the new preferences package. 16685 const registeredStore = (0,external_wp_data_namespaceObject.registerStore)(STORE_NAME, { 16686 ...storeConfig, 16687 persist: ['preferences'] 16688 }); 16689 unlock(registeredStore).registerPrivateActions(private_actions_namespaceObject); 16690 unlock(registeredStore).registerPrivateSelectors(private_selectors_namespaceObject); 16691 16692 // TODO: Remove once we switch to the `register` function (see above). 16693 // 16694 // Until then, private functions also need to be attached to the original 16695 // `store` descriptor in order to avoid unit tests failing, which could happen 16696 // when tests create new registries in which they register stores. 16697 // 16698 // @see https://github.com/WordPress/gutenberg/pull/51145#discussion_r1239999590 16699 unlock(store).registerPrivateActions(private_actions_namespaceObject); 16700 unlock(store).registerPrivateSelectors(private_selectors_namespaceObject); 16701 16702 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/use-settings/index.js 16703 /** 16704 * WordPress dependencies 16705 */ 16706 16707 16708 16709 /** 16710 * Internal dependencies 16711 */ 16712 16713 16714 16715 16716 /** 16717 * Hook that retrieves the given settings for the block instance in use. 16718 * 16719 * It looks up the settings first in the block instance hierarchy. 16720 * If none are found, it'll look them up in the block editor settings. 16721 * 16722 * @param {string[]} paths The paths to the settings. 16723 * @return {any[]} Returns the values defined for the settings. 16724 * @example 16725 * ```js 16726 * const [ fixed, sticky ] = useSettings( 'position.fixed', 'position.sticky' ); 16727 * ``` 16728 */ 16729 function use_settings_useSettings(...paths) { 16730 const { 16731 clientId = null 16732 } = useBlockEditContext(); 16733 return (0,external_wp_data_namespaceObject.useSelect)(select => unlock(select(store)).getBlockSettings(clientId, ...paths), 16734 // eslint-disable-next-line react-hooks/exhaustive-deps 16735 [clientId, ...paths]); 16736 } 16737 16738 /** 16739 * Hook that retrieves the given setting for the block instance in use. 16740 * 16741 * It looks up the setting first in the block instance hierarchy. 16742 * If none is found, it'll look it up in the block editor settings. 16743 * 16744 * @param {string} path The path to the setting. 16745 * @return {any} Returns the value defined for the setting. 16746 * @deprecated 6.5.0 Use useSettings instead. 16747 * @example 16748 * ```js 16749 * const isEnabled = useSetting( 'typography.dropCap' ); 16750 * ``` 16751 */ 16752 function useSetting(path) { 16753 external_wp_deprecated_default()('wp.blockEditor.useSetting', { 16754 since: '6.5', 16755 alternative: 'wp.blockEditor.useSettings', 16756 note: 'The new useSettings function can retrieve multiple settings at once, with better performance.' 16757 }); 16758 const [value] = use_settings_useSettings(path); 16759 return value; 16760 } 16761 16762 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/font-sizes/fluid-utils.js 16763 /** 16764 * The fluid utilities must match the backend equivalent. 16765 * See: gutenberg_get_typography_font_size_value() in lib/block-supports/typography.php 16766 * --------------------------------------------------------------- 16767 */ 16768 16769 // Defaults. 16770 const DEFAULT_MAXIMUM_VIEWPORT_WIDTH = '1600px'; 16771 const DEFAULT_MINIMUM_VIEWPORT_WIDTH = '320px'; 16772 const DEFAULT_SCALE_FACTOR = 1; 16773 const DEFAULT_MINIMUM_FONT_SIZE_FACTOR_MIN = 0.25; 16774 const DEFAULT_MINIMUM_FONT_SIZE_FACTOR_MAX = 0.75; 16775 const DEFAULT_MINIMUM_FONT_SIZE_LIMIT = '14px'; 16776 16777 /** 16778 * Computes a fluid font-size value that uses clamp(). A minimum and maximum 16779 * font size OR a single font size can be specified. 16780 * 16781 * If a single font size is specified, it is scaled up and down using a logarithmic scale. 16782 * 16783 * @example 16784 * ```js 16785 * // Calculate fluid font-size value from a minimum and maximum value. 16786 * const fontSize = getComputedFluidTypographyValue( { 16787 * minimumFontSize: '20px', 16788 * maximumFontSize: '45px' 16789 * } ); 16790 * // Calculate fluid font-size value from a single font size. 16791 * const fontSize = getComputedFluidTypographyValue( { 16792 * fontSize: '30px', 16793 * } ); 16794 * ``` 16795 * 16796 * @param {Object} args 16797 * @param {?string} args.minimumViewportWidth Minimum viewport size from which type will have fluidity. Optional if fontSize is specified. 16798 * @param {?string} args.maximumViewportWidth Maximum size up to which type will have fluidity. Optional if fontSize is specified. 16799 * @param {string|number} [args.fontSize] Size to derive maximumFontSize and minimumFontSize from, if necessary. Optional if minimumFontSize and maximumFontSize are specified. 16800 * @param {?string} args.maximumFontSize Maximum font size for any clamp() calculation. Optional. 16801 * @param {?string} args.minimumFontSize Minimum font size for any clamp() calculation. Optional. 16802 * @param {?number} args.scaleFactor A scale factor to determine how fast a font scales within boundaries. Optional. 16803 * @param {?string} args.minimumFontSizeLimit The smallest a calculated font size may be. Optional. 16804 * 16805 * @return {string|null} A font-size value using clamp(). 16806 */ 16807 function getComputedFluidTypographyValue({ 16808 minimumFontSize, 16809 maximumFontSize, 16810 fontSize, 16811 minimumViewportWidth = DEFAULT_MINIMUM_VIEWPORT_WIDTH, 16812 maximumViewportWidth = DEFAULT_MAXIMUM_VIEWPORT_WIDTH, 16813 scaleFactor = DEFAULT_SCALE_FACTOR, 16814 minimumFontSizeLimit 16815 }) { 16816 // Validate incoming settings and set defaults. 16817 minimumFontSizeLimit = !!getTypographyValueAndUnit(minimumFontSizeLimit) ? minimumFontSizeLimit : DEFAULT_MINIMUM_FONT_SIZE_LIMIT; 16818 16819 /* 16820 * Calculates missing minimumFontSize and maximumFontSize from 16821 * defaultFontSize if provided. 16822 */ 16823 if (fontSize) { 16824 // Parses default font size. 16825 const fontSizeParsed = getTypographyValueAndUnit(fontSize); 16826 16827 // Protect against invalid units. 16828 if (!fontSizeParsed?.unit) { 16829 return null; 16830 } 16831 16832 // Parses the minimum font size limit, so we can perform checks using it. 16833 const minimumFontSizeLimitParsed = getTypographyValueAndUnit(minimumFontSizeLimit, { 16834 coerceTo: fontSizeParsed.unit 16835 }); 16836 16837 // Don't enforce minimum font size if a font size has explicitly set a min and max value. 16838 if (!!minimumFontSizeLimitParsed?.value && !minimumFontSize && !maximumFontSize) { 16839 /* 16840 * If a minimum size was not passed to this function 16841 * and the user-defined font size is lower than $minimum_font_size_limit, 16842 * do not calculate a fluid value. 16843 */ 16844 if (fontSizeParsed?.value <= minimumFontSizeLimitParsed?.value) { 16845 return null; 16846 } 16847 } 16848 16849 // If no fluid max font size is available use the incoming value. 16850 if (!maximumFontSize) { 16851 maximumFontSize = `$fontSizeParsed.value}$fontSizeParsed.unit}`; 16852 } 16853 16854 /* 16855 * If no minimumFontSize is provided, create one using 16856 * the given font size multiplied by the min font size scale factor. 16857 */ 16858 if (!minimumFontSize) { 16859 const fontSizeValueInPx = fontSizeParsed.unit === 'px' ? fontSizeParsed.value : fontSizeParsed.value * 16; 16860 16861 /* 16862 * The scale factor is a multiplier that affects how quickly the curve will move towards the minimum, 16863 * that is, how quickly the size factor reaches 0 given increasing font size values. 16864 * For a - b * log2(), lower values of b will make the curve move towards the minimum faster. 16865 * The scale factor is constrained between min and max values. 16866 */ 16867 const minimumFontSizeFactor = Math.min(Math.max(1 - 0.075 * Math.log2(fontSizeValueInPx), DEFAULT_MINIMUM_FONT_SIZE_FACTOR_MIN), DEFAULT_MINIMUM_FONT_SIZE_FACTOR_MAX); 16868 16869 // Calculates the minimum font size. 16870 const calculatedMinimumFontSize = roundToPrecision(fontSizeParsed.value * minimumFontSizeFactor, 3); 16871 16872 // Only use calculated min font size if it's > $minimum_font_size_limit value. 16873 if (!!minimumFontSizeLimitParsed?.value && calculatedMinimumFontSize < minimumFontSizeLimitParsed?.value) { 16874 minimumFontSize = `$minimumFontSizeLimitParsed.value}$minimumFontSizeLimitParsed.unit}`; 16875 } else { 16876 minimumFontSize = `$calculatedMinimumFontSize}$fontSizeParsed.unit}`; 16877 } 16878 } 16879 } 16880 16881 // Grab the minimum font size and normalize it in order to use the value for calculations. 16882 const minimumFontSizeParsed = getTypographyValueAndUnit(minimumFontSize); 16883 16884 // We get a 'preferred' unit to keep units consistent when calculating, 16885 // otherwise the result will not be accurate. 16886 const fontSizeUnit = minimumFontSizeParsed?.unit || 'rem'; 16887 16888 // Grabs the maximum font size and normalize it in order to use the value for calculations. 16889 const maximumFontSizeParsed = getTypographyValueAndUnit(maximumFontSize, { 16890 coerceTo: fontSizeUnit 16891 }); 16892 16893 // Checks for mandatory min and max sizes, and protects against unsupported units. 16894 if (!minimumFontSizeParsed || !maximumFontSizeParsed) { 16895 return null; 16896 } 16897 16898 // Uses rem for accessible fluid target font scaling. 16899 const minimumFontSizeRem = getTypographyValueAndUnit(minimumFontSize, { 16900 coerceTo: 'rem' 16901 }); 16902 16903 // Viewport widths defined for fluid typography. Normalize units 16904 const maximumViewportWidthParsed = getTypographyValueAndUnit(maximumViewportWidth, { 16905 coerceTo: fontSizeUnit 16906 }); 16907 const minimumViewportWidthParsed = getTypographyValueAndUnit(minimumViewportWidth, { 16908 coerceTo: fontSizeUnit 16909 }); 16910 16911 // Protect against unsupported units. 16912 if (!maximumViewportWidthParsed || !minimumViewportWidthParsed || !minimumFontSizeRem) { 16913 return null; 16914 } 16915 16916 // Calculates the linear factor denominator. If it's 0, we cannot calculate a fluid value. 16917 const linearDenominator = maximumViewportWidthParsed.value - minimumViewportWidthParsed.value; 16918 if (!linearDenominator) { 16919 return null; 16920 } 16921 16922 // Build CSS rule. 16923 // Borrowed from https://websemantics.uk/tools/responsive-font-calculator/. 16924 const minViewportWidthOffsetValue = roundToPrecision(minimumViewportWidthParsed.value / 100, 3); 16925 const viewportWidthOffset = roundToPrecision(minViewportWidthOffsetValue, 3) + fontSizeUnit; 16926 const linearFactor = 100 * ((maximumFontSizeParsed.value - minimumFontSizeParsed.value) / linearDenominator); 16927 const linearFactorScaled = roundToPrecision((linearFactor || 1) * scaleFactor, 3); 16928 const fluidTargetFontSize = `$minimumFontSizeRem.value}$minimumFontSizeRem.unit} + ((1vw - $viewportWidthOffset}) * $linearFactorScaled})`; 16929 return `clamp($minimumFontSize}, $fluidTargetFontSize}, $maximumFontSize})`; 16930 } 16931 16932 /** 16933 * Internal method that checks a string for a unit and value and returns an array consisting of `'value'` and `'unit'`, e.g., [ '42', 'rem' ]. 16934 * A raw font size of `value + unit` is expected. If the value is an integer, it will convert to `value + 'px'`. 16935 * 16936 * @param {string|number} rawValue Raw size value from theme.json. 16937 * @param {Object|undefined} options Calculation options. 16938 * 16939 * @return {{ unit: string, value: number }|null} An object consisting of `'value'` and `'unit'` properties. 16940 */ 16941 function getTypographyValueAndUnit(rawValue, options = {}) { 16942 if (typeof rawValue !== 'string' && typeof rawValue !== 'number') { 16943 return null; 16944 } 16945 16946 // Converts numeric values to pixel values by default. 16947 if (isFinite(rawValue)) { 16948 rawValue = `$rawValue}px`; 16949 } 16950 const { 16951 coerceTo, 16952 rootSizeValue, 16953 acceptableUnits 16954 } = { 16955 coerceTo: '', 16956 // Default browser font size. Later we could inject some JS to compute this `getComputedStyle( document.querySelector( "html" ) ).fontSize`. 16957 rootSizeValue: 16, 16958 acceptableUnits: ['rem', 'px', 'em'], 16959 ...options 16960 }; 16961 const acceptableUnitsGroup = acceptableUnits?.join('|'); 16962 const regexUnits = new RegExp(`^(\\d*\\.?\\d+)($acceptableUnitsGroup}){1,1}$`); 16963 const matches = rawValue.match(regexUnits); 16964 16965 // We need a number value and a unit. 16966 if (!matches || matches.length < 3) { 16967 return null; 16968 } 16969 let [, value, unit] = matches; 16970 let returnValue = parseFloat(value); 16971 if ('px' === coerceTo && ('em' === unit || 'rem' === unit)) { 16972 returnValue = returnValue * rootSizeValue; 16973 unit = coerceTo; 16974 } 16975 if ('px' === unit && ('em' === coerceTo || 'rem' === coerceTo)) { 16976 returnValue = returnValue / rootSizeValue; 16977 unit = coerceTo; 16978 } 16979 16980 /* 16981 * No calculation is required if swapping between em and rem yet, 16982 * since we assume a root size value. Later we might like to differentiate between 16983 * :root font size (rem) and parent element font size (em) relativity. 16984 */ 16985 if (('em' === coerceTo || 'rem' === coerceTo) && ('em' === unit || 'rem' === unit)) { 16986 unit = coerceTo; 16987 } 16988 return { 16989 value: roundToPrecision(returnValue, 3), 16990 unit 16991 }; 16992 } 16993 16994 /** 16995 * Returns a value rounded to defined precision. 16996 * Returns `undefined` if the value is not a valid finite number. 16997 * 16998 * @param {number} value Raw value. 16999 * @param {number} digits The number of digits to appear after the decimal point 17000 * 17001 * @return {number|undefined} Value rounded to standard precision. 17002 */ 17003 function roundToPrecision(value, digits = 3) { 17004 const base = Math.pow(10, digits); 17005 return Number.isFinite(value) ? parseFloat(Math.round(value * base) / base) : undefined; 17006 } 17007 17008 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/global-styles/typography-utils.js 17009 /** 17010 * The fluid utilities must match the backend equivalent. 17011 * See: gutenberg_get_typography_font_size_value() in lib/block-supports/typography.php 17012 * --------------------------------------------------------------- 17013 */ 17014 17015 /** 17016 * Internal dependencies 17017 */ 17018 17019 17020 /** 17021 * @typedef {Object} FluidPreset 17022 * @property {string|undefined} max A maximum font size value. 17023 * @property {?string|undefined} min A minimum font size value. 17024 */ 17025 17026 /** 17027 * @typedef {Object} Preset 17028 * @property {?string|?number} size A default font size. 17029 * @property {string} name A font size name, displayed in the UI. 17030 * @property {string} slug A font size slug 17031 * @property {boolean|FluidPreset|undefined} fluid Specifies the minimum and maximum font size value of a fluid font size. 17032 */ 17033 17034 /** 17035 * @typedef {Object} TypographySettings 17036 * @property {?string} minViewportWidth Minimum viewport size from which type will have fluidity. Optional if size is specified. 17037 * @property {?string} maxViewportWidth Maximum size up to which type will have fluidity. Optional if size is specified. 17038 * @property {?number} scaleFactor A scale factor to determine how fast a font scales within boundaries. Optional. 17039 * @property {?number} minFontSizeFactor How much to scale defaultFontSize by to derive minimumFontSize. Optional. 17040 * @property {?string} minFontSize The smallest a calculated font size may be. Optional. 17041 */ 17042 17043 /** 17044 * Returns a font-size value based on a given font-size preset. 17045 * Takes into account fluid typography parameters and attempts to return a css formula depending on available, valid values. 17046 * 17047 * @param {Preset} preset 17048 * @param {Object} typographyOptions 17049 * @param {boolean|TypographySettings} typographyOptions.fluid Whether fluid typography is enabled, and, optionally, fluid font size options. 17050 * 17051 * @return {string|*} A font-size value or the value of preset.size. 17052 */ 17053 function getTypographyFontSizeValue(preset, typographyOptions) { 17054 const { 17055 size: defaultSize 17056 } = preset; 17057 if (!isFluidTypographyEnabled(typographyOptions)) { 17058 return defaultSize; 17059 } 17060 /* 17061 * Checks whether a font size has explicitly bypassed fluid calculations. 17062 * Also catches falsy values and 0/'0'. 17063 * Fluid calculations cannot be performed on `0`. 17064 */ 17065 if (!defaultSize || '0' === defaultSize || false === preset?.fluid) { 17066 return defaultSize; 17067 } 17068 const fluidTypographySettings = typeof typographyOptions?.fluid === 'object' ? typographyOptions?.fluid : {}; 17069 const fluidFontSizeValue = getComputedFluidTypographyValue({ 17070 minimumFontSize: preset?.fluid?.min, 17071 maximumFontSize: preset?.fluid?.max, 17072 fontSize: defaultSize, 17073 minimumFontSizeLimit: fluidTypographySettings?.minFontSize, 17074 maximumViewportWidth: fluidTypographySettings?.maxViewportWidth, 17075 minimumViewportWidth: fluidTypographySettings?.minViewportWidth 17076 }); 17077 if (!!fluidFontSizeValue) { 17078 return fluidFontSizeValue; 17079 } 17080 return defaultSize; 17081 } 17082 function isFluidTypographyEnabled(typographySettings) { 17083 const fluidSettings = typographySettings?.fluid; 17084 return true === fluidSettings || fluidSettings && typeof fluidSettings === 'object' && Object.keys(fluidSettings).length > 0; 17085 } 17086 17087 /** 17088 * Returns fluid typography settings from theme.json setting object. 17089 * 17090 * @param {Object} settings Theme.json settings 17091 * @param {Object} settings.typography Theme.json typography settings 17092 * @param {Object} settings.layout Theme.json layout settings 17093 * @return {TypographySettings} Fluid typography settings 17094 */ 17095 function getFluidTypographyOptionsFromSettings(settings) { 17096 const typographySettings = settings?.typography; 17097 const layoutSettings = settings?.layout; 17098 const defaultMaxViewportWidth = getTypographyValueAndUnit(layoutSettings?.wideSize) ? layoutSettings?.wideSize : null; 17099 return isFluidTypographyEnabled(typographySettings) && defaultMaxViewportWidth ? { 17100 fluid: { 17101 maxViewportWidth: defaultMaxViewportWidth, 17102 ...typographySettings.fluid 17103 } 17104 } : { 17105 fluid: typographySettings?.fluid 17106 }; 17107 } 17108 17109 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/global-styles/utils.js 17110 /** 17111 * External dependencies 17112 */ 17113 17114 17115 /** 17116 * Internal dependencies 17117 */ 17118 17119 17120 17121 /* Supporting data. */ 17122 const ROOT_BLOCK_NAME = 'root'; 17123 const ROOT_BLOCK_SELECTOR = 'body'; 17124 const ROOT_BLOCK_SUPPORTS = (/* unused pure expression or super */ null && (['background', 'backgroundColor', 'color', 'linkColor', 'captionColor', 'buttonColor', 'headingColor', 'fontFamily', 'fontSize', 'fontStyle', 'fontWeight', 'lineHeight', 'textDecoration', 'textTransform', 'padding'])); 17125 const PRESET_METADATA = [{ 17126 path: ['color', 'palette'], 17127 valueKey: 'color', 17128 cssVarInfix: 'color', 17129 classes: [{ 17130 classSuffix: 'color', 17131 propertyName: 'color' 17132 }, { 17133 classSuffix: 'background-color', 17134 propertyName: 'background-color' 17135 }, { 17136 classSuffix: 'border-color', 17137 propertyName: 'border-color' 17138 }] 17139 }, { 17140 path: ['color', 'gradients'], 17141 valueKey: 'gradient', 17142 cssVarInfix: 'gradient', 17143 classes: [{ 17144 classSuffix: 'gradient-background', 17145 propertyName: 'background' 17146 }] 17147 }, { 17148 path: ['color', 'duotone'], 17149 valueKey: 'colors', 17150 cssVarInfix: 'duotone', 17151 valueFunc: ({ 17152 slug 17153 }) => `url( '#wp-duotone-$slug}' )`, 17154 classes: [] 17155 }, { 17156 path: ['shadow', 'presets'], 17157 valueKey: 'shadow', 17158 cssVarInfix: 'shadow', 17159 classes: [] 17160 }, { 17161 path: ['typography', 'fontSizes'], 17162 valueFunc: (preset, settings) => getTypographyFontSizeValue(preset, getFluidTypographyOptionsFromSettings(settings)), 17163 valueKey: 'size', 17164 cssVarInfix: 'font-size', 17165 classes: [{ 17166 classSuffix: 'font-size', 17167 propertyName: 'font-size' 17168 }] 17169 }, { 17170 path: ['typography', 'fontFamilies'], 17171 valueKey: 'fontFamily', 17172 cssVarInfix: 'font-family', 17173 classes: [{ 17174 classSuffix: 'font-family', 17175 propertyName: 'font-family' 17176 }] 17177 }, { 17178 path: ['spacing', 'spacingSizes'], 17179 valueKey: 'size', 17180 cssVarInfix: 'spacing', 17181 valueFunc: ({ 17182 size 17183 }) => size, 17184 classes: [] 17185 }]; 17186 const STYLE_PATH_TO_CSS_VAR_INFIX = { 17187 'color.background': 'color', 17188 'color.text': 'color', 17189 'filter.duotone': 'duotone', 17190 'elements.link.color.text': 'color', 17191 'elements.link.:hover.color.text': 'color', 17192 'elements.link.typography.fontFamily': 'font-family', 17193 'elements.link.typography.fontSize': 'font-size', 17194 'elements.button.color.text': 'color', 17195 'elements.button.color.background': 'color', 17196 'elements.caption.color.text': 'color', 17197 'elements.button.typography.fontFamily': 'font-family', 17198 'elements.button.typography.fontSize': 'font-size', 17199 'elements.heading.color': 'color', 17200 'elements.heading.color.background': 'color', 17201 'elements.heading.typography.fontFamily': 'font-family', 17202 'elements.heading.gradient': 'gradient', 17203 'elements.heading.color.gradient': 'gradient', 17204 'elements.h1.color': 'color', 17205 'elements.h1.color.background': 'color', 17206 'elements.h1.typography.fontFamily': 'font-family', 17207 'elements.h1.color.gradient': 'gradient', 17208 'elements.h2.color': 'color', 17209 'elements.h2.color.background': 'color', 17210 'elements.h2.typography.fontFamily': 'font-family', 17211 'elements.h2.color.gradient': 'gradient', 17212 'elements.h3.color': 'color', 17213 'elements.h3.color.background': 'color', 17214 'elements.h3.typography.fontFamily': 'font-family', 17215 'elements.h3.color.gradient': 'gradient', 17216 'elements.h4.color': 'color', 17217 'elements.h4.color.background': 'color', 17218 'elements.h4.typography.fontFamily': 'font-family', 17219 'elements.h4.color.gradient': 'gradient', 17220 'elements.h5.color': 'color', 17221 'elements.h5.color.background': 'color', 17222 'elements.h5.typography.fontFamily': 'font-family', 17223 'elements.h5.color.gradient': 'gradient', 17224 'elements.h6.color': 'color', 17225 'elements.h6.color.background': 'color', 17226 'elements.h6.typography.fontFamily': 'font-family', 17227 'elements.h6.color.gradient': 'gradient', 17228 'color.gradient': 'gradient', 17229 shadow: 'shadow', 17230 'typography.fontSize': 'font-size', 17231 'typography.fontFamily': 'font-family' 17232 }; 17233 17234 // A static list of block attributes that store global style preset slugs. 17235 const STYLE_PATH_TO_PRESET_BLOCK_ATTRIBUTE = { 17236 'color.background': 'backgroundColor', 17237 'color.text': 'textColor', 17238 'color.gradient': 'gradient', 17239 'typography.fontSize': 'fontSize', 17240 'typography.fontFamily': 'fontFamily' 17241 }; 17242 const TOOLSPANEL_DROPDOWNMENU_PROPS = { 17243 popoverProps: { 17244 placement: 'left-start', 17245 offset: 259 // Inner sidebar width (248px) - button width (24px) - border (1px) + padding (16px) + spacing (20px) 17246 } 17247 }; 17248 function findInPresetsBy(features, blockName, presetPath, presetProperty, presetValueValue) { 17249 // Block presets take priority above root level presets. 17250 const orderedPresetsByOrigin = [getValueFromObjectPath(features, ['blocks', blockName, ...presetPath]), getValueFromObjectPath(features, presetPath)]; 17251 for (const presetByOrigin of orderedPresetsByOrigin) { 17252 if (presetByOrigin) { 17253 // Preset origins ordered by priority. 17254 const origins = ['custom', 'theme', 'default']; 17255 for (const origin of origins) { 17256 const presets = presetByOrigin[origin]; 17257 if (presets) { 17258 const presetObject = presets.find(preset => preset[presetProperty] === presetValueValue); 17259 if (presetObject) { 17260 if (presetProperty === 'slug') { 17261 return presetObject; 17262 } 17263 // If there is a highest priority preset with the same slug but different value the preset we found was overwritten and should be ignored. 17264 const highestPresetObjectWithSameSlug = findInPresetsBy(features, blockName, presetPath, 'slug', presetObject.slug); 17265 if (highestPresetObjectWithSameSlug[presetProperty] === presetObject[presetProperty]) { 17266 return presetObject; 17267 } 17268 return undefined; 17269 } 17270 } 17271 } 17272 } 17273 } 17274 } 17275 function getPresetVariableFromValue(features, blockName, variableStylePath, presetPropertyValue) { 17276 if (!presetPropertyValue) { 17277 return presetPropertyValue; 17278 } 17279 const cssVarInfix = STYLE_PATH_TO_CSS_VAR_INFIX[variableStylePath]; 17280 const metadata = PRESET_METADATA.find(data => data.cssVarInfix === cssVarInfix); 17281 if (!metadata) { 17282 // The property doesn't have preset data 17283 // so the value should be returned as it is. 17284 return presetPropertyValue; 17285 } 17286 const { 17287 valueKey, 17288 path 17289 } = metadata; 17290 const presetObject = findInPresetsBy(features, blockName, path, valueKey, presetPropertyValue); 17291 if (!presetObject) { 17292 // Value wasn't found in the presets, 17293 // so it must be a custom value. 17294 return presetPropertyValue; 17295 } 17296 return `var:preset|$cssVarInfix}|$presetObject.slug}`; 17297 } 17298 function getValueFromPresetVariable(features, blockName, variable, [presetType, slug]) { 17299 const metadata = PRESET_METADATA.find(data => data.cssVarInfix === presetType); 17300 if (!metadata) { 17301 return variable; 17302 } 17303 const presetObject = findInPresetsBy(features.settings, blockName, metadata.path, 'slug', slug); 17304 if (presetObject) { 17305 const { 17306 valueKey 17307 } = metadata; 17308 const result = presetObject[valueKey]; 17309 return getValueFromVariable(features, blockName, result); 17310 } 17311 return variable; 17312 } 17313 function getValueFromCustomVariable(features, blockName, variable, path) { 17314 var _getValueFromObjectPa; 17315 const result = (_getValueFromObjectPa = getValueFromObjectPath(features.settings, ['blocks', blockName, 'custom', ...path])) !== null && _getValueFromObjectPa !== void 0 ? _getValueFromObjectPa : getValueFromObjectPath(features.settings, ['custom', ...path]); 17316 if (!result) { 17317 return variable; 17318 } 17319 // A variable may reference another variable so we need recursion until we find the value. 17320 return getValueFromVariable(features, blockName, result); 17321 } 17322 17323 /** 17324 * Attempts to fetch the value of a theme.json CSS variable. 17325 * 17326 * @param {Object} features GlobalStylesContext config, e.g., user, base or merged. Represents the theme.json tree. 17327 * @param {string} blockName The name of a block as represented in the styles property. E.g., 'root' for root-level, and 'core/${blockName}' for blocks. 17328 * @param {string|*} variable An incoming style value. A CSS var value is expected, but it could be any value. 17329 * @return {string|*|{ref}} The value of the CSS var, if found. If not found, the passed variable argument. 17330 */ 17331 function getValueFromVariable(features, blockName, variable) { 17332 if (!variable || typeof variable !== 'string') { 17333 if (variable?.ref && typeof variable?.ref === 'string') { 17334 const refPath = variable.ref.split('.'); 17335 variable = getValueFromObjectPath(features, refPath); 17336 // Presence of another ref indicates a reference to another dynamic value. 17337 // Pointing to another dynamic value is not supported. 17338 if (!variable || !!variable?.ref) { 17339 return variable; 17340 } 17341 } else { 17342 return variable; 17343 } 17344 } 17345 const USER_VALUE_PREFIX = 'var:'; 17346 const THEME_VALUE_PREFIX = 'var(--wp--'; 17347 const THEME_VALUE_SUFFIX = ')'; 17348 let parsedVar; 17349 if (variable.startsWith(USER_VALUE_PREFIX)) { 17350 parsedVar = variable.slice(USER_VALUE_PREFIX.length).split('|'); 17351 } else if (variable.startsWith(THEME_VALUE_PREFIX) && variable.endsWith(THEME_VALUE_SUFFIX)) { 17352 parsedVar = variable.slice(THEME_VALUE_PREFIX.length, -THEME_VALUE_SUFFIX.length).split('--'); 17353 } else { 17354 // We don't know how to parse the value: either is raw of uses complex CSS such as `calc(1px * var(--wp--variable) )` 17355 return variable; 17356 } 17357 const [type, ...path] = parsedVar; 17358 if (type === 'preset') { 17359 return getValueFromPresetVariable(features, blockName, variable, path); 17360 } 17361 if (type === 'custom') { 17362 return getValueFromCustomVariable(features, blockName, variable, path); 17363 } 17364 return variable; 17365 } 17366 17367 /** 17368 * Function that scopes a selector with another one. This works a bit like 17369 * SCSS nesting except the `&` operator isn't supported. 17370 * 17371 * @example 17372 * ```js 17373 * const scope = '.a, .b .c'; 17374 * const selector = '> .x, .y'; 17375 * const merged = scopeSelector( scope, selector ); 17376 * // merged is '.a > .x, .a .y, .b .c > .x, .b .c .y' 17377 * ``` 17378 * 17379 * @param {string} scope Selector to scope to. 17380 * @param {string} selector Original selector. 17381 * 17382 * @return {string} Scoped selector. 17383 */ 17384 function scopeSelector(scope, selector) { 17385 const scopes = scope.split(','); 17386 const selectors = selector.split(','); 17387 const selectorsScoped = []; 17388 scopes.forEach(outer => { 17389 selectors.forEach(inner => { 17390 selectorsScoped.push(`$outer.trim()} $inner.trim()}`); 17391 }); 17392 }); 17393 return selectorsScoped.join(', '); 17394 } 17395 17396 /** 17397 * Appends a sub-selector to an existing one. 17398 * 17399 * Given the compounded `selector` "h1, h2, h3" 17400 * and the `toAppend` selector ".some-class" the result will be 17401 * "h1.some-class, h2.some-class, h3.some-class". 17402 * 17403 * @param {string} selector Original selector. 17404 * @param {string} toAppend Selector to append. 17405 * 17406 * @return {string} The new selector. 17407 */ 17408 function appendToSelector(selector, toAppend) { 17409 if (!selector.includes(',')) { 17410 return selector + toAppend; 17411 } 17412 const selectors = selector.split(','); 17413 const newSelectors = selectors.map(sel => sel + toAppend); 17414 return newSelectors.join(','); 17415 } 17416 17417 /** 17418 * Compares global style variations according to their styles and settings properties. 17419 * 17420 * @example 17421 * ```js 17422 * const globalStyles = { styles: { typography: { fontSize: '10px' } }, settings: {} }; 17423 * const variation = { styles: { typography: { fontSize: '10000px' } }, settings: {} }; 17424 * const isEqual = areGlobalStyleConfigsEqual( globalStyles, variation ); 17425 * // false 17426 * ``` 17427 * 17428 * @param {Object} original A global styles object. 17429 * @param {Object} variation A global styles object. 17430 * 17431 * @return {boolean} Whether `original` and `variation` match. 17432 */ 17433 function areGlobalStyleConfigsEqual(original, variation) { 17434 if (typeof original !== 'object' || typeof variation !== 'object') { 17435 return original === variation; 17436 } 17437 return es6_default()(original?.styles, variation?.styles) && es6_default()(original?.settings, variation?.settings); 17438 } 17439 17440 /** 17441 * Generates the selector for a block style variation by creating the 17442 * appropriate CSS class and adding it to the ancestor portion of the block's 17443 * selector. 17444 * 17445 * For example, take the Button block which has a compound selector: 17446 * `.wp-block-button .wp-block-button__link`. With a variation named 'custom', 17447 * the class `.is-style-custom` should be added to the `.wp-block-button` 17448 * ancestor only. 17449 * 17450 * This function will take into account comma separated and complex selectors. 17451 * 17452 * @param {string} variation Name for the variation. 17453 * @param {string} blockSelector CSS selector for the block. 17454 * 17455 * @return {string} CSS selector for the block style variation. 17456 */ 17457 function getBlockStyleVariationSelector(variation, blockSelector) { 17458 const variationClass = `.is-style-$variation}`; 17459 if (!blockSelector) { 17460 return variationClass; 17461 } 17462 const ancestorRegex = /((?::\([^)]+\))?\s*)([^\s:]+)/; 17463 const addVariationClass = (_match, group1, group2) => { 17464 return group1 + group2 + variationClass; 17465 }; 17466 const result = blockSelector.split(',').map(part => part.replace(ancestorRegex, addVariationClass)); 17467 return result.join(','); 17468 } 17469 17470 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/global-styles/context.js 17471 /** 17472 * WordPress dependencies 17473 */ 17474 17475 const DEFAULT_GLOBAL_STYLES_CONTEXT = { 17476 user: {}, 17477 base: {}, 17478 merged: {}, 17479 setUserConfig: () => {} 17480 }; 17481 const GlobalStylesContext = (0,external_wp_element_namespaceObject.createContext)(DEFAULT_GLOBAL_STYLES_CONTEXT); 17482 17483 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/global-styles/hooks.js 17484 /** 17485 * External dependencies 17486 */ 17487 17488 17489 /** 17490 * WordPress dependencies 17491 */ 17492 17493 17494 17495 17496 17497 /** 17498 * Internal dependencies 17499 */ 17500 17501 17502 17503 17504 const EMPTY_CONFIG = { 17505 settings: {}, 17506 styles: {} 17507 }; 17508 const VALID_SETTINGS = ['appearanceTools', 'useRootPaddingAwareAlignments', 'background.backgroundImage', 'background.backgroundRepeat', 'background.backgroundSize', 'border.color', 'border.radius', 'border.style', 'border.width', 'shadow.presets', 'shadow.defaultPresets', 'color.background', 'color.button', 'color.caption', 'color.custom', 'color.customDuotone', 'color.customGradient', 'color.defaultDuotone', 'color.defaultGradients', 'color.defaultPalette', 'color.duotone', 'color.gradients', 'color.heading', 'color.link', 'color.palette', 'color.text', 'custom', 'dimensions.aspectRatio', 'dimensions.minHeight', 'layout.contentSize', 'layout.definitions', 'layout.wideSize', 'lightbox.enabled', 'lightbox.allowEditing', 'position.fixed', 'position.sticky', 'spacing.customSpacingSize', 'spacing.spacingSizes', 'spacing.spacingScale', 'spacing.blockGap', 'spacing.margin', 'spacing.padding', 'spacing.units', 'typography.fluid', 'typography.customFontSize', 'typography.dropCap', 'typography.fontFamilies', 'typography.fontSizes', 'typography.fontStyle', 'typography.fontWeight', 'typography.letterSpacing', 'typography.lineHeight', 'typography.textColumns', 'typography.textDecoration', 'typography.textTransform', 'typography.writingMode']; 17509 const useGlobalStylesReset = () => { 17510 const { 17511 user: config, 17512 setUserConfig 17513 } = (0,external_wp_element_namespaceObject.useContext)(GlobalStylesContext); 17514 const canReset = !!config && !es6_default()(config, EMPTY_CONFIG); 17515 return [canReset, (0,external_wp_element_namespaceObject.useCallback)(() => setUserConfig(() => EMPTY_CONFIG), [setUserConfig])]; 17516 }; 17517 function useGlobalSetting(propertyPath, blockName, source = 'all') { 17518 const { 17519 setUserConfig, 17520 ...configs 17521 } = (0,external_wp_element_namespaceObject.useContext)(GlobalStylesContext); 17522 const appendedBlockPath = blockName ? '.blocks.' + blockName : ''; 17523 const appendedPropertyPath = propertyPath ? '.' + propertyPath : ''; 17524 const contextualPath = `settings$appendedBlockPath}$appendedPropertyPath}`; 17525 const globalPath = `settings$appendedPropertyPath}`; 17526 const sourceKey = source === 'all' ? 'merged' : source; 17527 const settingValue = (0,external_wp_element_namespaceObject.useMemo)(() => { 17528 const configToUse = configs[sourceKey]; 17529 if (!configToUse) { 17530 throw 'Unsupported source'; 17531 } 17532 if (propertyPath) { 17533 var _getValueFromObjectPa; 17534 return (_getValueFromObjectPa = getValueFromObjectPath(configToUse, contextualPath)) !== null && _getValueFromObjectPa !== void 0 ? _getValueFromObjectPa : getValueFromObjectPath(configToUse, globalPath); 17535 } 17536 let result = {}; 17537 VALID_SETTINGS.forEach(setting => { 17538 var _getValueFromObjectPa2; 17539 const value = (_getValueFromObjectPa2 = getValueFromObjectPath(configToUse, `settings$appendedBlockPath}.$setting}`)) !== null && _getValueFromObjectPa2 !== void 0 ? _getValueFromObjectPa2 : getValueFromObjectPath(configToUse, `settings.$setting}`); 17540 if (value !== undefined) { 17541 result = setImmutably(result, setting.split('.'), value); 17542 } 17543 }); 17544 return result; 17545 }, [configs, sourceKey, propertyPath, contextualPath, globalPath, appendedBlockPath]); 17546 const setSetting = newValue => { 17547 setUserConfig(currentConfig => setImmutably(currentConfig, contextualPath.split('.'), newValue)); 17548 }; 17549 return [settingValue, setSetting]; 17550 } 17551 function useGlobalStyle(path, blockName, source = 'all', { 17552 shouldDecodeEncode = true 17553 } = {}) { 17554 const { 17555 merged: mergedConfig, 17556 base: baseConfig, 17557 user: userConfig, 17558 setUserConfig 17559 } = (0,external_wp_element_namespaceObject.useContext)(GlobalStylesContext); 17560 const appendedPath = path ? '.' + path : ''; 17561 const finalPath = !blockName ? `styles$appendedPath}` : `styles.blocks.$blockName}$appendedPath}`; 17562 const setStyle = newValue => { 17563 setUserConfig(currentConfig => setImmutably(currentConfig, finalPath.split('.'), shouldDecodeEncode ? getPresetVariableFromValue(mergedConfig.settings, blockName, path, newValue) : newValue)); 17564 }; 17565 let rawResult, result; 17566 switch (source) { 17567 case 'all': 17568 rawResult = getValueFromObjectPath(mergedConfig, finalPath); 17569 result = shouldDecodeEncode ? getValueFromVariable(mergedConfig, blockName, rawResult) : rawResult; 17570 break; 17571 case 'user': 17572 rawResult = getValueFromObjectPath(userConfig, finalPath); 17573 result = shouldDecodeEncode ? getValueFromVariable(mergedConfig, blockName, rawResult) : rawResult; 17574 break; 17575 case 'base': 17576 rawResult = getValueFromObjectPath(baseConfig, finalPath); 17577 result = shouldDecodeEncode ? getValueFromVariable(baseConfig, blockName, rawResult) : rawResult; 17578 break; 17579 default: 17580 throw 'Unsupported source'; 17581 } 17582 return [result, setStyle]; 17583 } 17584 17585 /** 17586 * React hook that overrides a global settings object with block and element specific settings. 17587 * 17588 * @param {Object} parentSettings Settings object. 17589 * @param {blockName?} blockName Block name. 17590 * @param {element?} element Element name. 17591 * 17592 * @return {Object} Merge of settings and supports. 17593 */ 17594 function useSettingsForBlockElement(parentSettings, blockName, element) { 17595 const { 17596 supportedStyles, 17597 supports 17598 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 17599 return { 17600 supportedStyles: unlock(select(external_wp_blocks_namespaceObject.store)).getSupportedStyles(blockName, element), 17601 supports: select(external_wp_blocks_namespaceObject.store).getBlockType(blockName)?.supports 17602 }; 17603 }, [blockName, element]); 17604 return (0,external_wp_element_namespaceObject.useMemo)(() => { 17605 const updatedSettings = { 17606 ...parentSettings 17607 }; 17608 if (!supportedStyles.includes('fontSize')) { 17609 updatedSettings.typography = { 17610 ...updatedSettings.typography, 17611 fontSizes: {}, 17612 customFontSize: false 17613 }; 17614 } 17615 if (!supportedStyles.includes('fontFamily')) { 17616 updatedSettings.typography = { 17617 ...updatedSettings.typography, 17618 fontFamilies: {} 17619 }; 17620 } 17621 updatedSettings.color = { 17622 ...updatedSettings.color, 17623 text: updatedSettings.color?.text && supportedStyles.includes('color'), 17624 background: updatedSettings.color?.background && (supportedStyles.includes('background') || supportedStyles.includes('backgroundColor')), 17625 button: updatedSettings.color?.button && supportedStyles.includes('buttonColor'), 17626 heading: updatedSettings.color?.heading && supportedStyles.includes('headingColor'), 17627 link: updatedSettings.color?.link && supportedStyles.includes('linkColor'), 17628 caption: updatedSettings.color?.caption && supportedStyles.includes('captionColor') 17629 }; 17630 17631 // Some blocks can enable background colors but disable gradients. 17632 if (!supportedStyles.includes('background')) { 17633 updatedSettings.color.gradients = []; 17634 updatedSettings.color.customGradient = false; 17635 } 17636 17637 // If filters are not supported by the block/element, disable duotone. 17638 if (!supportedStyles.includes('filter')) { 17639 updatedSettings.color.defaultDuotone = false; 17640 updatedSettings.color.customDuotone = false; 17641 } 17642 ['lineHeight', 'fontStyle', 'fontWeight', 'letterSpacing', 'textTransform', 'textDecoration', 'writingMode'].forEach(key => { 17643 if (!supportedStyles.includes(key)) { 17644 updatedSettings.typography = { 17645 ...updatedSettings.typography, 17646 [key]: false 17647 }; 17648 } 17649 }); 17650 17651 // The column-count style is named text column to reduce confusion with 17652 // the columns block and manage expectations from the support. 17653 // See: https://github.com/WordPress/gutenberg/pull/33587 17654 if (!supportedStyles.includes('columnCount')) { 17655 updatedSettings.typography = { 17656 ...updatedSettings.typography, 17657 textColumns: false 17658 }; 17659 } 17660 ['contentSize', 'wideSize'].forEach(key => { 17661 if (!supportedStyles.includes(key)) { 17662 updatedSettings.layout = { 17663 ...updatedSettings.layout, 17664 [key]: false 17665 }; 17666 } 17667 }); 17668 ['padding', 'margin', 'blockGap'].forEach(key => { 17669 if (!supportedStyles.includes(key)) { 17670 updatedSettings.spacing = { 17671 ...updatedSettings.spacing, 17672 [key]: false 17673 }; 17674 } 17675 const sides = Array.isArray(supports?.spacing?.[key]) ? supports?.spacing?.[key] : supports?.spacing?.[key]?.sides; 17676 // Check if spacing type is supported before adding sides. 17677 if (sides?.length && updatedSettings.spacing?.[key]) { 17678 updatedSettings.spacing = { 17679 ...updatedSettings.spacing, 17680 [key]: { 17681 ...updatedSettings.spacing?.[key], 17682 sides 17683 } 17684 }; 17685 } 17686 }); 17687 ['aspectRatio', 'minHeight'].forEach(key => { 17688 if (!supportedStyles.includes(key)) { 17689 updatedSettings.dimensions = { 17690 ...updatedSettings.dimensions, 17691 [key]: false 17692 }; 17693 } 17694 }); 17695 ['radius', 'color', 'style', 'width'].forEach(key => { 17696 if (!supportedStyles.includes('border' + key.charAt(0).toUpperCase() + key.slice(1))) { 17697 updatedSettings.border = { 17698 ...updatedSettings.border, 17699 [key]: false 17700 }; 17701 } 17702 }); 17703 updatedSettings.shadow = supportedStyles.includes('shadow') ? updatedSettings.shadow : false; 17704 return updatedSettings; 17705 }, [parentSettings, supportedStyles, supports]); 17706 } 17707 function useColorsPerOrigin(settings) { 17708 const customColors = settings?.color?.palette?.custom; 17709 const themeColors = settings?.color?.palette?.theme; 17710 const defaultColors = settings?.color?.palette?.default; 17711 const shouldDisplayDefaultColors = settings?.color?.defaultPalette; 17712 return (0,external_wp_element_namespaceObject.useMemo)(() => { 17713 const result = []; 17714 if (themeColors && themeColors.length) { 17715 result.push({ 17716 name: (0,external_wp_i18n_namespaceObject._x)('Theme', 'Indicates this palette comes from the theme.'), 17717 colors: themeColors 17718 }); 17719 } 17720 if (shouldDisplayDefaultColors && defaultColors && defaultColors.length) { 17721 result.push({ 17722 name: (0,external_wp_i18n_namespaceObject._x)('Default', 'Indicates this palette comes from WordPress.'), 17723 colors: defaultColors 17724 }); 17725 } 17726 if (customColors && customColors.length) { 17727 result.push({ 17728 name: (0,external_wp_i18n_namespaceObject._x)('Custom', 'Indicates this palette is created by the user.'), 17729 colors: customColors 17730 }); 17731 } 17732 return result; 17733 }, [customColors, themeColors, defaultColors, shouldDisplayDefaultColors]); 17734 } 17735 function useGradientsPerOrigin(settings) { 17736 const customGradients = settings?.color?.gradients?.custom; 17737 const themeGradients = settings?.color?.gradients?.theme; 17738 const defaultGradients = settings?.color?.gradients?.default; 17739 const shouldDisplayDefaultGradients = settings?.color?.defaultGradients; 17740 return (0,external_wp_element_namespaceObject.useMemo)(() => { 17741 const result = []; 17742 if (themeGradients && themeGradients.length) { 17743 result.push({ 17744 name: (0,external_wp_i18n_namespaceObject._x)('Theme', 'Indicates this palette comes from the theme.'), 17745 gradients: themeGradients 17746 }); 17747 } 17748 if (shouldDisplayDefaultGradients && defaultGradients && defaultGradients.length) { 17749 result.push({ 17750 name: (0,external_wp_i18n_namespaceObject._x)('Default', 'Indicates this palette comes from WordPress.'), 17751 gradients: defaultGradients 17752 }); 17753 } 17754 if (customGradients && customGradients.length) { 17755 result.push({ 17756 name: (0,external_wp_i18n_namespaceObject._x)('Custom', 'Indicates this palette is created by the user.'), 17757 gradients: customGradients 17758 }); 17759 } 17760 return result; 17761 }, [customGradients, themeGradients, defaultGradients, shouldDisplayDefaultGradients]); 17762 } 17763 17764 // EXTERNAL MODULE: ./node_modules/classnames/index.js 17765 var classnames = __webpack_require__(5755); 17766 var classnames_default = /*#__PURE__*/__webpack_require__.n(classnames); 17767 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/utils.js 17768 17769 /** 17770 * WordPress dependencies 17771 */ 17772 17773 17774 17775 17776 17777 17778 /** 17779 * Internal dependencies 17780 */ 17781 17782 17783 17784 17785 17786 17787 /** 17788 * External dependencies 17789 */ 17790 17791 17792 /** 17793 * Removed falsy values from nested object. 17794 * 17795 * @param {*} object 17796 * @return {*} Object cleaned from falsy values 17797 */ 17798 const utils_cleanEmptyObject = object => { 17799 if (object === null || typeof object !== 'object' || Array.isArray(object)) { 17800 return object; 17801 } 17802 const cleanedNestedObjects = Object.entries(object).map(([key, value]) => [key, utils_cleanEmptyObject(value)]).filter(([, value]) => value !== undefined); 17803 return !cleanedNestedObjects.length ? undefined : Object.fromEntries(cleanedNestedObjects); 17804 }; 17805 function transformStyles(activeSupports, migrationPaths, result, source, index, results) { 17806 // If there are no active supports return early. 17807 if (Object.values(activeSupports !== null && activeSupports !== void 0 ? activeSupports : {}).every(isActive => !isActive)) { 17808 return result; 17809 } 17810 // If the condition verifies we are probably in the presence of a wrapping transform 17811 // e.g: nesting paragraphs in a group or columns and in that case the styles should not be transformed. 17812 if (results.length === 1 && result.innerBlocks.length === source.length) { 17813 return result; 17814 } 17815 // For cases where we have a transform from one block to multiple blocks 17816 // or multiple blocks to one block we apply the styles of the first source block 17817 // to the result(s). 17818 let referenceBlockAttributes = source[0]?.attributes; 17819 // If we are in presence of transform between more than one block in the source 17820 // that has more than one block in the result 17821 // we apply the styles on source N to the result N, 17822 // if source N does not exists we do nothing. 17823 if (results.length > 1 && source.length > 1) { 17824 if (source[index]) { 17825 referenceBlockAttributes = source[index]?.attributes; 17826 } else { 17827 return result; 17828 } 17829 } 17830 let returnBlock = result; 17831 Object.entries(activeSupports).forEach(([support, isActive]) => { 17832 if (isActive) { 17833 migrationPaths[support].forEach(path => { 17834 const styleValue = getValueFromObjectPath(referenceBlockAttributes, path); 17835 if (styleValue) { 17836 returnBlock = { 17837 ...returnBlock, 17838 attributes: setImmutably(returnBlock.attributes, path, styleValue) 17839 }; 17840 } 17841 }); 17842 } 17843 }); 17844 return returnBlock; 17845 } 17846 17847 /** 17848 * Check whether serialization of specific block support feature or set should 17849 * be skipped. 17850 * 17851 * @param {string|Object} blockNameOrType Block name or block type object. 17852 * @param {string} featureSet Name of block support feature set. 17853 * @param {string} feature Name of the individual feature to check. 17854 * 17855 * @return {boolean} Whether serialization should occur. 17856 */ 17857 function shouldSkipSerialization(blockNameOrType, featureSet, feature) { 17858 const support = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockNameOrType, featureSet); 17859 const skipSerialization = support?.__experimentalSkipSerialization; 17860 if (Array.isArray(skipSerialization)) { 17861 return skipSerialization.includes(feature); 17862 } 17863 return skipSerialization; 17864 } 17865 function useStyleOverride({ 17866 id, 17867 css, 17868 assets, 17869 __unstableType 17870 } = {}) { 17871 const { 17872 setStyleOverride, 17873 deleteStyleOverride 17874 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store)); 17875 const fallbackId = (0,external_wp_element_namespaceObject.useId)(); 17876 (0,external_wp_element_namespaceObject.useEffect)(() => { 17877 // Unmount if there is CSS and assets are empty. 17878 if (!css && !assets) return; 17879 const _id = id || fallbackId; 17880 setStyleOverride(_id, { 17881 id, 17882 css, 17883 assets, 17884 __unstableType 17885 }); 17886 return () => { 17887 deleteStyleOverride(_id); 17888 }; 17889 }, [id, css, assets, __unstableType, fallbackId, setStyleOverride, deleteStyleOverride]); 17890 } 17891 17892 /** 17893 * Based on the block and its context, returns an object of all the block settings. 17894 * This object can be passed as a prop to all the Styles UI components 17895 * (TypographyPanel, DimensionsPanel...). 17896 * 17897 * @param {string} name Block name. 17898 * @param {*} parentLayout Parent layout. 17899 * 17900 * @return {Object} Settings object. 17901 */ 17902 function useBlockSettings(name, parentLayout) { 17903 const [backgroundImage, backgroundSize, customFontFamilies, defaultFontFamilies, themeFontFamilies, customFontSizes, defaultFontSizes, themeFontSizes, customFontSize, fontStyle, fontWeight, lineHeight, textColumns, textDecoration, writingMode, textTransform, letterSpacing, padding, margin, blockGap, spacingSizes, units, aspectRatio, minHeight, layout, borderColor, borderRadius, borderStyle, borderWidth, customColorsEnabled, customColors, customDuotone, themeColors, defaultColors, defaultPalette, defaultDuotone, userDuotonePalette, themeDuotonePalette, defaultDuotonePalette, userGradientPalette, themeGradientPalette, defaultGradientPalette, defaultGradients, areCustomGradientsEnabled, isBackgroundEnabled, isLinkEnabled, isTextEnabled, isHeadingEnabled, isButtonEnabled, shadow] = use_settings_useSettings('background.backgroundImage', 'background.backgroundSize', 'typography.fontFamilies.custom', 'typography.fontFamilies.default', 'typography.fontFamilies.theme', 'typography.fontSizes.custom', 'typography.fontSizes.default', 'typography.fontSizes.theme', 'typography.customFontSize', 'typography.fontStyle', 'typography.fontWeight', 'typography.lineHeight', 'typography.textColumns', 'typography.textDecoration', 'typography.writingMode', 'typography.textTransform', 'typography.letterSpacing', 'spacing.padding', 'spacing.margin', 'spacing.blockGap', 'spacing.spacingSizes', 'spacing.units', 'dimensions.aspectRatio', 'dimensions.minHeight', 'layout', 'border.color', 'border.radius', 'border.style', 'border.width', 'color.custom', 'color.palette.custom', 'color.customDuotone', 'color.palette.theme', 'color.palette.default', 'color.defaultPalette', 'color.defaultDuotone', 'color.duotone.custom', 'color.duotone.theme', 'color.duotone.default', 'color.gradients.custom', 'color.gradients.theme', 'color.gradients.default', 'color.defaultGradients', 'color.customGradient', 'color.background', 'color.link', 'color.text', 'color.heading', 'color.button', 'shadow'); 17904 const rawSettings = (0,external_wp_element_namespaceObject.useMemo)(() => { 17905 return { 17906 background: { 17907 backgroundImage, 17908 backgroundSize 17909 }, 17910 color: { 17911 palette: { 17912 custom: customColors, 17913 theme: themeColors, 17914 default: defaultColors 17915 }, 17916 gradients: { 17917 custom: userGradientPalette, 17918 theme: themeGradientPalette, 17919 default: defaultGradientPalette 17920 }, 17921 duotone: { 17922 custom: userDuotonePalette, 17923 theme: themeDuotonePalette, 17924 default: defaultDuotonePalette 17925 }, 17926 defaultGradients, 17927 defaultPalette, 17928 defaultDuotone, 17929 custom: customColorsEnabled, 17930 customGradient: areCustomGradientsEnabled, 17931 customDuotone, 17932 background: isBackgroundEnabled, 17933 link: isLinkEnabled, 17934 heading: isHeadingEnabled, 17935 button: isButtonEnabled, 17936 text: isTextEnabled 17937 }, 17938 typography: { 17939 fontFamilies: { 17940 custom: customFontFamilies, 17941 default: defaultFontFamilies, 17942 theme: themeFontFamilies 17943 }, 17944 fontSizes: { 17945 custom: customFontSizes, 17946 default: defaultFontSizes, 17947 theme: themeFontSizes 17948 }, 17949 customFontSize, 17950 fontStyle, 17951 fontWeight, 17952 lineHeight, 17953 textColumns, 17954 textDecoration, 17955 textTransform, 17956 letterSpacing, 17957 writingMode 17958 }, 17959 spacing: { 17960 spacingSizes: { 17961 custom: spacingSizes 17962 }, 17963 padding, 17964 margin, 17965 blockGap, 17966 units 17967 }, 17968 border: { 17969 color: borderColor, 17970 radius: borderRadius, 17971 style: borderStyle, 17972 width: borderWidth 17973 }, 17974 dimensions: { 17975 aspectRatio, 17976 minHeight 17977 }, 17978 layout, 17979 parentLayout, 17980 shadow 17981 }; 17982 }, [backgroundImage, backgroundSize, customFontFamilies, defaultFontFamilies, themeFontFamilies, customFontSizes, defaultFontSizes, themeFontSizes, customFontSize, fontStyle, fontWeight, lineHeight, textColumns, textDecoration, textTransform, letterSpacing, writingMode, padding, margin, blockGap, spacingSizes, units, aspectRatio, minHeight, layout, parentLayout, borderColor, borderRadius, borderStyle, borderWidth, customColorsEnabled, customColors, customDuotone, themeColors, defaultColors, defaultPalette, defaultDuotone, userDuotonePalette, themeDuotonePalette, defaultDuotonePalette, userGradientPalette, themeGradientPalette, defaultGradientPalette, defaultGradients, areCustomGradientsEnabled, isBackgroundEnabled, isLinkEnabled, isTextEnabled, isHeadingEnabled, isButtonEnabled, shadow]); 17983 return useSettingsForBlockElement(rawSettings, name); 17984 } 17985 function createBlockEditFilter(features) { 17986 // We don't want block controls to re-render when typing inside a block. 17987 // `memo` will prevent re-renders unless props change, so only pass the 17988 // needed props and not the whole attributes object. 17989 features = features.map(settings => { 17990 return { 17991 ...settings, 17992 Edit: (0,external_wp_element_namespaceObject.memo)(settings.edit) 17993 }; 17994 }); 17995 const withBlockEditHooks = (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(OriginalBlockEdit => props => { 17996 const context = useBlockEditContext(); 17997 // CAUTION: code added before this line will be executed for all 17998 // blocks, not just those that support the feature! Code added 17999 // above this line should be carefully evaluated for its impact on 18000 // performance. 18001 return [...features.map((feature, i) => { 18002 const { 18003 Edit, 18004 hasSupport, 18005 attributeKeys = [], 18006 shareWithChildBlocks 18007 } = feature; 18008 const shouldDisplayControls = context[mayDisplayControlsKey] || context[mayDisplayParentControlsKey] && shareWithChildBlocks; 18009 if (!shouldDisplayControls || !hasSupport(props.name)) { 18010 return null; 18011 } 18012 const neededProps = {}; 18013 for (const key of attributeKeys) { 18014 if (props.attributes[key]) { 18015 neededProps[key] = props.attributes[key]; 18016 } 18017 } 18018 return (0,external_React_.createElement)(Edit 18019 // We can use the index because the array length 18020 // is fixed per page load right now. 18021 , { 18022 key: i, 18023 name: props.name, 18024 isSelected: props.isSelected, 18025 clientId: props.clientId, 18026 setAttributes: props.setAttributes, 18027 __unstableParentLayout: props.__unstableParentLayout 18028 // This component is pure, so only pass needed 18029 // props!!! 18030 , 18031 ...neededProps 18032 }); 18033 }), (0,external_React_.createElement)(OriginalBlockEdit, { 18034 key: "edit", 18035 ...props 18036 })]; 18037 }, 'withBlockEditHooks'); 18038 (0,external_wp_hooks_namespaceObject.addFilter)('editor.BlockEdit', 'core/editor/hooks', withBlockEditHooks); 18039 } 18040 function BlockProps({ 18041 index, 18042 useBlockProps, 18043 setAllWrapperProps, 18044 ...props 18045 }) { 18046 const wrapperProps = useBlockProps(props); 18047 const setWrapperProps = next => setAllWrapperProps(prev => { 18048 const nextAll = [...prev]; 18049 nextAll[index] = next; 18050 return nextAll; 18051 }); 18052 // Setting state after every render is fine because this component is 18053 // pure and will only re-render when needed props change. 18054 (0,external_wp_element_namespaceObject.useEffect)(() => { 18055 // We could shallow compare the props, but since this component only 18056 // changes when needed attributes change, the benefit is probably small. 18057 setWrapperProps(wrapperProps); 18058 return () => { 18059 setWrapperProps(undefined); 18060 }; 18061 }); 18062 return null; 18063 } 18064 const BlockPropsPure = (0,external_wp_element_namespaceObject.memo)(BlockProps); 18065 function createBlockListBlockFilter(features) { 18066 const withBlockListBlockHooks = (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(BlockListBlock => props => { 18067 const [allWrapperProps, setAllWrapperProps] = (0,external_wp_element_namespaceObject.useState)(Array(features.length).fill(undefined)); 18068 return [...features.map((feature, i) => { 18069 const { 18070 hasSupport, 18071 attributeKeys = [], 18072 useBlockProps 18073 } = feature; 18074 const neededProps = {}; 18075 for (const key of attributeKeys) { 18076 if (props.attributes[key]) { 18077 neededProps[key] = props.attributes[key]; 18078 } 18079 } 18080 if ( 18081 // Skip rendering if none of the needed attributes are 18082 // set. 18083 !Object.keys(neededProps).length || !hasSupport(props.name)) { 18084 return null; 18085 } 18086 return (0,external_React_.createElement)(BlockPropsPure 18087 // We can use the index because the array length 18088 // is fixed per page load right now. 18089 , { 18090 key: i, 18091 index: i, 18092 useBlockProps: useBlockProps 18093 // This component is pure, so we must pass a stable 18094 // function reference. 18095 , 18096 setAllWrapperProps: setAllWrapperProps, 18097 name: props.name 18098 // This component is pure, so only pass needed 18099 // props!!! 18100 , 18101 ...neededProps 18102 }); 18103 }), (0,external_React_.createElement)(BlockListBlock, { 18104 key: "edit", 18105 ...props, 18106 wrapperProps: allWrapperProps.filter(Boolean).reduce((acc, wrapperProps) => { 18107 return { 18108 ...acc, 18109 ...wrapperProps, 18110 className: classnames_default()(acc.className, wrapperProps.className), 18111 style: { 18112 ...acc.style, 18113 ...wrapperProps.style 18114 } 18115 }; 18116 }, props.wrapperProps || {}) 18117 })]; 18118 }, 'withBlockListBlockHooks'); 18119 (0,external_wp_hooks_namespaceObject.addFilter)('editor.BlockListBlock', 'core/editor/hooks', withBlockListBlockHooks); 18120 } 18121 function createBlockSaveFilter(features) { 18122 function extraPropsFromHooks(props, name, attributes) { 18123 return features.reduce((accu, feature) => { 18124 const { 18125 hasSupport, 18126 attributeKeys = [], 18127 addSaveProps 18128 } = feature; 18129 const neededAttributes = {}; 18130 for (const key of attributeKeys) { 18131 if (attributes[key]) { 18132 neededAttributes[key] = attributes[key]; 18133 } 18134 } 18135 if ( 18136 // Skip rendering if none of the needed attributes are 18137 // set. 18138 !Object.keys(neededAttributes).length || !hasSupport(name)) { 18139 return accu; 18140 } 18141 return addSaveProps(accu, name, neededAttributes); 18142 }, props); 18143 } 18144 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.getSaveContent.extraProps', 'core/editor/hooks', extraPropsFromHooks, 0); 18145 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.getSaveContent.extraProps', 'core/editor/hooks', props => { 18146 // Previously we had a filter deleting the className if it was an empty 18147 // string. That filter is no longer running, so now we need to delete it 18148 // here. 18149 if (props.hasOwnProperty('className') && !props.className) { 18150 delete props.className; 18151 } 18152 return props; 18153 }); 18154 } 18155 18156 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/compat.js 18157 /** 18158 * WordPress dependencies 18159 */ 18160 18161 18162 function migrateLightBlockWrapper(settings) { 18163 const { 18164 apiVersion = 1 18165 } = settings; 18166 if (apiVersion < 2 && (0,external_wp_blocks_namespaceObject.hasBlockSupport)(settings, 'lightBlockWrapper', false)) { 18167 settings.apiVersion = 2; 18168 } 18169 return settings; 18170 } 18171 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/compat/migrateLightBlockWrapper', migrateLightBlockWrapper); 18172 18173 ;// CONCATENATED MODULE: external ["wp","components"] 18174 const external_wp_components_namespaceObject = window["wp"]["components"]; 18175 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-controls/groups.js 18176 /** 18177 * WordPress dependencies 18178 */ 18179 18180 const BlockControlsDefault = (0,external_wp_components_namespaceObject.createSlotFill)('BlockControls'); 18181 const BlockControlsBlock = (0,external_wp_components_namespaceObject.createSlotFill)('BlockControlsBlock'); 18182 const BlockControlsInline = (0,external_wp_components_namespaceObject.createSlotFill)('BlockFormatControls'); 18183 const BlockControlsOther = (0,external_wp_components_namespaceObject.createSlotFill)('BlockControlsOther'); 18184 const BlockControlsParent = (0,external_wp_components_namespaceObject.createSlotFill)('BlockControlsParent'); 18185 const groups = { 18186 default: BlockControlsDefault, 18187 block: BlockControlsBlock, 18188 inline: BlockControlsInline, 18189 other: BlockControlsOther, 18190 parent: BlockControlsParent 18191 }; 18192 /* harmony default export */ const block_controls_groups = (groups); 18193 18194 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-controls/hook.js 18195 /** 18196 * WordPress dependencies 18197 */ 18198 18199 /** 18200 * Internal dependencies 18201 */ 18202 18203 18204 function useBlockControlsFill(group, shareWithChildBlocks) { 18205 const context = useBlockEditContext(); 18206 if (context[mayDisplayControlsKey]) { 18207 return block_controls_groups[group]?.Fill; 18208 } 18209 if (context[mayDisplayParentControlsKey] && shareWithChildBlocks) { 18210 return block_controls_groups.parent.Fill; 18211 } 18212 return null; 18213 } 18214 18215 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-controls/fill.js 18216 18217 /** 18218 * WordPress dependencies 18219 */ 18220 18221 18222 /** 18223 * Internal dependencies 18224 */ 18225 18226 function BlockControlsFill({ 18227 group = 'default', 18228 controls, 18229 children, 18230 __experimentalShareWithChildBlocks = false 18231 }) { 18232 const Fill = useBlockControlsFill(group, __experimentalShareWithChildBlocks); 18233 if (!Fill) { 18234 return null; 18235 } 18236 const innerMarkup = (0,external_React_.createElement)(external_React_.Fragment, null, group === 'default' && (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarGroup, { 18237 controls: controls 18238 }), children); 18239 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalStyleProvider, { 18240 document: document 18241 }, (0,external_React_.createElement)(Fill, null, fillProps => { 18242 // `fillProps.forwardedContext` is an array of context provider entries, provided by slot, 18243 // that should wrap the fill markup. 18244 const { 18245 forwardedContext = [] 18246 } = fillProps; 18247 return forwardedContext.reduce((inner, [Provider, props]) => (0,external_React_.createElement)(Provider, { 18248 ...props 18249 }, inner), innerMarkup); 18250 })); 18251 } 18252 18253 ;// CONCATENATED MODULE: external ["wp","warning"] 18254 const external_wp_warning_namespaceObject = window["wp"]["warning"]; 18255 var external_wp_warning_default = /*#__PURE__*/__webpack_require__.n(external_wp_warning_namespaceObject); 18256 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-controls/slot.js 18257 18258 /** 18259 * WordPress dependencies 18260 */ 18261 18262 18263 18264 18265 /** 18266 * Internal dependencies 18267 */ 18268 18269 18270 const { 18271 ComponentsContext 18272 } = unlock(external_wp_components_namespaceObject.privateApis); 18273 function BlockControlsSlot({ 18274 group = 'default', 18275 ...props 18276 }) { 18277 const toolbarState = (0,external_wp_element_namespaceObject.useContext)(external_wp_components_namespaceObject.__experimentalToolbarContext); 18278 const contextState = (0,external_wp_element_namespaceObject.useContext)(ComponentsContext); 18279 const fillProps = (0,external_wp_element_namespaceObject.useMemo)(() => ({ 18280 forwardedContext: [[external_wp_components_namespaceObject.__experimentalToolbarContext.Provider, { 18281 value: toolbarState 18282 }], [ComponentsContext.Provider, { 18283 value: contextState 18284 }]] 18285 }), [toolbarState, contextState]); 18286 const Slot = block_controls_groups[group]?.Slot; 18287 const fills = (0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(Slot?.__unstableName); 18288 if (!Slot) { 18289 true ? external_wp_warning_default()(`Unknown BlockControls group "$group}" provided.`) : 0; 18290 return null; 18291 } 18292 if (!fills?.length) { 18293 return null; 18294 } 18295 const slot = (0,external_React_.createElement)(Slot, { 18296 ...props, 18297 bubblesVirtually: true, 18298 fillProps: fillProps 18299 }); 18300 if (group === 'default') { 18301 return slot; 18302 } 18303 return (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarGroup, null, slot); 18304 } 18305 18306 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-controls/index.js 18307 18308 /** 18309 * Internal dependencies 18310 */ 18311 18312 18313 const BlockControls = BlockControlsFill; 18314 BlockControls.Slot = BlockControlsSlot; 18315 18316 // This is just here for backward compatibility. 18317 const BlockFormatControls = props => { 18318 return (0,external_React_.createElement)(BlockControlsFill, { 18319 group: "inline", 18320 ...props 18321 }); 18322 }; 18323 BlockFormatControls.Slot = props => { 18324 return (0,external_React_.createElement)(BlockControlsSlot, { 18325 group: "inline", 18326 ...props 18327 }); 18328 }; 18329 /* harmony default export */ const block_controls = (BlockControls); 18330 18331 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/justify-left.js 18332 18333 /** 18334 * WordPress dependencies 18335 */ 18336 18337 const justifyLeft = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 18338 xmlns: "http://www.w3.org/2000/svg", 18339 viewBox: "0 0 24 24" 18340 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 18341 d: "M9 9v6h11V9H9zM4 20h1.5V4H4v16z" 18342 })); 18343 /* harmony default export */ const justify_left = (justifyLeft); 18344 18345 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/justify-center.js 18346 18347 /** 18348 * WordPress dependencies 18349 */ 18350 18351 const justifyCenter = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 18352 xmlns: "http://www.w3.org/2000/svg", 18353 viewBox: "0 0 24 24" 18354 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 18355 d: "M12.5 15v5H11v-5H4V9h7V4h1.5v5h7v6h-7Z" 18356 })); 18357 /* harmony default export */ const justify_center = (justifyCenter); 18358 18359 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/justify-right.js 18360 18361 /** 18362 * WordPress dependencies 18363 */ 18364 18365 const justifyRight = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 18366 xmlns: "http://www.w3.org/2000/svg", 18367 viewBox: "0 0 24 24" 18368 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 18369 d: "M4 15h11V9H4v6zM18.5 4v16H20V4h-1.5z" 18370 })); 18371 /* harmony default export */ const justify_right = (justifyRight); 18372 18373 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/justify-space-between.js 18374 18375 /** 18376 * WordPress dependencies 18377 */ 18378 18379 const justifySpaceBetween = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 18380 xmlns: "http://www.w3.org/2000/svg", 18381 viewBox: "0 0 24 24" 18382 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 18383 d: "M9 15h6V9H9v6zm-5 5h1.5V4H4v16zM18.5 4v16H20V4h-1.5z" 18384 })); 18385 /* harmony default export */ const justify_space_between = (justifySpaceBetween); 18386 18387 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/justify-stretch.js 18388 18389 /** 18390 * WordPress dependencies 18391 */ 18392 18393 const justifyStretch = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 18394 xmlns: "http://www.w3.org/2000/svg", 18395 viewBox: "0 0 24 24" 18396 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 18397 d: "M4 4H5.5V20H4V4ZM7 10L17 10V14L7 14V10ZM20 4H18.5V20H20V4Z" 18398 })); 18399 /* harmony default export */ const justify_stretch = (justifyStretch); 18400 18401 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/arrow-right.js 18402 18403 /** 18404 * WordPress dependencies 18405 */ 18406 18407 const arrowRight = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 18408 xmlns: "http://www.w3.org/2000/svg", 18409 viewBox: "0 0 24 24" 18410 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 18411 d: "m14.5 6.5-1 1 3.7 3.7H4v1.6h13.2l-3.7 3.7 1 1 5.6-5.5z" 18412 })); 18413 /* harmony default export */ const arrow_right = (arrowRight); 18414 18415 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/arrow-down.js 18416 18417 /** 18418 * WordPress dependencies 18419 */ 18420 18421 const arrowDown = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 18422 xmlns: "http://www.w3.org/2000/svg", 18423 viewBox: "0 0 24 24" 18424 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 18425 d: "m16.5 13.5-3.7 3.7V4h-1.5v13.2l-3.8-3.7-1 1 5.5 5.6 5.5-5.6z" 18426 })); 18427 /* harmony default export */ const arrow_down = (arrowDown); 18428 18429 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/layouts/definitions.js 18430 // Layout definitions keyed by layout type. 18431 // Provides a common definition of slugs, classnames, base styles, and spacing styles for each layout type. 18432 // If making changes or additions to layout definitions, be sure to update the corresponding PHP definitions in 18433 // `block-supports/layout.php` so that the server-side and client-side definitions match. 18434 const LAYOUT_DEFINITIONS = { 18435 default: { 18436 name: 'default', 18437 slug: 'flow', 18438 className: 'is-layout-flow', 18439 baseStyles: [{ 18440 selector: ' > .alignleft', 18441 rules: { 18442 float: 'left', 18443 'margin-inline-start': '0', 18444 'margin-inline-end': '2em' 18445 } 18446 }, { 18447 selector: ' > .alignright', 18448 rules: { 18449 float: 'right', 18450 'margin-inline-start': '2em', 18451 'margin-inline-end': '0' 18452 } 18453 }, { 18454 selector: ' > .aligncenter', 18455 rules: { 18456 'margin-left': 'auto !important', 18457 'margin-right': 'auto !important' 18458 } 18459 }], 18460 spacingStyles: [{ 18461 selector: ' > :first-child:first-child', 18462 rules: { 18463 'margin-block-start': '0' 18464 } 18465 }, { 18466 selector: ' > :last-child:last-child', 18467 rules: { 18468 'margin-block-end': '0' 18469 } 18470 }, { 18471 selector: ' > *', 18472 rules: { 18473 'margin-block-start': null, 18474 'margin-block-end': '0' 18475 } 18476 }] 18477 }, 18478 constrained: { 18479 name: 'constrained', 18480 slug: 'constrained', 18481 className: 'is-layout-constrained', 18482 baseStyles: [{ 18483 selector: ' > .alignleft', 18484 rules: { 18485 float: 'left', 18486 'margin-inline-start': '0', 18487 'margin-inline-end': '2em' 18488 } 18489 }, { 18490 selector: ' > .alignright', 18491 rules: { 18492 float: 'right', 18493 'margin-inline-start': '2em', 18494 'margin-inline-end': '0' 18495 } 18496 }, { 18497 selector: ' > .aligncenter', 18498 rules: { 18499 'margin-left': 'auto !important', 18500 'margin-right': 'auto !important' 18501 } 18502 }, { 18503 selector: ' > :where(:not(.alignleft):not(.alignright):not(.alignfull))', 18504 rules: { 18505 'max-width': 'var(--wp--style--global--content-size)', 18506 'margin-left': 'auto !important', 18507 'margin-right': 'auto !important' 18508 } 18509 }, { 18510 selector: ' > .alignwide', 18511 rules: { 18512 'max-width': 'var(--wp--style--global--wide-size)' 18513 } 18514 }], 18515 spacingStyles: [{ 18516 selector: ' > :first-child:first-child', 18517 rules: { 18518 'margin-block-start': '0' 18519 } 18520 }, { 18521 selector: ' > :last-child:last-child', 18522 rules: { 18523 'margin-block-end': '0' 18524 } 18525 }, { 18526 selector: ' > *', 18527 rules: { 18528 'margin-block-start': null, 18529 'margin-block-end': '0' 18530 } 18531 }] 18532 }, 18533 flex: { 18534 name: 'flex', 18535 slug: 'flex', 18536 className: 'is-layout-flex', 18537 displayMode: 'flex', 18538 baseStyles: [{ 18539 selector: '', 18540 rules: { 18541 'flex-wrap': 'wrap', 18542 'align-items': 'center' 18543 } 18544 }, { 18545 selector: ' > *', 18546 rules: { 18547 margin: '0' 18548 } 18549 }], 18550 spacingStyles: [{ 18551 selector: '', 18552 rules: { 18553 gap: null 18554 } 18555 }] 18556 }, 18557 grid: { 18558 name: 'grid', 18559 slug: 'grid', 18560 className: 'is-layout-grid', 18561 displayMode: 'grid', 18562 baseStyles: [{ 18563 selector: ' > *', 18564 rules: { 18565 margin: '0' 18566 } 18567 }], 18568 spacingStyles: [{ 18569 selector: '', 18570 rules: { 18571 gap: null 18572 } 18573 }] 18574 } 18575 }; 18576 18577 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/layouts/utils.js 18578 /** 18579 * WordPress dependencies 18580 */ 18581 18582 18583 /** 18584 * Internal dependencies 18585 */ 18586 18587 18588 /** 18589 * Utility to generate the proper CSS selector for layout styles. 18590 * 18591 * @param {string} selectors CSS selector, also supports multiple comma-separated selectors. 18592 * @param {string} append The string to append. 18593 * 18594 * @return {string} - CSS selector. 18595 */ 18596 function appendSelectors(selectors, append = '') { 18597 // Ideally we shouldn't need the `.editor-styles-wrapper` increased specificity here 18598 // The problem though is that we have a `.editor-styles-wrapper p { margin: reset; }` style 18599 // it's used to reset the default margin added by wp-admin to paragraphs 18600 // so we need this to be higher speficity otherwise, it won't be applied to paragraphs inside containers 18601 // When the post editor is fully iframed, this extra classname could be removed. 18602 18603 return selectors.split(',').map(subselector => `.editor-styles-wrapper $subselector}$append ? ` $append}` : ''}`).join(','); 18604 } 18605 18606 /** 18607 * Get generated blockGap CSS rules based on layout definitions provided in theme.json 18608 * Falsy values in the layout definition's spacingStyles rules will be swapped out 18609 * with the provided `blockGapValue`. 18610 * 18611 * @param {string} selector The CSS selector to target for the generated rules. 18612 * @param {Object} layoutDefinitions Layout definitions object. 18613 * @param {string} layoutType The layout type (e.g. `default` or `flex`). 18614 * @param {string} blockGapValue The current blockGap value to be applied. 18615 * @return {string} The generated CSS rules. 18616 */ 18617 function getBlockGapCSS(selector, layoutDefinitions = LAYOUT_DEFINITIONS, layoutType, blockGapValue) { 18618 let output = ''; 18619 if (layoutDefinitions?.[layoutType]?.spacingStyles?.length && blockGapValue) { 18620 layoutDefinitions[layoutType].spacingStyles.forEach(gapStyle => { 18621 output += `$appendSelectors(selector, gapStyle.selector.trim())} { `; 18622 output += Object.entries(gapStyle.rules).map(([cssProperty, value]) => `$cssProperty}: $value ? value : blockGapValue}`).join('; '); 18623 output += '; }'; 18624 }); 18625 } 18626 return output; 18627 } 18628 18629 /** 18630 * Helper method to assign contextual info to clarify 18631 * alignment settings. 18632 * 18633 * Besides checking if `contentSize` and `wideSize` have a 18634 * value, we now show this information only if their values 18635 * are not a `css var`. This needs to change when parsing 18636 * css variables land. 18637 * 18638 * @see https://github.com/WordPress/gutenberg/pull/34710#issuecomment-918000752 18639 * 18640 * @param {Object} layout The layout object. 18641 * @return {Object} An object with contextual info per alignment. 18642 */ 18643 function getAlignmentsInfo(layout) { 18644 const { 18645 contentSize, 18646 wideSize, 18647 type = 'default' 18648 } = layout; 18649 const alignmentInfo = {}; 18650 const sizeRegex = /^(?!0)\d+(px|em|rem|vw|vh|%|svw|lvw|dvw|svh|lvh|dvh|vi|svi|lvi|dvi|vb|svb|lvb|dvb|vmin|svmin|lvmin|dvmin|vmax|svmax|lvmax|dvmax)?$/i; 18651 if (sizeRegex.test(contentSize) && type === 'constrained') { 18652 // translators: %s: container size (i.e. 600px etc) 18653 alignmentInfo.none = (0,external_wp_i18n_namespaceObject.sprintf)((0,external_wp_i18n_namespaceObject.__)('Max %s wide'), contentSize); 18654 } 18655 if (sizeRegex.test(wideSize)) { 18656 // translators: %s: container size (i.e. 600px etc) 18657 alignmentInfo.wide = (0,external_wp_i18n_namespaceObject.sprintf)((0,external_wp_i18n_namespaceObject.__)('Max %s wide'), wideSize); 18658 } 18659 return alignmentInfo; 18660 } 18661 18662 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/sides-all.js 18663 18664 /** 18665 * WordPress dependencies 18666 */ 18667 18668 const sidesAll = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 18669 xmlns: "http://www.w3.org/2000/svg", 18670 viewBox: "0 0 24 24" 18671 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 18672 d: "m7.5 6h9v-1.5h-9zm0 13.5h9v-1.5h-9zm-3-3h1.5v-9h-1.5zm13.5-9v9h1.5v-9z" 18673 })); 18674 /* harmony default export */ const sides_all = (sidesAll); 18675 18676 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/sides-horizontal.js 18677 18678 /** 18679 * WordPress dependencies 18680 */ 18681 18682 const sidesHorizontal = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 18683 xmlns: "http://www.w3.org/2000/svg", 18684 viewBox: "0 0 24 24" 18685 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 18686 d: "m7.5 6h9v-1.5h-9zm0 13.5h9v-1.5h-9zm-3-3h1.5v-9h-1.5zm13.5-9v9h1.5v-9z", 18687 style: { 18688 opacity: 0.25 18689 } 18690 }), (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 18691 d: "m4.5 7.5v9h1.5v-9z" 18692 }), (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 18693 d: "m18 7.5v9h1.5v-9z" 18694 })); 18695 /* harmony default export */ const sides_horizontal = (sidesHorizontal); 18696 18697 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/sides-vertical.js 18698 18699 /** 18700 * WordPress dependencies 18701 */ 18702 18703 const sidesVertical = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 18704 xmlns: "http://www.w3.org/2000/svg", 18705 viewBox: "0 0 24 24" 18706 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 18707 d: "m7.5 6h9v-1.5h-9zm0 13.5h9v-1.5h-9zm-3-3h1.5v-9h-1.5zm13.5-9v9h1.5v-9z", 18708 style: { 18709 opacity: 0.25 18710 } 18711 }), (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 18712 d: "m7.5 6h9v-1.5h-9z" 18713 }), (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 18714 d: "m7.5 19.5h9v-1.5h-9z" 18715 })); 18716 /* harmony default export */ const sides_vertical = (sidesVertical); 18717 18718 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/sides-top.js 18719 18720 /** 18721 * WordPress dependencies 18722 */ 18723 18724 const sidesTop = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 18725 xmlns: "http://www.w3.org/2000/svg", 18726 viewBox: "0 0 24 24" 18727 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 18728 d: "m7.5 6h9v-1.5h-9zm0 13.5h9v-1.5h-9zm-3-3h1.5v-9h-1.5zm13.5-9v9h1.5v-9z", 18729 style: { 18730 opacity: 0.25 18731 } 18732 }), (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 18733 d: "m16.5 6h-9v-1.5h9z" 18734 })); 18735 /* harmony default export */ const sides_top = (sidesTop); 18736 18737 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/sides-right.js 18738 18739 /** 18740 * WordPress dependencies 18741 */ 18742 18743 const sidesRight = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 18744 xmlns: "http://www.w3.org/2000/svg", 18745 viewBox: "0 0 24 24" 18746 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 18747 d: "m7.5 6h9v-1.5h-9zm0 13.5h9v-1.5h-9zm-3-3h1.5v-9h-1.5zm13.5-9v9h1.5v-9z", 18748 style: { 18749 opacity: 0.25 18750 } 18751 }), (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 18752 d: "m18 16.5v-9h1.5v9z" 18753 })); 18754 /* harmony default export */ const sides_right = (sidesRight); 18755 18756 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/sides-bottom.js 18757 18758 /** 18759 * WordPress dependencies 18760 */ 18761 18762 const sidesBottom = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 18763 xmlns: "http://www.w3.org/2000/svg", 18764 viewBox: "0 0 24 24" 18765 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 18766 d: "m7.5 6h9v-1.5h-9zm0 13.5h9v-1.5h-9zm-3-3h1.5v-9h-1.5zm13.5-9v9h1.5v-9z", 18767 style: { 18768 opacity: 0.25 18769 } 18770 }), (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 18771 d: "m16.5 19.5h-9v-1.5h9z", 18772 style: { 18773 fill: '#1e1e1e' 18774 } 18775 })); 18776 /* harmony default export */ const sides_bottom = (sidesBottom); 18777 18778 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/sides-left.js 18779 18780 /** 18781 * WordPress dependencies 18782 */ 18783 18784 const sidesLeft = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 18785 xmlns: "http://www.w3.org/2000/svg", 18786 viewBox: "0 0 24 24" 18787 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 18788 d: "m7.5 6h9v-1.5h-9zm0 13.5h9v-1.5h-9zm-3-3h1.5v-9h-1.5zm13.5-9v9h1.5v-9z", 18789 style: { 18790 opacity: 0.25 18791 } 18792 }), (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 18793 d: "m4.5 16.5v-9h1.5v9z" 18794 })); 18795 /* harmony default export */ const sides_left = (sidesLeft); 18796 18797 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/spacing-sizes-control/utils.js 18798 /** 18799 * WordPress dependencies 18800 */ 18801 18802 18803 const ALL_SIDES = ['top', 'right', 'bottom', 'left']; 18804 const DEFAULT_VALUES = { 18805 top: undefined, 18806 right: undefined, 18807 bottom: undefined, 18808 left: undefined 18809 }; 18810 const ICONS = { 18811 custom: sides_all, 18812 axial: sides_all, 18813 horizontal: sides_horizontal, 18814 vertical: sides_vertical, 18815 top: sides_top, 18816 right: sides_right, 18817 bottom: sides_bottom, 18818 left: sides_left 18819 }; 18820 const LABELS = { 18821 default: (0,external_wp_i18n_namespaceObject.__)('Spacing control'), 18822 top: (0,external_wp_i18n_namespaceObject.__)('Top'), 18823 bottom: (0,external_wp_i18n_namespaceObject.__)('Bottom'), 18824 left: (0,external_wp_i18n_namespaceObject.__)('Left'), 18825 right: (0,external_wp_i18n_namespaceObject.__)('Right'), 18826 mixed: (0,external_wp_i18n_namespaceObject.__)('Mixed'), 18827 vertical: (0,external_wp_i18n_namespaceObject.__)('Vertical'), 18828 horizontal: (0,external_wp_i18n_namespaceObject.__)('Horizontal'), 18829 axial: (0,external_wp_i18n_namespaceObject.__)('Horizontal & vertical'), 18830 custom: (0,external_wp_i18n_namespaceObject.__)('Custom') 18831 }; 18832 const VIEWS = { 18833 axial: 'axial', 18834 top: 'top', 18835 right: 'right', 18836 bottom: 'bottom', 18837 left: 'left', 18838 custom: 'custom' 18839 }; 18840 18841 /** 18842 * Checks is given value is a spacing preset. 18843 * 18844 * @param {string} value Value to check 18845 * 18846 * @return {boolean} Return true if value is string in format var:preset|spacing|. 18847 */ 18848 function isValueSpacingPreset(value) { 18849 if (!value?.includes) { 18850 return false; 18851 } 18852 return value === '0' || value.includes('var:preset|spacing|'); 18853 } 18854 18855 /** 18856 * Converts a spacing preset into a custom value. 18857 * 18858 * @param {string} value Value to convert 18859 * @param {Array} spacingSizes Array of the current spacing preset objects 18860 * 18861 * @return {string} Mapping of the spacing preset to its equivalent custom value. 18862 */ 18863 function getCustomValueFromPreset(value, spacingSizes) { 18864 if (!isValueSpacingPreset(value)) { 18865 return value; 18866 } 18867 const slug = getSpacingPresetSlug(value); 18868 const spacingSize = spacingSizes.find(size => String(size.slug) === slug); 18869 return spacingSize?.size; 18870 } 18871 18872 /** 18873 * Converts a custom value to preset value if one can be found. 18874 * 18875 * Returns value as-is if no match is found. 18876 * 18877 * @param {string} value Value to convert 18878 * @param {Array} spacingSizes Array of the current spacing preset objects 18879 * 18880 * @return {string} The preset value if it can be found. 18881 */ 18882 function getPresetValueFromCustomValue(value, spacingSizes) { 18883 // Return value as-is if it is undefined or is already a preset, or '0'; 18884 if (!value || isValueSpacingPreset(value) || value === '0') { 18885 return value; 18886 } 18887 const spacingMatch = spacingSizes.find(size => String(size.size) === String(value)); 18888 if (spacingMatch?.slug) { 18889 return `var:preset|spacing|$spacingMatch.slug}`; 18890 } 18891 return value; 18892 } 18893 18894 /** 18895 * Converts a spacing preset into a custom value. 18896 * 18897 * @param {string} value Value to convert. 18898 * 18899 * @return {string | undefined} CSS var string for given spacing preset value. 18900 */ 18901 function getSpacingPresetCssVar(value) { 18902 if (!value) { 18903 return; 18904 } 18905 const slug = value.match(/var:preset\|spacing\|(.+)/); 18906 if (!slug) { 18907 return value; 18908 } 18909 return `var(--wp--preset--spacing--$slug[1]})`; 18910 } 18911 18912 /** 18913 * Returns the slug section of the given spacing preset string. 18914 * 18915 * @param {string} value Value to extract slug from. 18916 * 18917 * @return {string|undefined} The int value of the slug from given spacing preset. 18918 */ 18919 function getSpacingPresetSlug(value) { 18920 if (!value) { 18921 return; 18922 } 18923 if (value === '0' || value === 'default') { 18924 return value; 18925 } 18926 const slug = value.match(/var:preset\|spacing\|(.+)/); 18927 return slug ? slug[1] : undefined; 18928 } 18929 18930 /** 18931 * Converts spacing preset value into a Range component value . 18932 * 18933 * @param {string} presetValue Value to convert to Range value. 18934 * @param {Array} spacingSizes Array of current spacing preset value objects. 18935 * 18936 * @return {number} The int value for use in Range control. 18937 */ 18938 function getSliderValueFromPreset(presetValue, spacingSizes) { 18939 if (presetValue === undefined) { 18940 return 0; 18941 } 18942 const slug = parseFloat(presetValue, 10) === 0 ? '0' : getSpacingPresetSlug(presetValue); 18943 const sliderValue = spacingSizes.findIndex(spacingSize => { 18944 return String(spacingSize.slug) === slug; 18945 }); 18946 18947 // Returning NaN rather than undefined as undefined makes range control thumb sit in center 18948 return sliderValue !== -1 ? sliderValue : NaN; 18949 } 18950 18951 /** 18952 * Gets an items with the most occurrence within an array 18953 * https://stackoverflow.com/a/20762713 18954 * 18955 * @param {Array<any>} arr Array of items to check. 18956 * @return {any} The item with the most occurrences. 18957 */ 18958 function mode(arr) { 18959 return arr.sort((a, b) => arr.filter(v => v === a).length - arr.filter(v => v === b).length).pop(); 18960 } 18961 18962 /** 18963 * Gets the 'all' input value from values data. 18964 * 18965 * @param {Object} values Box spacing values 18966 * 18967 * @return {string} The most common value from all sides of box. 18968 */ 18969 function getAllRawValue(values = {}) { 18970 return mode(Object.values(values)); 18971 } 18972 18973 /** 18974 * Checks to determine if values are mixed. 18975 * 18976 * @param {Object} values Box values. 18977 * @param {Array} sides Sides that values relate to. 18978 * 18979 * @return {boolean} Whether values are mixed. 18980 */ 18981 function isValuesMixed(values = {}, sides = ALL_SIDES) { 18982 return Object.values(values).length >= 1 && Object.values(values).length < sides.length || new Set(Object.values(values)).size > 1; 18983 } 18984 18985 /** 18986 * Checks to determine if values are defined. 18987 * 18988 * @param {Object} values Box values. 18989 * 18990 * @return {boolean} Whether values are defined. 18991 */ 18992 function isValuesDefined(values) { 18993 if (values === undefined || values === null) { 18994 return false; 18995 } 18996 return Object.values(values).filter(value => !!value).length > 0; 18997 } 18998 18999 /** 19000 * Determines whether a particular axis has support. If no axis is 19001 * specified, this function checks if either axis is supported. 19002 * 19003 * @param {Array} sides Supported sides. 19004 * @param {string} axis Which axis to check. 19005 * 19006 * @return {boolean} Whether there is support for the specified axis or both axes. 19007 */ 19008 function hasAxisSupport(sides, axis) { 19009 if (!sides || !sides.length) { 19010 return false; 19011 } 19012 const hasHorizontalSupport = sides.includes('horizontal') || sides.includes('left') && sides.includes('right'); 19013 const hasVerticalSupport = sides.includes('vertical') || sides.includes('top') && sides.includes('bottom'); 19014 if (axis === 'horizontal') { 19015 return hasHorizontalSupport; 19016 } 19017 if (axis === 'vertical') { 19018 return hasVerticalSupport; 19019 } 19020 return hasHorizontalSupport || hasVerticalSupport; 19021 } 19022 19023 /** 19024 * Determines which menu options should be included in the SidePicker. 19025 * 19026 * @param {Array} sides Supported sides. 19027 * 19028 * @return {Object} Menu options with each option containing label & icon. 19029 */ 19030 function getSupportedMenuItems(sides) { 19031 if (!sides || !sides.length) { 19032 return {}; 19033 } 19034 const menuItems = {}; 19035 19036 // Determine the primary "side" menu options. 19037 const hasHorizontalSupport = hasAxisSupport(sides, 'horizontal'); 19038 const hasVerticalSupport = hasAxisSupport(sides, 'vertical'); 19039 if (hasHorizontalSupport && hasVerticalSupport) { 19040 menuItems.axial = { 19041 label: LABELS.axial, 19042 icon: ICONS.axial 19043 }; 19044 } else if (hasHorizontalSupport) { 19045 menuItems.axial = { 19046 label: LABELS.horizontal, 19047 icon: ICONS.horizontal 19048 }; 19049 } else if (hasVerticalSupport) { 19050 menuItems.axial = { 19051 label: LABELS.vertical, 19052 icon: ICONS.vertical 19053 }; 19054 } 19055 19056 // Track whether we have any individual sides so we can omit the custom 19057 // option if required. 19058 let numberOfIndividualSides = 0; 19059 ALL_SIDES.forEach(side => { 19060 if (sides.includes(side)) { 19061 numberOfIndividualSides += 1; 19062 menuItems[side] = { 19063 label: LABELS[side], 19064 icon: ICONS[side] 19065 }; 19066 } 19067 }); 19068 19069 // Add custom item if there are enough sides to warrant a separated view. 19070 if (numberOfIndividualSides > 1) { 19071 menuItems.custom = { 19072 label: LABELS.custom, 19073 icon: ICONS.custom 19074 }; 19075 } 19076 return menuItems; 19077 } 19078 19079 /** 19080 * Checks if the supported sides are balanced for each axis. 19081 * - Horizontal - both left and right sides are supported. 19082 * - Vertical - both top and bottom are supported. 19083 * 19084 * @param {Array} sides The supported sides which may be axes as well. 19085 * 19086 * @return {boolean} Whether or not the supported sides are balanced. 19087 */ 19088 function hasBalancedSidesSupport(sides = []) { 19089 const counts = { 19090 top: 0, 19091 right: 0, 19092 bottom: 0, 19093 left: 0 19094 }; 19095 sides.forEach(side => counts[side] += 1); 19096 return (counts.top + counts.bottom) % 2 === 0 && (counts.left + counts.right) % 2 === 0; 19097 } 19098 19099 /** 19100 * Determines which view the SpacingSizesControl should default to on its 19101 * first render; Axial, Custom, or Single side. 19102 * 19103 * @param {Object} values Current side values. 19104 * @param {Array} sides Supported sides. 19105 * 19106 * @return {string} View to display. 19107 */ 19108 function getInitialView(values = {}, sides) { 19109 const { 19110 top, 19111 right, 19112 bottom, 19113 left 19114 } = values; 19115 const sideValues = [top, right, bottom, left].filter(Boolean); 19116 19117 // Axial ( Horizontal & vertical ). 19118 // - Has axial side support 19119 // - Has axial side values which match 19120 // - Has no values and the supported sides are balanced 19121 const hasMatchingAxialValues = top === bottom && left === right && (!!top || !!left); 19122 const hasNoValuesAndBalancedSides = !sideValues.length && hasBalancedSidesSupport(sides); 19123 if (hasAxisSupport(sides) && (hasMatchingAxialValues || hasNoValuesAndBalancedSides)) { 19124 return VIEWS.axial; 19125 } 19126 19127 // Single side. 19128 // - Ensure the side returned is the first side that has a value. 19129 if (sideValues.length === 1) { 19130 let side; 19131 Object.entries(values).some(([key, value]) => { 19132 side = key; 19133 return value !== undefined; 19134 }); 19135 return side; 19136 } 19137 19138 // Only single side supported and no value defined. 19139 if (sides?.length === 1 && !sideValues.length) { 19140 return sides[0]; 19141 } 19142 19143 // Default to the Custom (separated sides) view. 19144 return VIEWS.custom; 19145 } 19146 19147 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/gap.js 19148 /** 19149 * Internal dependencies 19150 */ 19151 19152 19153 /** 19154 * Returns a BoxControl object value from a given blockGap style value. 19155 * The string check is for backwards compatibility before Gutenberg supported 19156 * split gap values (row and column) and the value was a string n + unit. 19157 * 19158 * @param {string? | Object?} blockGapValue A block gap string or axial object value, e.g., '10px' or { top: '10px', left: '10px'}. 19159 * @return {Object|null} A value to pass to the BoxControl component. 19160 */ 19161 function getGapBoxControlValueFromStyle(blockGapValue) { 19162 if (!blockGapValue) { 19163 return null; 19164 } 19165 const isValueString = typeof blockGapValue === 'string'; 19166 return { 19167 top: isValueString ? blockGapValue : blockGapValue?.top, 19168 left: isValueString ? blockGapValue : blockGapValue?.left 19169 }; 19170 } 19171 19172 /** 19173 * Returns a CSS value for the `gap` property from a given blockGap style. 19174 * 19175 * @param {string? | Object?} blockGapValue A block gap string or axial object value, e.g., '10px' or { top: '10px', left: '10px'}. 19176 * @param {string?} defaultValue A default gap value. 19177 * @return {string|null} The concatenated gap value (row and column). 19178 */ 19179 function getGapCSSValue(blockGapValue, defaultValue = '0') { 19180 const blockGapBoxControlValue = getGapBoxControlValueFromStyle(blockGapValue); 19181 if (!blockGapBoxControlValue) { 19182 return null; 19183 } 19184 const row = getSpacingPresetCssVar(blockGapBoxControlValue?.top) || defaultValue; 19185 const column = getSpacingPresetCssVar(blockGapBoxControlValue?.left) || defaultValue; 19186 return row === column ? row : `$row} $column}`; 19187 } 19188 19189 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-vertical-alignment-control/icons.js 19190 19191 /** 19192 * WordPress dependencies 19193 */ 19194 19195 const alignBottom = (0,external_React_.createElement)(external_wp_components_namespaceObject.SVG, { 19196 xmlns: "http://www.w3.org/2000/svg", 19197 viewBox: "0 0 24 24" 19198 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Path, { 19199 d: "M15 4H9v11h6V4zM4 18.5V20h16v-1.5H4z" 19200 })); 19201 const alignCenter = (0,external_React_.createElement)(external_wp_components_namespaceObject.SVG, { 19202 xmlns: "http://www.w3.org/2000/svg", 19203 viewBox: "0 0 24 24" 19204 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Path, { 19205 d: "M20 11h-5V4H9v7H4v1.5h5V20h6v-7.5h5z" 19206 })); 19207 const alignTop = (0,external_React_.createElement)(external_wp_components_namespaceObject.SVG, { 19208 xmlns: "http://www.w3.org/2000/svg", 19209 viewBox: "0 0 24 24" 19210 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Path, { 19211 d: "M9 20h6V9H9v11zM4 4v1.5h16V4H4z" 19212 })); 19213 const alignStretch = (0,external_React_.createElement)(external_wp_components_namespaceObject.SVG, { 19214 xmlns: "http://www.w3.org/2000/svg", 19215 viewBox: "0 0 24 24" 19216 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Path, { 19217 d: "M4 4L20 4L20 5.5L4 5.5L4 4ZM10 7L14 7L14 17L10 17L10 7ZM20 18.5L4 18.5L4 20L20 20L20 18.5Z" 19218 })); 19219 const spaceBetween = (0,external_React_.createElement)(external_wp_components_namespaceObject.SVG, { 19220 xmlns: "http://www.w3.org/2000/svg", 19221 viewBox: "0 0 24 24" 19222 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Path, { 19223 d: "M7 4H17V8L7 8V4ZM7 16L17 16V20L7 20V16ZM20 11.25H4V12.75H20V11.25Z" 19224 })); 19225 19226 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-vertical-alignment-control/ui.js 19227 19228 /** 19229 * WordPress dependencies 19230 */ 19231 19232 19233 19234 /** 19235 * Internal dependencies 19236 */ 19237 19238 const BLOCK_ALIGNMENTS_CONTROLS = { 19239 top: { 19240 icon: alignTop, 19241 title: (0,external_wp_i18n_namespaceObject._x)('Align top', 'Block vertical alignment setting') 19242 }, 19243 center: { 19244 icon: alignCenter, 19245 title: (0,external_wp_i18n_namespaceObject._x)('Align middle', 'Block vertical alignment setting') 19246 }, 19247 bottom: { 19248 icon: alignBottom, 19249 title: (0,external_wp_i18n_namespaceObject._x)('Align bottom', 'Block vertical alignment setting') 19250 }, 19251 stretch: { 19252 icon: alignStretch, 19253 title: (0,external_wp_i18n_namespaceObject._x)('Stretch to fill', 'Block vertical alignment setting') 19254 }, 19255 'space-between': { 19256 icon: spaceBetween, 19257 title: (0,external_wp_i18n_namespaceObject._x)('Space between', 'Block vertical alignment setting') 19258 } 19259 }; 19260 const DEFAULT_CONTROLS = ['top', 'center', 'bottom']; 19261 const DEFAULT_CONTROL = 'top'; 19262 function BlockVerticalAlignmentUI({ 19263 value, 19264 onChange, 19265 controls = DEFAULT_CONTROLS, 19266 isCollapsed = true, 19267 isToolbar 19268 }) { 19269 function applyOrUnset(align) { 19270 return () => onChange(value === align ? undefined : align); 19271 } 19272 const activeAlignment = BLOCK_ALIGNMENTS_CONTROLS[value]; 19273 const defaultAlignmentControl = BLOCK_ALIGNMENTS_CONTROLS[DEFAULT_CONTROL]; 19274 const UIComponent = isToolbar ? external_wp_components_namespaceObject.ToolbarGroup : external_wp_components_namespaceObject.ToolbarDropdownMenu; 19275 const extraProps = isToolbar ? { 19276 isCollapsed 19277 } : {}; 19278 return (0,external_React_.createElement)(UIComponent, { 19279 icon: activeAlignment ? activeAlignment.icon : defaultAlignmentControl.icon, 19280 label: (0,external_wp_i18n_namespaceObject._x)('Change vertical alignment', 'Block vertical alignment setting label'), 19281 controls: controls.map(control => { 19282 return { 19283 ...BLOCK_ALIGNMENTS_CONTROLS[control], 19284 isActive: value === control, 19285 role: isCollapsed ? 'menuitemradio' : undefined, 19286 onClick: applyOrUnset(control) 19287 }; 19288 }), 19289 ...extraProps 19290 }); 19291 } 19292 19293 /** 19294 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-vertical-alignment-toolbar/README.md 19295 */ 19296 /* harmony default export */ const ui = (BlockVerticalAlignmentUI); 19297 19298 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-vertical-alignment-control/index.js 19299 19300 /** 19301 * Internal dependencies 19302 */ 19303 19304 const BlockVerticalAlignmentControl = props => { 19305 return (0,external_React_.createElement)(ui, { 19306 ...props, 19307 isToolbar: false 19308 }); 19309 }; 19310 const BlockVerticalAlignmentToolbar = props => { 19311 return (0,external_React_.createElement)(ui, { 19312 ...props, 19313 isToolbar: true 19314 }); 19315 }; 19316 19317 /** 19318 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-vertical-alignment-control/README.md 19319 */ 19320 19321 19322 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/justify-content-control/ui.js 19323 19324 /** 19325 * WordPress dependencies 19326 */ 19327 19328 19329 19330 const icons = { 19331 left: justify_left, 19332 center: justify_center, 19333 right: justify_right, 19334 'space-between': justify_space_between, 19335 stretch: justify_stretch 19336 }; 19337 function JustifyContentUI({ 19338 allowedControls = ['left', 'center', 'right', 'space-between'], 19339 isCollapsed = true, 19340 onChange, 19341 value, 19342 popoverProps, 19343 isToolbar 19344 }) { 19345 // If the control is already selected we want a click 19346 // again on the control to deselect the item, so we 19347 // call onChange( undefined ) 19348 const handleClick = next => { 19349 if (next === value) { 19350 onChange(undefined); 19351 } else { 19352 onChange(next); 19353 } 19354 }; 19355 const icon = value ? icons[value] : icons.left; 19356 const allControls = [{ 19357 name: 'left', 19358 icon: justify_left, 19359 title: (0,external_wp_i18n_namespaceObject.__)('Justify items left'), 19360 isActive: 'left' === value, 19361 onClick: () => handleClick('left') 19362 }, { 19363 name: 'center', 19364 icon: justify_center, 19365 title: (0,external_wp_i18n_namespaceObject.__)('Justify items center'), 19366 isActive: 'center' === value, 19367 onClick: () => handleClick('center') 19368 }, { 19369 name: 'right', 19370 icon: justify_right, 19371 title: (0,external_wp_i18n_namespaceObject.__)('Justify items right'), 19372 isActive: 'right' === value, 19373 onClick: () => handleClick('right') 19374 }, { 19375 name: 'space-between', 19376 icon: justify_space_between, 19377 title: (0,external_wp_i18n_namespaceObject.__)('Space between items'), 19378 isActive: 'space-between' === value, 19379 onClick: () => handleClick('space-between') 19380 }, { 19381 name: 'stretch', 19382 icon: justify_stretch, 19383 title: (0,external_wp_i18n_namespaceObject.__)('Stretch items'), 19384 isActive: 'stretch' === value, 19385 onClick: () => handleClick('stretch') 19386 }]; 19387 const UIComponent = isToolbar ? external_wp_components_namespaceObject.ToolbarGroup : external_wp_components_namespaceObject.ToolbarDropdownMenu; 19388 const extraProps = isToolbar ? { 19389 isCollapsed 19390 } : {}; 19391 return (0,external_React_.createElement)(UIComponent, { 19392 icon: icon, 19393 popoverProps: popoverProps, 19394 label: (0,external_wp_i18n_namespaceObject.__)('Change items justification'), 19395 controls: allControls.filter(elem => allowedControls.includes(elem.name)), 19396 ...extraProps 19397 }); 19398 } 19399 /* harmony default export */ const justify_content_control_ui = (JustifyContentUI); 19400 19401 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/justify-content-control/index.js 19402 19403 /** 19404 * Internal dependencies 19405 */ 19406 19407 const JustifyContentControl = props => { 19408 return (0,external_React_.createElement)(justify_content_control_ui, { 19409 ...props, 19410 isToolbar: false 19411 }); 19412 }; 19413 const JustifyToolbar = props => { 19414 return (0,external_React_.createElement)(justify_content_control_ui, { 19415 ...props, 19416 isToolbar: true 19417 }); 19418 }; 19419 19420 /** 19421 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/justify-content-control/README.md 19422 */ 19423 19424 19425 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/layouts/flex.js 19426 19427 /** 19428 * WordPress dependencies 19429 */ 19430 19431 19432 19433 19434 /** 19435 * Internal dependencies 19436 */ 19437 19438 19439 19440 19441 19442 19443 // Used with the default, horizontal flex orientation. 19444 const justifyContentMap = { 19445 left: 'flex-start', 19446 right: 'flex-end', 19447 center: 'center', 19448 'space-between': 'space-between' 19449 }; 19450 19451 // Used with the vertical (column) flex orientation. 19452 const alignItemsMap = { 19453 left: 'flex-start', 19454 right: 'flex-end', 19455 center: 'center', 19456 stretch: 'stretch' 19457 }; 19458 const verticalAlignmentMap = { 19459 top: 'flex-start', 19460 center: 'center', 19461 bottom: 'flex-end', 19462 stretch: 'stretch', 19463 'space-between': 'space-between' 19464 }; 19465 const flexWrapOptions = ['wrap', 'nowrap']; 19466 /* harmony default export */ const flex = ({ 19467 name: 'flex', 19468 label: (0,external_wp_i18n_namespaceObject.__)('Flex'), 19469 inspectorControls: function FlexLayoutInspectorControls({ 19470 layout = {}, 19471 onChange, 19472 layoutBlockSupport = {} 19473 }) { 19474 const { 19475 allowOrientation = true 19476 } = layoutBlockSupport; 19477 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.Flex, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexItem, null, (0,external_React_.createElement)(FlexLayoutJustifyContentControl, { 19478 layout: layout, 19479 onChange: onChange 19480 })), (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexItem, null, allowOrientation && (0,external_React_.createElement)(OrientationControl, { 19481 layout: layout, 19482 onChange: onChange 19483 }))), (0,external_React_.createElement)(FlexWrapControl, { 19484 layout: layout, 19485 onChange: onChange 19486 })); 19487 }, 19488 toolBarControls: function FlexLayoutToolbarControls({ 19489 layout = {}, 19490 onChange, 19491 layoutBlockSupport 19492 }) { 19493 if (layoutBlockSupport?.allowSwitching) { 19494 return null; 19495 } 19496 const { 19497 allowVerticalAlignment = true 19498 } = layoutBlockSupport; 19499 return (0,external_React_.createElement)(block_controls, { 19500 group: "block", 19501 __experimentalShareWithChildBlocks: true 19502 }, (0,external_React_.createElement)(FlexLayoutJustifyContentControl, { 19503 layout: layout, 19504 onChange: onChange, 19505 isToolbar: true 19506 }), allowVerticalAlignment && (0,external_React_.createElement)(FlexLayoutVerticalAlignmentControl, { 19507 layout: layout, 19508 onChange: onChange, 19509 isToolbar: true 19510 })); 19511 }, 19512 getLayoutStyle: function getLayoutStyle({ 19513 selector, 19514 layout, 19515 style, 19516 blockName, 19517 hasBlockGapSupport, 19518 layoutDefinitions = LAYOUT_DEFINITIONS 19519 }) { 19520 const { 19521 orientation = 'horizontal' 19522 } = layout; 19523 19524 // If a block's block.json skips serialization for spacing or spacing.blockGap, 19525 // don't apply the user-defined value to the styles. 19526 const blockGapValue = style?.spacing?.blockGap && !shouldSkipSerialization(blockName, 'spacing', 'blockGap') ? getGapCSSValue(style?.spacing?.blockGap, '0.5em') : undefined; 19527 const justifyContent = justifyContentMap[layout.justifyContent]; 19528 const flexWrap = flexWrapOptions.includes(layout.flexWrap) ? layout.flexWrap : 'wrap'; 19529 const verticalAlignment = verticalAlignmentMap[layout.verticalAlignment]; 19530 const alignItems = alignItemsMap[layout.justifyContent] || alignItemsMap.left; 19531 let output = ''; 19532 const rules = []; 19533 if (flexWrap && flexWrap !== 'wrap') { 19534 rules.push(`flex-wrap: $flexWrap}`); 19535 } 19536 if (orientation === 'horizontal') { 19537 if (verticalAlignment) { 19538 rules.push(`align-items: $verticalAlignment}`); 19539 } 19540 if (justifyContent) { 19541 rules.push(`justify-content: $justifyContent}`); 19542 } 19543 } else { 19544 if (verticalAlignment) { 19545 rules.push(`justify-content: $verticalAlignment}`); 19546 } 19547 rules.push('flex-direction: column'); 19548 rules.push(`align-items: $alignItems}`); 19549 } 19550 if (rules.length) { 19551 output = `$appendSelectors(selector)} { 19552 $rules.join('; ')}; 19553 }`; 19554 } 19555 19556 // Output blockGap styles based on rules contained in layout definitions in theme.json. 19557 if (hasBlockGapSupport && blockGapValue) { 19558 output += getBlockGapCSS(selector, layoutDefinitions, 'flex', blockGapValue); 19559 } 19560 return output; 19561 }, 19562 getOrientation(layout) { 19563 const { 19564 orientation = 'horizontal' 19565 } = layout; 19566 return orientation; 19567 }, 19568 getAlignments() { 19569 return []; 19570 } 19571 }); 19572 function FlexLayoutVerticalAlignmentControl({ 19573 layout, 19574 onChange, 19575 isToolbar = false 19576 }) { 19577 const { 19578 orientation = 'horizontal' 19579 } = layout; 19580 const defaultVerticalAlignment = orientation === 'horizontal' ? verticalAlignmentMap.center : verticalAlignmentMap.top; 19581 const { 19582 verticalAlignment = defaultVerticalAlignment 19583 } = layout; 19584 const onVerticalAlignmentChange = value => { 19585 onChange({ 19586 ...layout, 19587 verticalAlignment: value 19588 }); 19589 }; 19590 if (isToolbar) { 19591 return (0,external_React_.createElement)(BlockVerticalAlignmentControl, { 19592 onChange: onVerticalAlignmentChange, 19593 value: verticalAlignment, 19594 controls: orientation === 'horizontal' ? ['top', 'center', 'bottom', 'stretch'] : ['top', 'center', 'bottom', 'space-between'] 19595 }); 19596 } 19597 const verticalAlignmentOptions = [{ 19598 value: 'flex-start', 19599 label: (0,external_wp_i18n_namespaceObject.__)('Align items top') 19600 }, { 19601 value: 'center', 19602 label: (0,external_wp_i18n_namespaceObject.__)('Align items center') 19603 }, { 19604 value: 'flex-end', 19605 label: (0,external_wp_i18n_namespaceObject.__)('Align items bottom') 19606 }]; 19607 return (0,external_React_.createElement)("fieldset", { 19608 className: "block-editor-hooks__flex-layout-vertical-alignment-control" 19609 }, (0,external_React_.createElement)("legend", null, (0,external_wp_i18n_namespaceObject.__)('Vertical alignment')), (0,external_React_.createElement)("div", null, verticalAlignmentOptions.map((value, icon, label) => { 19610 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 19611 key: value, 19612 label: label, 19613 icon: icon, 19614 isPressed: verticalAlignment === value, 19615 onClick: () => onVerticalAlignmentChange(value) 19616 }); 19617 }))); 19618 } 19619 const POPOVER_PROPS = { 19620 placement: 'bottom-start' 19621 }; 19622 function FlexLayoutJustifyContentControl({ 19623 layout, 19624 onChange, 19625 isToolbar = false 19626 }) { 19627 const { 19628 justifyContent = 'left', 19629 orientation = 'horizontal' 19630 } = layout; 19631 const onJustificationChange = value => { 19632 onChange({ 19633 ...layout, 19634 justifyContent: value 19635 }); 19636 }; 19637 const allowedControls = ['left', 'center', 'right']; 19638 if (orientation === 'horizontal') { 19639 allowedControls.push('space-between'); 19640 } else { 19641 allowedControls.push('stretch'); 19642 } 19643 if (isToolbar) { 19644 return (0,external_React_.createElement)(JustifyContentControl, { 19645 allowedControls: allowedControls, 19646 value: justifyContent, 19647 onChange: onJustificationChange, 19648 popoverProps: POPOVER_PROPS 19649 }); 19650 } 19651 const justificationOptions = [{ 19652 value: 'left', 19653 icon: justify_left, 19654 label: (0,external_wp_i18n_namespaceObject.__)('Justify items left') 19655 }, { 19656 value: 'center', 19657 icon: justify_center, 19658 label: (0,external_wp_i18n_namespaceObject.__)('Justify items center') 19659 }, { 19660 value: 'right', 19661 icon: justify_right, 19662 label: (0,external_wp_i18n_namespaceObject.__)('Justify items right') 19663 }]; 19664 if (orientation === 'horizontal') { 19665 justificationOptions.push({ 19666 value: 'space-between', 19667 icon: justify_space_between, 19668 label: (0,external_wp_i18n_namespaceObject.__)('Space between items') 19669 }); 19670 } else { 19671 justificationOptions.push({ 19672 value: 'stretch', 19673 icon: justify_stretch, 19674 label: (0,external_wp_i18n_namespaceObject.__)('Stretch items') 19675 }); 19676 } 19677 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToggleGroupControl, { 19678 __nextHasNoMarginBottom: true, 19679 label: (0,external_wp_i18n_namespaceObject.__)('Justification'), 19680 value: justifyContent, 19681 onChange: onJustificationChange, 19682 className: "block-editor-hooks__flex-layout-justification-controls" 19683 }, justificationOptions.map(({ 19684 value, 19685 icon, 19686 label 19687 }) => { 19688 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOptionIcon, { 19689 key: value, 19690 value: value, 19691 icon: icon, 19692 label: label 19693 }); 19694 })); 19695 } 19696 function FlexWrapControl({ 19697 layout, 19698 onChange 19699 }) { 19700 const { 19701 flexWrap = 'wrap' 19702 } = layout; 19703 return (0,external_React_.createElement)(external_wp_components_namespaceObject.ToggleControl, { 19704 __nextHasNoMarginBottom: true, 19705 label: (0,external_wp_i18n_namespaceObject.__)('Allow to wrap to multiple lines'), 19706 onChange: value => { 19707 onChange({ 19708 ...layout, 19709 flexWrap: value ? 'wrap' : 'nowrap' 19710 }); 19711 }, 19712 checked: flexWrap === 'wrap' 19713 }); 19714 } 19715 function OrientationControl({ 19716 layout, 19717 onChange 19718 }) { 19719 const { 19720 orientation = 'horizontal', 19721 verticalAlignment, 19722 justifyContent 19723 } = layout; 19724 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToggleGroupControl, { 19725 __nextHasNoMarginBottom: true, 19726 className: "block-editor-hooks__flex-layout-orientation-controls", 19727 label: (0,external_wp_i18n_namespaceObject.__)('Orientation'), 19728 value: orientation, 19729 onChange: value => { 19730 // Make sure the vertical alignment and justification are compatible with the new orientation. 19731 let newVerticalAlignment = verticalAlignment; 19732 let newJustification = justifyContent; 19733 if (value === 'horizontal') { 19734 if (verticalAlignment === 'space-between') { 19735 newVerticalAlignment = 'center'; 19736 } 19737 if (justifyContent === 'stretch') { 19738 newJustification = 'left'; 19739 } 19740 } else { 19741 if (verticalAlignment === 'stretch') { 19742 newVerticalAlignment = 'top'; 19743 } 19744 if (justifyContent === 'space-between') { 19745 newJustification = 'left'; 19746 } 19747 } 19748 return onChange({ 19749 ...layout, 19750 orientation: value, 19751 verticalAlignment: newVerticalAlignment, 19752 justifyContent: newJustification 19753 }); 19754 } 19755 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOptionIcon, { 19756 icon: arrow_right, 19757 value: 'horizontal', 19758 label: (0,external_wp_i18n_namespaceObject.__)('Horizontal') 19759 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOptionIcon, { 19760 icon: arrow_down, 19761 value: 'vertical', 19762 label: (0,external_wp_i18n_namespaceObject.__)('Vertical') 19763 })); 19764 } 19765 19766 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/layouts/flow.js 19767 /** 19768 * WordPress dependencies 19769 */ 19770 19771 19772 /** 19773 * Internal dependencies 19774 */ 19775 19776 19777 19778 19779 /* harmony default export */ const flow = ({ 19780 name: 'default', 19781 label: (0,external_wp_i18n_namespaceObject.__)('Flow'), 19782 inspectorControls: function DefaultLayoutInspectorControls() { 19783 return null; 19784 }, 19785 toolBarControls: function DefaultLayoutToolbarControls() { 19786 return null; 19787 }, 19788 getLayoutStyle: function getLayoutStyle({ 19789 selector, 19790 style, 19791 blockName, 19792 hasBlockGapSupport, 19793 layoutDefinitions = LAYOUT_DEFINITIONS 19794 }) { 19795 const blockGapStyleValue = getGapCSSValue(style?.spacing?.blockGap); 19796 19797 // If a block's block.json skips serialization for spacing or 19798 // spacing.blockGap, don't apply the user-defined value to the styles. 19799 let blockGapValue = ''; 19800 if (!shouldSkipSerialization(blockName, 'spacing', 'blockGap')) { 19801 // If an object is provided only use the 'top' value for this kind of gap. 19802 if (blockGapStyleValue?.top) { 19803 blockGapValue = getGapCSSValue(blockGapStyleValue?.top); 19804 } else if (typeof blockGapStyleValue === 'string') { 19805 blockGapValue = getGapCSSValue(blockGapStyleValue); 19806 } 19807 } 19808 let output = ''; 19809 19810 // Output blockGap styles based on rules contained in layout definitions in theme.json. 19811 if (hasBlockGapSupport && blockGapValue) { 19812 output += getBlockGapCSS(selector, layoutDefinitions, 'default', blockGapValue); 19813 } 19814 return output; 19815 }, 19816 getOrientation() { 19817 return 'vertical'; 19818 }, 19819 getAlignments(layout, isBlockBasedTheme) { 19820 const alignmentInfo = getAlignmentsInfo(layout); 19821 if (layout.alignments !== undefined) { 19822 if (!layout.alignments.includes('none')) { 19823 layout.alignments.unshift('none'); 19824 } 19825 return layout.alignments.map(alignment => ({ 19826 name: alignment, 19827 info: alignmentInfo[alignment] 19828 })); 19829 } 19830 const alignments = [{ 19831 name: 'left' 19832 }, { 19833 name: 'center' 19834 }, { 19835 name: 'right' 19836 }]; 19837 19838 // This is for backwards compatibility with hybrid themes. 19839 if (!isBlockBasedTheme) { 19840 const { 19841 contentSize, 19842 wideSize 19843 } = layout; 19844 if (contentSize) { 19845 alignments.unshift({ 19846 name: 'full' 19847 }); 19848 } 19849 if (wideSize) { 19850 alignments.unshift({ 19851 name: 'wide', 19852 info: alignmentInfo.wide 19853 }); 19854 } 19855 } 19856 alignments.unshift({ 19857 name: 'none', 19858 info: alignmentInfo.none 19859 }); 19860 return alignments; 19861 } 19862 }); 19863 19864 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/icon/index.js 19865 /** 19866 * WordPress dependencies 19867 */ 19868 19869 19870 /** @typedef {{icon: JSX.Element, size?: number} & import('@wordpress/primitives').SVGProps} IconProps */ 19871 19872 /** 19873 * Return an SVG icon. 19874 * 19875 * @param {IconProps} props icon is the SVG component to render 19876 * size is a number specifiying the icon size in pixels 19877 * Other props will be passed to wrapped SVG component 19878 * @param {import('react').ForwardedRef<HTMLElement>} ref The forwarded ref to the SVG element. 19879 * 19880 * @return {JSX.Element} Icon component 19881 */ 19882 function Icon({ 19883 icon, 19884 size = 24, 19885 ...props 19886 }, ref) { 19887 return (0,external_wp_element_namespaceObject.cloneElement)(icon, { 19888 width: size, 19889 height: size, 19890 ...props, 19891 ref 19892 }); 19893 } 19894 /* harmony default export */ const build_module_icon = ((0,external_wp_element_namespaceObject.forwardRef)(Icon)); 19895 19896 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/position-center.js 19897 19898 /** 19899 * WordPress dependencies 19900 */ 19901 19902 const positionCenter = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 19903 xmlns: "http://www.w3.org/2000/svg", 19904 viewBox: "0 0 24 24" 19905 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 19906 d: "M19 5.5H5V4h14v1.5ZM19 20H5v-1.5h14V20ZM7 9h10v6H7V9Z" 19907 })); 19908 /* harmony default export */ const position_center = (positionCenter); 19909 19910 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/stretch-wide.js 19911 19912 /** 19913 * WordPress dependencies 19914 */ 19915 19916 const stretchWide = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 19917 xmlns: "http://www.w3.org/2000/svg", 19918 viewBox: "0 0 24 24" 19919 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 19920 d: "M16 5.5H8V4h8v1.5ZM16 20H8v-1.5h8V20ZM5 9h14v6H5V9Z" 19921 })); 19922 /* harmony default export */ const stretch_wide = (stretchWide); 19923 19924 ;// CONCATENATED MODULE: external ["wp","styleEngine"] 19925 const external_wp_styleEngine_namespaceObject = window["wp"]["styleEngine"]; 19926 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/layouts/constrained.js 19927 19928 /** 19929 * WordPress dependencies 19930 */ 19931 19932 19933 19934 19935 19936 /** 19937 * Internal dependencies 19938 */ 19939 19940 19941 19942 19943 19944 /* harmony default export */ const constrained = ({ 19945 name: 'constrained', 19946 label: (0,external_wp_i18n_namespaceObject.__)('Constrained'), 19947 inspectorControls: function DefaultLayoutInspectorControls({ 19948 layout, 19949 onChange, 19950 layoutBlockSupport = {} 19951 }) { 19952 const { 19953 wideSize, 19954 contentSize, 19955 justifyContent = 'center' 19956 } = layout; 19957 const { 19958 allowJustification = true, 19959 allowCustomContentAndWideSize = true 19960 } = layoutBlockSupport; 19961 const onJustificationChange = value => { 19962 onChange({ 19963 ...layout, 19964 justifyContent: value 19965 }); 19966 }; 19967 const justificationOptions = [{ 19968 value: 'left', 19969 icon: justify_left, 19970 label: (0,external_wp_i18n_namespaceObject.__)('Justify items left') 19971 }, { 19972 value: 'center', 19973 icon: justify_center, 19974 label: (0,external_wp_i18n_namespaceObject.__)('Justify items center') 19975 }, { 19976 value: 'right', 19977 icon: justify_right, 19978 label: (0,external_wp_i18n_namespaceObject.__)('Justify items right') 19979 }]; 19980 const [availableUnits] = use_settings_useSettings('spacing.units'); 19981 const units = (0,external_wp_components_namespaceObject.__experimentalUseCustomUnits)({ 19982 availableUnits: availableUnits || ['%', 'px', 'em', 'rem', 'vw'] 19983 }); 19984 return (0,external_React_.createElement)(external_React_.Fragment, null, allowCustomContentAndWideSize && (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)("div", { 19985 className: "block-editor-hooks__layout-controls" 19986 }, (0,external_React_.createElement)("div", { 19987 className: "block-editor-hooks__layout-controls-unit" 19988 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalUnitControl, { 19989 className: "block-editor-hooks__layout-controls-unit-input", 19990 label: (0,external_wp_i18n_namespaceObject.__)('Content'), 19991 labelPosition: "top", 19992 __unstableInputWidth: "80px", 19993 value: contentSize || wideSize || '', 19994 onChange: nextWidth => { 19995 nextWidth = 0 > parseFloat(nextWidth) ? '0' : nextWidth; 19996 onChange({ 19997 ...layout, 19998 contentSize: nextWidth 19999 }); 20000 }, 20001 units: units 20002 }), (0,external_React_.createElement)(build_module_icon, { 20003 icon: position_center 20004 })), (0,external_React_.createElement)("div", { 20005 className: "block-editor-hooks__layout-controls-unit" 20006 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalUnitControl, { 20007 className: "block-editor-hooks__layout-controls-unit-input", 20008 label: (0,external_wp_i18n_namespaceObject.__)('Wide'), 20009 labelPosition: "top", 20010 __unstableInputWidth: "80px", 20011 value: wideSize || contentSize || '', 20012 onChange: nextWidth => { 20013 nextWidth = 0 > parseFloat(nextWidth) ? '0' : nextWidth; 20014 onChange({ 20015 ...layout, 20016 wideSize: nextWidth 20017 }); 20018 }, 20019 units: units 20020 }), (0,external_React_.createElement)(build_module_icon, { 20021 icon: stretch_wide 20022 }))), (0,external_React_.createElement)("p", { 20023 className: "block-editor-hooks__layout-controls-helptext" 20024 }, (0,external_wp_i18n_namespaceObject.__)('Customize the width for all elements that are assigned to the center or wide columns.'))), allowJustification && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToggleGroupControl, { 20025 __nextHasNoMarginBottom: true, 20026 label: (0,external_wp_i18n_namespaceObject.__)('Justification'), 20027 value: justifyContent, 20028 onChange: onJustificationChange 20029 }, justificationOptions.map(({ 20030 value, 20031 icon, 20032 label 20033 }) => { 20034 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOptionIcon, { 20035 key: value, 20036 value: value, 20037 icon: icon, 20038 label: label 20039 }); 20040 }))); 20041 }, 20042 toolBarControls: function DefaultLayoutToolbarControls() { 20043 return null; 20044 }, 20045 getLayoutStyle: function getLayoutStyle({ 20046 selector, 20047 layout = {}, 20048 style, 20049 blockName, 20050 hasBlockGapSupport, 20051 layoutDefinitions = LAYOUT_DEFINITIONS 20052 }) { 20053 const { 20054 contentSize, 20055 wideSize, 20056 justifyContent 20057 } = layout; 20058 const blockGapStyleValue = getGapCSSValue(style?.spacing?.blockGap); 20059 20060 // If a block's block.json skips serialization for spacing or 20061 // spacing.blockGap, don't apply the user-defined value to the styles. 20062 let blockGapValue = ''; 20063 if (!shouldSkipSerialization(blockName, 'spacing', 'blockGap')) { 20064 // If an object is provided only use the 'top' value for this kind of gap. 20065 if (blockGapStyleValue?.top) { 20066 blockGapValue = getGapCSSValue(blockGapStyleValue?.top); 20067 } else if (typeof blockGapStyleValue === 'string') { 20068 blockGapValue = getGapCSSValue(blockGapStyleValue); 20069 } 20070 } 20071 const marginLeft = justifyContent === 'left' ? '0 !important' : 'auto !important'; 20072 const marginRight = justifyContent === 'right' ? '0 !important' : 'auto !important'; 20073 let output = !!contentSize || !!wideSize ? ` 20074 $appendSelectors(selector, '> :where(:not(.alignleft):not(.alignright):not(.alignfull))')} { 20075 max-width: $contentSize !== null && contentSize !== void 0 ? contentSize : wideSize}; 20076 margin-left: $marginLeft}; 20077 margin-right: $marginRight}; 20078 } 20079 $appendSelectors(selector, '> .alignwide')} { 20080 max-width: $wideSize !== null && wideSize !== void 0 ? wideSize : contentSize}; 20081 } 20082 $appendSelectors(selector, '> .alignfull')} { 20083 max-width: none; 20084 } 20085 ` : ''; 20086 if (justifyContent === 'left') { 20087 output += `$appendSelectors(selector, '> :where(:not(.alignleft):not(.alignright):not(.alignfull))')} 20088 { margin-left: $marginLeft}; }`; 20089 } else if (justifyContent === 'right') { 20090 output += `$appendSelectors(selector, '> :where(:not(.alignleft):not(.alignright):not(.alignfull))')} 20091 { margin-right: $marginRight}; }`; 20092 } 20093 20094 // If there is custom padding, add negative margins for alignfull blocks. 20095 if (style?.spacing?.padding) { 20096 // The style object might be storing a preset so we need to make sure we get a usable value. 20097 const paddingValues = (0,external_wp_styleEngine_namespaceObject.getCSSRules)(style); 20098 paddingValues.forEach(rule => { 20099 if (rule.key === 'paddingRight') { 20100 output += ` 20101 $appendSelectors(selector, '> .alignfull')} { 20102 margin-right: calc($rule.value} * -1); 20103 } 20104 `; 20105 } else if (rule.key === 'paddingLeft') { 20106 output += ` 20107 $appendSelectors(selector, '> .alignfull')} { 20108 margin-left: calc($rule.value} * -1); 20109 } 20110 `; 20111 } 20112 }); 20113 } 20114 20115 // Output blockGap styles based on rules contained in layout definitions in theme.json. 20116 if (hasBlockGapSupport && blockGapValue) { 20117 output += getBlockGapCSS(selector, layoutDefinitions, 'constrained', blockGapValue); 20118 } 20119 return output; 20120 }, 20121 getOrientation() { 20122 return 'vertical'; 20123 }, 20124 getAlignments(layout) { 20125 const alignmentInfo = getAlignmentsInfo(layout); 20126 if (layout.alignments !== undefined) { 20127 if (!layout.alignments.includes('none')) { 20128 layout.alignments.unshift('none'); 20129 } 20130 return layout.alignments.map(alignment => ({ 20131 name: alignment, 20132 info: alignmentInfo[alignment] 20133 })); 20134 } 20135 const { 20136 contentSize, 20137 wideSize 20138 } = layout; 20139 const alignments = [{ 20140 name: 'left' 20141 }, { 20142 name: 'center' 20143 }, { 20144 name: 'right' 20145 }]; 20146 if (contentSize) { 20147 alignments.unshift({ 20148 name: 'full' 20149 }); 20150 } 20151 if (wideSize) { 20152 alignments.unshift({ 20153 name: 'wide', 20154 info: alignmentInfo.wide 20155 }); 20156 } 20157 alignments.unshift({ 20158 name: 'none', 20159 info: alignmentInfo.none 20160 }); 20161 return alignments; 20162 } 20163 }); 20164 20165 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/layouts/grid.js 20166 20167 /** 20168 * WordPress dependencies 20169 */ 20170 20171 20172 20173 /** 20174 * Internal dependencies 20175 */ 20176 20177 20178 20179 20180 const RANGE_CONTROL_MAX_VALUES = { 20181 px: 600, 20182 '%': 100, 20183 vw: 100, 20184 vh: 100, 20185 em: 38, 20186 rem: 38, 20187 svw: 100, 20188 lvw: 100, 20189 dvw: 100, 20190 svh: 100, 20191 lvh: 100, 20192 dvh: 100, 20193 vi: 100, 20194 svi: 100, 20195 lvi: 100, 20196 dvi: 100, 20197 vb: 100, 20198 svb: 100, 20199 lvb: 100, 20200 dvb: 100, 20201 vmin: 100, 20202 svmin: 100, 20203 lvmin: 100, 20204 dvmin: 100, 20205 vmax: 100, 20206 svmax: 100, 20207 lvmax: 100, 20208 dvmax: 100 20209 }; 20210 /* harmony default export */ const grid = ({ 20211 name: 'grid', 20212 label: (0,external_wp_i18n_namespaceObject.__)('Grid'), 20213 inspectorControls: function GridLayoutInspectorControls({ 20214 layout = {}, 20215 onChange 20216 }) { 20217 return layout?.columnCount ? (0,external_React_.createElement)(GridLayoutColumnsControl, { 20218 layout: layout, 20219 onChange: onChange 20220 }) : (0,external_React_.createElement)(GridLayoutMinimumWidthControl, { 20221 layout: layout, 20222 onChange: onChange 20223 }); 20224 }, 20225 toolBarControls: function DefaultLayoutToolbarControls() { 20226 return null; 20227 }, 20228 getLayoutStyle: function getLayoutStyle({ 20229 selector, 20230 layout, 20231 style, 20232 blockName, 20233 hasBlockGapSupport, 20234 layoutDefinitions = LAYOUT_DEFINITIONS 20235 }) { 20236 const { 20237 minimumColumnWidth = '12rem', 20238 columnCount = null 20239 } = layout; 20240 20241 // If a block's block.json skips serialization for spacing or spacing.blockGap, 20242 // don't apply the user-defined value to the styles. 20243 const blockGapValue = style?.spacing?.blockGap && !shouldSkipSerialization(blockName, 'spacing', 'blockGap') ? getGapCSSValue(style?.spacing?.blockGap, '0.5em') : undefined; 20244 let output = ''; 20245 const rules = []; 20246 if (columnCount) { 20247 rules.push(`grid-template-columns: repeat($columnCount}, minmax(0, 1fr))`); 20248 } else if (minimumColumnWidth) { 20249 rules.push(`grid-template-columns: repeat(auto-fill, minmax(min($minimumColumnWidth}, 100%), 1fr))`); 20250 } 20251 if (rules.length) { 20252 // Reason to disable: the extra line breaks added by prettier mess with the unit tests. 20253 // eslint-disable-next-line prettier/prettier 20254 output = `$appendSelectors(selector)} { $rules.join('; ')}; }`; 20255 } 20256 20257 // Output blockGap styles based on rules contained in layout definitions in theme.json. 20258 if (hasBlockGapSupport && blockGapValue) { 20259 output += getBlockGapCSS(selector, layoutDefinitions, 'grid', blockGapValue); 20260 } 20261 return output; 20262 }, 20263 getOrientation() { 20264 return 'horizontal'; 20265 }, 20266 getAlignments() { 20267 return []; 20268 } 20269 }); 20270 20271 // Enables setting minimum width of grid items. 20272 function GridLayoutMinimumWidthControl({ 20273 layout, 20274 onChange 20275 }) { 20276 const { 20277 minimumColumnWidth: value = '12rem' 20278 } = layout; 20279 const [quantity, unit] = (0,external_wp_components_namespaceObject.__experimentalParseQuantityAndUnitFromRawValue)(value); 20280 const handleSliderChange = next => { 20281 onChange({ 20282 ...layout, 20283 minimumColumnWidth: [next, unit].join('') 20284 }); 20285 }; 20286 20287 // Mostly copied from HeightControl. 20288 const handleUnitChange = newUnit => { 20289 // Attempt to smooth over differences between currentUnit and newUnit. 20290 // This should slightly improve the experience of switching between unit types. 20291 let newValue; 20292 if (['em', 'rem'].includes(newUnit) && unit === 'px') { 20293 // Convert pixel value to an approximate of the new unit, assuming a root size of 16px. 20294 newValue = (quantity / 16).toFixed(2) + newUnit; 20295 } else if (['em', 'rem'].includes(unit) && newUnit === 'px') { 20296 // Convert to pixel value assuming a root size of 16px. 20297 newValue = Math.round(quantity * 16) + newUnit; 20298 } else if (['vh', 'vw', '%', 'svw', 'lvw', 'dvw', 'svh', 'lvh', 'dvh', 'vi', 'svi', 'lvi', 'dvi', 'vb', 'svb', 'lvb', 'dvb', 'vmin', 'svmin', 'lvmin', 'dvmin', 'vmax', 'svmax', 'lvmax', 'dvmax'].includes(newUnit) && quantity > 100) { 20299 // When converting to `%` or viewport-relative units, cap the new value at 100. 20300 newValue = 100 + newUnit; 20301 } 20302 onChange({ 20303 ...layout, 20304 minimumColumnWidth: newValue 20305 }); 20306 }; 20307 return (0,external_React_.createElement)("fieldset", null, (0,external_React_.createElement)(external_wp_components_namespaceObject.BaseControl.VisualLabel, { 20308 as: "legend" 20309 }, (0,external_wp_i18n_namespaceObject.__)('Minimum column width')), (0,external_React_.createElement)(external_wp_components_namespaceObject.Flex, { 20310 gap: 4 20311 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexItem, { 20312 isBlock: true 20313 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalUnitControl, { 20314 size: '__unstable-large', 20315 onChange: newValue => { 20316 onChange({ 20317 ...layout, 20318 minimumColumnWidth: newValue 20319 }); 20320 }, 20321 onUnitChange: handleUnitChange, 20322 value: value, 20323 min: 0 20324 })), (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexItem, { 20325 isBlock: true 20326 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.RangeControl, { 20327 onChange: handleSliderChange, 20328 value: quantity, 20329 min: 0, 20330 max: RANGE_CONTROL_MAX_VALUES[unit] || 600, 20331 withInputField: false 20332 })))); 20333 } 20334 20335 // Enables setting number of grid columns 20336 function GridLayoutColumnsControl({ 20337 layout, 20338 onChange 20339 }) { 20340 const { 20341 columnCount = 3 20342 } = layout; 20343 return (0,external_React_.createElement)(external_wp_components_namespaceObject.RangeControl, { 20344 label: (0,external_wp_i18n_namespaceObject.__)('Columns'), 20345 value: columnCount, 20346 onChange: value => onChange({ 20347 ...layout, 20348 columnCount: value 20349 }), 20350 min: 1, 20351 max: 6 20352 }); 20353 } 20354 20355 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/layouts/index.js 20356 /** 20357 * Internal dependencies 20358 */ 20359 20360 20361 20362 20363 const layoutTypes = [flow, flex, constrained, grid]; 20364 20365 /** 20366 * Retrieves a layout type by name. 20367 * 20368 * @param {string} name - The name of the layout type. 20369 * @return {Object} Layout type. 20370 */ 20371 function getLayoutType(name = 'default') { 20372 return layoutTypes.find(layoutType => layoutType.name === name); 20373 } 20374 20375 /** 20376 * Retrieves the available layout types. 20377 * 20378 * @return {Array} Layout types. 20379 */ 20380 function getLayoutTypes() { 20381 return layoutTypes; 20382 } 20383 20384 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/layout.js 20385 20386 /** 20387 * WordPress dependencies 20388 */ 20389 20390 20391 /** 20392 * Internal dependencies 20393 */ 20394 20395 20396 const defaultLayout = { 20397 type: 'default' 20398 }; 20399 const Layout = (0,external_wp_element_namespaceObject.createContext)(defaultLayout); 20400 20401 /** 20402 * Allows to define the layout. 20403 */ 20404 const LayoutProvider = Layout.Provider; 20405 20406 /** 20407 * React hook used to retrieve the layout config. 20408 */ 20409 function useLayout() { 20410 return (0,external_wp_element_namespaceObject.useContext)(Layout); 20411 } 20412 function LayoutStyle({ 20413 layout = {}, 20414 css, 20415 ...props 20416 }) { 20417 const layoutType = getLayoutType(layout.type); 20418 const [blockGapSupport] = use_settings_useSettings('spacing.blockGap'); 20419 const hasBlockGapSupport = blockGapSupport !== null; 20420 if (layoutType) { 20421 if (css) { 20422 return (0,external_React_.createElement)("style", null, css); 20423 } 20424 const layoutStyle = layoutType.getLayoutStyle?.({ 20425 hasBlockGapSupport, 20426 layout, 20427 ...props 20428 }); 20429 if (layoutStyle) { 20430 return (0,external_React_.createElement)("style", null, layoutStyle); 20431 } 20432 } 20433 return null; 20434 } 20435 20436 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-alignment-control/use-available-alignments.js 20437 /** 20438 * WordPress dependencies 20439 */ 20440 20441 20442 /** 20443 * Internal dependencies 20444 */ 20445 20446 20447 20448 const use_available_alignments_EMPTY_ARRAY = []; 20449 const use_available_alignments_DEFAULT_CONTROLS = ['none', 'left', 'center', 'right', 'wide', 'full']; 20450 const WIDE_CONTROLS = ['wide', 'full']; 20451 function useAvailableAlignments(controls = use_available_alignments_DEFAULT_CONTROLS) { 20452 // Always add the `none` option if not exists. 20453 if (!controls.includes('none')) { 20454 controls = ['none', ...controls]; 20455 } 20456 const isNoneOnly = controls.length === 1 && controls[0] === 'none'; 20457 const [wideControlsEnabled, themeSupportsLayout, isBlockBasedTheme] = (0,external_wp_data_namespaceObject.useSelect)(select => { 20458 var _settings$alignWide; 20459 // If `isNoneOnly` is true, we'll be returning early because there is 20460 // nothing to filter on an empty array. We won't need the info from 20461 // the `useSelect` but we must call it anyway because Rules of Hooks. 20462 // So the callback returns early to avoid block editor subscription. 20463 if (isNoneOnly) { 20464 return [false, false, false]; 20465 } 20466 const settings = select(store).getSettings(); 20467 return [(_settings$alignWide = settings.alignWide) !== null && _settings$alignWide !== void 0 ? _settings$alignWide : false, settings.supportsLayout, settings.__unstableIsBlockBasedTheme]; 20468 }, [isNoneOnly]); 20469 const layout = useLayout(); 20470 if (isNoneOnly) { 20471 return use_available_alignments_EMPTY_ARRAY; 20472 } 20473 const layoutType = getLayoutType(layout?.type); 20474 if (themeSupportsLayout) { 20475 const layoutAlignments = layoutType.getAlignments(layout, isBlockBasedTheme); 20476 const alignments = layoutAlignments.filter(alignment => controls.includes(alignment.name)); 20477 // While we treat `none` as an alignment, we shouldn't return it if no 20478 // other alignments exist. 20479 if (alignments.length === 1 && alignments[0].name === 'none') { 20480 return use_available_alignments_EMPTY_ARRAY; 20481 } 20482 return alignments; 20483 } 20484 20485 // Starting here, it's the fallback for themes not supporting the layout config. 20486 if (layoutType.name !== 'default' && layoutType.name !== 'constrained') { 20487 return use_available_alignments_EMPTY_ARRAY; 20488 } 20489 const alignments = controls.filter(control => { 20490 if (layout.alignments) { 20491 return layout.alignments.includes(control); 20492 } 20493 if (!wideControlsEnabled && WIDE_CONTROLS.includes(control)) { 20494 return false; 20495 } 20496 return use_available_alignments_DEFAULT_CONTROLS.includes(control); 20497 }).map(name => ({ 20498 name 20499 })); 20500 20501 // While we treat `none` as an alignment, we shouldn't return it if no 20502 // other alignments exist. 20503 if (alignments.length === 1 && alignments[0].name === 'none') { 20504 return use_available_alignments_EMPTY_ARRAY; 20505 } 20506 return alignments; 20507 } 20508 20509 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/align-none.js 20510 20511 /** 20512 * WordPress dependencies 20513 */ 20514 20515 const alignNone = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 20516 xmlns: "http://www.w3.org/2000/svg", 20517 viewBox: "0 0 24 24" 20518 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 20519 d: "M19 5.5H5V4h14v1.5ZM19 20H5v-1.5h14V20ZM5 9h14v6H5V9Z" 20520 })); 20521 /* harmony default export */ const align_none = (alignNone); 20522 20523 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/position-left.js 20524 20525 /** 20526 * WordPress dependencies 20527 */ 20528 20529 const positionLeft = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 20530 xmlns: "http://www.w3.org/2000/svg", 20531 viewBox: "0 0 24 24" 20532 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 20533 d: "M5 5.5h8V4H5v1.5ZM5 20h8v-1.5H5V20ZM19 9H5v6h14V9Z" 20534 })); 20535 /* harmony default export */ const position_left = (positionLeft); 20536 20537 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/position-right.js 20538 20539 /** 20540 * WordPress dependencies 20541 */ 20542 20543 const positionRight = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 20544 xmlns: "http://www.w3.org/2000/svg", 20545 viewBox: "0 0 24 24" 20546 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 20547 d: "M19 5.5h-8V4h8v1.5ZM19 20h-8v-1.5h8V20ZM5 9h14v6H5V9Z" 20548 })); 20549 /* harmony default export */ const position_right = (positionRight); 20550 20551 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/stretch-full-width.js 20552 20553 /** 20554 * WordPress dependencies 20555 */ 20556 20557 const stretchFullWidth = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 20558 xmlns: "http://www.w3.org/2000/svg", 20559 viewBox: "0 0 24 24" 20560 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 20561 d: "M5 4h14v11H5V4Zm11 16H8v-1.5h8V20Z" 20562 })); 20563 /* harmony default export */ const stretch_full_width = (stretchFullWidth); 20564 20565 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-alignment-control/constants.js 20566 /** 20567 * WordPress dependencies 20568 */ 20569 20570 20571 const constants_BLOCK_ALIGNMENTS_CONTROLS = { 20572 none: { 20573 icon: align_none, 20574 title: (0,external_wp_i18n_namespaceObject._x)('None', 'Alignment option') 20575 }, 20576 left: { 20577 icon: position_left, 20578 title: (0,external_wp_i18n_namespaceObject.__)('Align left') 20579 }, 20580 center: { 20581 icon: position_center, 20582 title: (0,external_wp_i18n_namespaceObject.__)('Align center') 20583 }, 20584 right: { 20585 icon: position_right, 20586 title: (0,external_wp_i18n_namespaceObject.__)('Align right') 20587 }, 20588 wide: { 20589 icon: stretch_wide, 20590 title: (0,external_wp_i18n_namespaceObject.__)('Wide width') 20591 }, 20592 full: { 20593 icon: stretch_full_width, 20594 title: (0,external_wp_i18n_namespaceObject.__)('Full width') 20595 } 20596 }; 20597 const constants_DEFAULT_CONTROL = 'none'; 20598 20599 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-alignment-control/ui.js 20600 20601 /** 20602 * External dependencies 20603 */ 20604 20605 20606 /** 20607 * WordPress dependencies 20608 */ 20609 20610 20611 20612 /** 20613 * Internal dependencies 20614 */ 20615 20616 20617 function BlockAlignmentUI({ 20618 value, 20619 onChange, 20620 controls, 20621 isToolbar, 20622 isCollapsed = true 20623 }) { 20624 const enabledControls = useAvailableAlignments(controls); 20625 const hasEnabledControls = !!enabledControls.length; 20626 if (!hasEnabledControls) { 20627 return null; 20628 } 20629 function onChangeAlignment(align) { 20630 onChange([value, 'none'].includes(align) ? undefined : align); 20631 } 20632 const activeAlignmentControl = constants_BLOCK_ALIGNMENTS_CONTROLS[value]; 20633 const defaultAlignmentControl = constants_BLOCK_ALIGNMENTS_CONTROLS[constants_DEFAULT_CONTROL]; 20634 const UIComponent = isToolbar ? external_wp_components_namespaceObject.ToolbarGroup : external_wp_components_namespaceObject.ToolbarDropdownMenu; 20635 const commonProps = { 20636 icon: activeAlignmentControl ? activeAlignmentControl.icon : defaultAlignmentControl.icon, 20637 label: (0,external_wp_i18n_namespaceObject.__)('Align') 20638 }; 20639 const extraProps = isToolbar ? { 20640 isCollapsed, 20641 controls: enabledControls.map(({ 20642 name: controlName 20643 }) => { 20644 return { 20645 ...constants_BLOCK_ALIGNMENTS_CONTROLS[controlName], 20646 isActive: value === controlName || !value && controlName === 'none', 20647 role: isCollapsed ? 'menuitemradio' : undefined, 20648 onClick: () => onChangeAlignment(controlName) 20649 }; 20650 }) 20651 } : { 20652 toggleProps: { 20653 describedBy: (0,external_wp_i18n_namespaceObject.__)('Change alignment') 20654 }, 20655 children: ({ 20656 onClose 20657 }) => { 20658 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuGroup, { 20659 className: "block-editor-block-alignment-control__menu-group" 20660 }, enabledControls.map(({ 20661 name: controlName, 20662 info 20663 }) => { 20664 const { 20665 icon, 20666 title 20667 } = constants_BLOCK_ALIGNMENTS_CONTROLS[controlName]; 20668 // If no value is provided, mark as selected the `none` option. 20669 const isSelected = controlName === value || !value && controlName === 'none'; 20670 return (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 20671 key: controlName, 20672 icon: icon, 20673 iconPosition: "left", 20674 className: classnames_default()('components-dropdown-menu__menu-item', { 20675 'is-active': isSelected 20676 }), 20677 isSelected: isSelected, 20678 onClick: () => { 20679 onChangeAlignment(controlName); 20680 onClose(); 20681 }, 20682 role: "menuitemradio", 20683 info: info 20684 }, title); 20685 }))); 20686 } 20687 }; 20688 return (0,external_React_.createElement)(UIComponent, { 20689 ...commonProps, 20690 ...extraProps 20691 }); 20692 } 20693 /* harmony default export */ const block_alignment_control_ui = (BlockAlignmentUI); 20694 20695 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-alignment-control/index.js 20696 20697 /** 20698 * Internal dependencies 20699 */ 20700 20701 const BlockAlignmentControl = props => { 20702 return (0,external_React_.createElement)(block_alignment_control_ui, { 20703 ...props, 20704 isToolbar: false 20705 }); 20706 }; 20707 const BlockAlignmentToolbar = props => { 20708 return (0,external_React_.createElement)(block_alignment_control_ui, { 20709 ...props, 20710 isToolbar: true 20711 }); 20712 }; 20713 20714 /** 20715 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-alignment-control/README.md 20716 */ 20717 20718 20719 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-editing-mode/index.js 20720 /** 20721 * WordPress dependencies 20722 */ 20723 20724 20725 20726 /** 20727 * Internal dependencies 20728 */ 20729 20730 20731 20732 /** 20733 * @typedef {'disabled'|'contentOnly'|'default'} BlockEditingMode 20734 */ 20735 20736 /** 20737 * Allows a block to restrict the user interface that is displayed for editing 20738 * that block and its inner blocks. 20739 * 20740 * @example 20741 * ```js 20742 * function MyBlock( { attributes, setAttributes } ) { 20743 * useBlockEditingMode( 'disabled' ); 20744 * return <div { ...useBlockProps() }></div>; 20745 * } 20746 * ``` 20747 * 20748 * `mode` can be one of three options: 20749 * 20750 * - `'disabled'`: Prevents editing the block entirely, i.e. it cannot be 20751 * selected. 20752 * - `'contentOnly'`: Hides all non-content UI, e.g. auxiliary controls in the 20753 * toolbar, the block movers, block settings. 20754 * - `'default'`: Allows editing the block as normal. 20755 * 20756 * The mode is inherited by all of the block's inner blocks, unless they have 20757 * their own mode. 20758 * 20759 * If called outside of a block context, the mode is applied to all blocks. 20760 * 20761 * @param {?BlockEditingMode} mode The editing mode to apply. If undefined, the 20762 * current editing mode is not changed. 20763 * 20764 * @return {BlockEditingMode} The current editing mode. 20765 */ 20766 function useBlockEditingMode(mode) { 20767 const context = useBlockEditContext(); 20768 const { 20769 clientId = '' 20770 } = context; 20771 const { 20772 setBlockEditingMode, 20773 unsetBlockEditingMode 20774 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 20775 const globalBlockEditingMode = (0,external_wp_data_namespaceObject.useSelect)(select => 20776 // Avoid adding the subscription if not needed! 20777 clientId ? null : select(store).getBlockEditingMode(), [clientId]); 20778 (0,external_wp_element_namespaceObject.useEffect)(() => { 20779 if (mode) { 20780 setBlockEditingMode(clientId, mode); 20781 } 20782 return () => { 20783 if (mode) { 20784 unsetBlockEditingMode(clientId); 20785 } 20786 }; 20787 }, [clientId, mode, setBlockEditingMode, unsetBlockEditingMode]); 20788 return clientId ? context[blockEditingModeKey] : globalBlockEditingMode; 20789 } 20790 20791 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/align.js 20792 20793 /** 20794 * External dependencies 20795 */ 20796 20797 20798 /** 20799 * WordPress dependencies 20800 */ 20801 20802 20803 20804 /** 20805 * Internal dependencies 20806 */ 20807 20808 20809 20810 20811 /** 20812 * An array which includes all possible valid alignments, 20813 * used to validate if an alignment is valid or not. 20814 * 20815 * @constant 20816 * @type {string[]} 20817 */ 20818 const ALL_ALIGNMENTS = ['left', 'center', 'right', 'wide', 'full']; 20819 20820 /** 20821 * An array which includes all wide alignments. 20822 * In order for this alignments to be valid they need to be supported by the block, 20823 * and by the theme. 20824 * 20825 * @constant 20826 * @type {string[]} 20827 */ 20828 const WIDE_ALIGNMENTS = ['wide', 'full']; 20829 20830 /** 20831 * Returns the valid alignments. 20832 * Takes into consideration the aligns supported by a block, if the block supports wide controls or not and if theme supports wide controls or not. 20833 * Exported just for testing purposes, not exported outside the module. 20834 * 20835 * @param {?boolean|string[]} blockAlign Aligns supported by the block. 20836 * @param {?boolean} hasWideBlockSupport True if block supports wide alignments. And False otherwise. 20837 * @param {?boolean} hasWideEnabled True if theme supports wide alignments. And False otherwise. 20838 * 20839 * @return {string[]} Valid alignments. 20840 */ 20841 function getValidAlignments(blockAlign, hasWideBlockSupport = true, hasWideEnabled = true) { 20842 let validAlignments; 20843 if (Array.isArray(blockAlign)) { 20844 validAlignments = ALL_ALIGNMENTS.filter(value => blockAlign.includes(value)); 20845 } else if (blockAlign === true) { 20846 // `true` includes all alignments... 20847 validAlignments = [...ALL_ALIGNMENTS]; 20848 } else { 20849 validAlignments = []; 20850 } 20851 if (!hasWideEnabled || blockAlign === true && !hasWideBlockSupport) { 20852 return validAlignments.filter(alignment => !WIDE_ALIGNMENTS.includes(alignment)); 20853 } 20854 return validAlignments; 20855 } 20856 20857 /** 20858 * Filters registered block settings, extending attributes to include `align`. 20859 * 20860 * @param {Object} settings Original block settings. 20861 * 20862 * @return {Object} Filtered block settings. 20863 */ 20864 function addAttribute(settings) { 20865 var _settings$attributes$; 20866 // Allow blocks to specify their own attribute definition with default values if needed. 20867 if ('type' in ((_settings$attributes$ = settings.attributes?.align) !== null && _settings$attributes$ !== void 0 ? _settings$attributes$ : {})) { 20868 return settings; 20869 } 20870 if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(settings, 'align')) { 20871 // Gracefully handle if settings.attributes is undefined. 20872 settings.attributes = { 20873 ...settings.attributes, 20874 align: { 20875 type: 'string', 20876 // Allow for '' since it is used by the `updateAlignment` function 20877 // in toolbar controls for special cases with defined default values. 20878 enum: [...ALL_ALIGNMENTS, ''] 20879 } 20880 }; 20881 } 20882 return settings; 20883 } 20884 function BlockEditAlignmentToolbarControlsPure({ 20885 name: blockName, 20886 align, 20887 setAttributes 20888 }) { 20889 // Compute the block valid alignments by taking into account, 20890 // if the theme supports wide alignments or not and the layout's 20891 // available alignments. We do that for conditionally rendering 20892 // Slot. 20893 const blockAllowedAlignments = getValidAlignments((0,external_wp_blocks_namespaceObject.getBlockSupport)(blockName, 'align'), (0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockName, 'alignWide', true)); 20894 const validAlignments = useAvailableAlignments(blockAllowedAlignments).map(({ 20895 name 20896 }) => name); 20897 const blockEditingMode = useBlockEditingMode(); 20898 if (!validAlignments.length || blockEditingMode !== 'default') { 20899 return null; 20900 } 20901 const updateAlignment = nextAlign => { 20902 if (!nextAlign) { 20903 const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockName); 20904 const blockDefaultAlign = blockType?.attributes?.align?.default; 20905 if (blockDefaultAlign) { 20906 nextAlign = ''; 20907 } 20908 } 20909 setAttributes({ 20910 align: nextAlign 20911 }); 20912 }; 20913 return (0,external_React_.createElement)(block_controls, { 20914 group: "block", 20915 __experimentalShareWithChildBlocks: true 20916 }, (0,external_React_.createElement)(BlockAlignmentControl, { 20917 value: align, 20918 onChange: updateAlignment, 20919 controls: validAlignments 20920 })); 20921 } 20922 /* harmony default export */ const align = ({ 20923 shareWithChildBlocks: true, 20924 edit: BlockEditAlignmentToolbarControlsPure, 20925 useBlockProps, 20926 addSaveProps: addAssignedAlign, 20927 attributeKeys: ['align'], 20928 hasSupport(name) { 20929 return (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, 'align', false); 20930 } 20931 }); 20932 function useBlockProps({ 20933 name, 20934 align 20935 }) { 20936 const blockAllowedAlignments = getValidAlignments((0,external_wp_blocks_namespaceObject.getBlockSupport)(name, 'align'), (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, 'alignWide', true)); 20937 const validAlignments = useAvailableAlignments(blockAllowedAlignments); 20938 if (validAlignments.some(alignment => alignment.name === align)) { 20939 return { 20940 'data-align': align 20941 }; 20942 } 20943 return {}; 20944 } 20945 20946 /** 20947 * Override props assigned to save component to inject alignment class name if 20948 * block supports it. 20949 * 20950 * @param {Object} props Additional props applied to save element. 20951 * @param {Object} blockType Block type. 20952 * @param {Object} attributes Block attributes. 20953 * 20954 * @return {Object} Filtered props applied to save element. 20955 */ 20956 function addAssignedAlign(props, blockType, attributes) { 20957 const { 20958 align 20959 } = attributes; 20960 const blockAlign = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockType, 'align'); 20961 const hasWideBlockSupport = (0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, 'alignWide', true); 20962 20963 // Compute valid alignments without taking into account if 20964 // the theme supports wide alignments or not. 20965 // This way changing themes does not impact the block save. 20966 const isAlignValid = getValidAlignments(blockAlign, hasWideBlockSupport).includes(align); 20967 if (isAlignValid) { 20968 props.className = classnames_default()(`align$align}`, props.className); 20969 } 20970 return props; 20971 } 20972 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/editor/align/addAttribute', addAttribute); 20973 20974 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/lock.js 20975 /** 20976 * WordPress dependencies 20977 */ 20978 20979 20980 /** 20981 * Filters registered block settings, extending attributes to include `lock`. 20982 * 20983 * @param {Object} settings Original block settings. 20984 * 20985 * @return {Object} Filtered block settings. 20986 */ 20987 function lock_addAttribute(settings) { 20988 var _settings$attributes$; 20989 // Allow blocks to specify their own attribute definition with default values if needed. 20990 if ('type' in ((_settings$attributes$ = settings.attributes?.lock) !== null && _settings$attributes$ !== void 0 ? _settings$attributes$ : {})) { 20991 return settings; 20992 } 20993 // Gracefully handle if settings.attributes is undefined. 20994 settings.attributes = { 20995 ...settings.attributes, 20996 lock: { 20997 type: 'object' 20998 } 20999 }; 21000 return settings; 21001 } 21002 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/lock/addAttribute', lock_addAttribute); 21003 21004 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls/groups.js 21005 /** 21006 * WordPress dependencies 21007 */ 21008 21009 const InspectorControlsDefault = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControls'); 21010 const InspectorControlsAdvanced = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorAdvancedControls'); 21011 const InspectorControlsBackground = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsBackground'); 21012 const InspectorControlsBorder = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsBorder'); 21013 const InspectorControlsColor = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsColor'); 21014 const InspectorControlsFilter = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsFilter'); 21015 const InspectorControlsDimensions = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsDimensions'); 21016 const InspectorControlsPosition = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsPosition'); 21017 const InspectorControlsTypography = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsTypography'); 21018 const InspectorControlsListView = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsListView'); 21019 const InspectorControlsStyles = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsStyles'); 21020 const InspectorControlsEffects = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsEffects'); 21021 const groups_groups = { 21022 default: InspectorControlsDefault, 21023 advanced: InspectorControlsAdvanced, 21024 background: InspectorControlsBackground, 21025 border: InspectorControlsBorder, 21026 color: InspectorControlsColor, 21027 dimensions: InspectorControlsDimensions, 21028 effects: InspectorControlsEffects, 21029 filter: InspectorControlsFilter, 21030 list: InspectorControlsListView, 21031 position: InspectorControlsPosition, 21032 settings: InspectorControlsDefault, 21033 // Alias for default. 21034 styles: InspectorControlsStyles, 21035 typography: InspectorControlsTypography 21036 }; 21037 /* harmony default export */ const inspector_controls_groups = (groups_groups); 21038 21039 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls/fill.js 21040 21041 /** 21042 * WordPress dependencies 21043 */ 21044 21045 21046 21047 21048 21049 /** 21050 * Internal dependencies 21051 */ 21052 21053 21054 function InspectorControlsFill({ 21055 children, 21056 group = 'default', 21057 __experimentalGroup, 21058 resetAllFilter 21059 }) { 21060 if (__experimentalGroup) { 21061 external_wp_deprecated_default()('`__experimentalGroup` property in `InspectorControlsFill`', { 21062 since: '6.2', 21063 version: '6.4', 21064 alternative: '`group`' 21065 }); 21066 group = __experimentalGroup; 21067 } 21068 const context = useBlockEditContext(); 21069 const Fill = inspector_controls_groups[group]?.Fill; 21070 if (!Fill) { 21071 true ? external_wp_warning_default()(`Unknown InspectorControls group "$group}" provided.`) : 0; 21072 return null; 21073 } 21074 if (!context[mayDisplayControlsKey]) { 21075 return null; 21076 } 21077 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalStyleProvider, { 21078 document: document 21079 }, (0,external_React_.createElement)(Fill, null, fillProps => { 21080 return (0,external_React_.createElement)(ToolsPanelInspectorControl, { 21081 fillProps: fillProps, 21082 children: children, 21083 resetAllFilter: resetAllFilter 21084 }); 21085 })); 21086 } 21087 function RegisterResetAll({ 21088 resetAllFilter, 21089 children 21090 }) { 21091 const { 21092 registerResetAllFilter, 21093 deregisterResetAllFilter 21094 } = (0,external_wp_element_namespaceObject.useContext)(external_wp_components_namespaceObject.__experimentalToolsPanelContext); 21095 (0,external_wp_element_namespaceObject.useEffect)(() => { 21096 if (resetAllFilter && registerResetAllFilter && deregisterResetAllFilter) { 21097 registerResetAllFilter(resetAllFilter); 21098 return () => { 21099 deregisterResetAllFilter(resetAllFilter); 21100 }; 21101 } 21102 }, [resetAllFilter, registerResetAllFilter, deregisterResetAllFilter]); 21103 return children; 21104 } 21105 function ToolsPanelInspectorControl({ 21106 children, 21107 resetAllFilter, 21108 fillProps 21109 }) { 21110 // `fillProps.forwardedContext` is an array of context provider entries, provided by slot, 21111 // that should wrap the fill markup. 21112 const { 21113 forwardedContext = [] 21114 } = fillProps; 21115 21116 // Children passed to InspectorControlsFill will not have 21117 // access to any React Context whose Provider is part of 21118 // the InspectorControlsSlot tree. So we re-create the 21119 // Provider in this subtree. 21120 const innerMarkup = (0,external_React_.createElement)(RegisterResetAll, { 21121 resetAllFilter: resetAllFilter 21122 }, children); 21123 return forwardedContext.reduce((inner, [Provider, props]) => (0,external_React_.createElement)(Provider, { 21124 ...props 21125 }, inner), innerMarkup); 21126 } 21127 21128 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls/block-support-tools-panel.js 21129 21130 /** 21131 * WordPress dependencies 21132 */ 21133 21134 21135 21136 21137 /** 21138 * Internal dependencies 21139 */ 21140 21141 21142 21143 function BlockSupportToolsPanel({ 21144 children, 21145 group, 21146 label 21147 }) { 21148 const { 21149 updateBlockAttributes 21150 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 21151 const { 21152 getBlockAttributes, 21153 getMultiSelectedBlockClientIds, 21154 getSelectedBlockClientId, 21155 hasMultiSelection 21156 } = (0,external_wp_data_namespaceObject.useSelect)(store); 21157 const panelId = getSelectedBlockClientId(); 21158 const resetAll = (0,external_wp_element_namespaceObject.useCallback)((resetFilters = []) => { 21159 const newAttributes = {}; 21160 const clientIds = hasMultiSelection() ? getMultiSelectedBlockClientIds() : [panelId]; 21161 clientIds.forEach(clientId => { 21162 const { 21163 style 21164 } = getBlockAttributes(clientId); 21165 let newBlockAttributes = { 21166 style 21167 }; 21168 resetFilters.forEach(resetFilter => { 21169 newBlockAttributes = { 21170 ...newBlockAttributes, 21171 ...resetFilter(newBlockAttributes) 21172 }; 21173 }); 21174 21175 // Enforce a cleaned style object. 21176 newBlockAttributes = { 21177 ...newBlockAttributes, 21178 style: utils_cleanEmptyObject(newBlockAttributes.style) 21179 }; 21180 newAttributes[clientId] = newBlockAttributes; 21181 }); 21182 updateBlockAttributes(clientIds, newAttributes, true); 21183 }, [getBlockAttributes, getMultiSelectedBlockClientIds, hasMultiSelection, panelId, updateBlockAttributes]); 21184 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanel, { 21185 className: `$group}-block-support-panel`, 21186 label: label, 21187 resetAll: resetAll, 21188 key: panelId, 21189 panelId: panelId, 21190 hasInnerWrapper: true, 21191 shouldRenderPlaceholderItems: true // Required to maintain fills ordering. 21192 , 21193 __experimentalFirstVisibleItemClass: "first", 21194 __experimentalLastVisibleItemClass: "last", 21195 dropdownMenuProps: TOOLSPANEL_DROPDOWNMENU_PROPS 21196 }, children); 21197 } 21198 21199 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls/block-support-slot-container.js 21200 21201 /** 21202 * WordPress dependencies 21203 */ 21204 21205 21206 function BlockSupportSlotContainer({ 21207 Slot, 21208 fillProps, 21209 ...props 21210 }) { 21211 // Add the toolspanel context provider and value to existing fill props 21212 const toolsPanelContext = (0,external_wp_element_namespaceObject.useContext)(external_wp_components_namespaceObject.__experimentalToolsPanelContext); 21213 const computedFillProps = (0,external_wp_element_namespaceObject.useMemo)(() => { 21214 var _fillProps$forwardedC; 21215 return { 21216 ...(fillProps !== null && fillProps !== void 0 ? fillProps : {}), 21217 forwardedContext: [...((_fillProps$forwardedC = fillProps?.forwardedContext) !== null && _fillProps$forwardedC !== void 0 ? _fillProps$forwardedC : []), [external_wp_components_namespaceObject.__experimentalToolsPanelContext.Provider, { 21218 value: toolsPanelContext 21219 }]] 21220 }; 21221 }, [toolsPanelContext, fillProps]); 21222 return (0,external_React_.createElement)(Slot, { 21223 ...props, 21224 fillProps: computedFillProps, 21225 bubblesVirtually: true 21226 }); 21227 } 21228 21229 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls/slot.js 21230 21231 /** 21232 * WordPress dependencies 21233 */ 21234 21235 21236 21237 21238 21239 /** 21240 * Internal dependencies 21241 */ 21242 21243 21244 21245 function InspectorControlsSlot({ 21246 __experimentalGroup, 21247 group = 'default', 21248 label, 21249 fillProps, 21250 ...props 21251 }) { 21252 if (__experimentalGroup) { 21253 external_wp_deprecated_default()('`__experimentalGroup` property in `InspectorControlsSlot`', { 21254 since: '6.2', 21255 version: '6.4', 21256 alternative: '`group`' 21257 }); 21258 group = __experimentalGroup; 21259 } 21260 const Slot = inspector_controls_groups[group]?.Slot; 21261 const fills = (0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(Slot?.__unstableName); 21262 const motionContextValue = (0,external_wp_element_namespaceObject.useContext)(external_wp_components_namespaceObject.__unstableMotionContext); 21263 const computedFillProps = (0,external_wp_element_namespaceObject.useMemo)(() => { 21264 var _fillProps$forwardedC; 21265 return { 21266 ...(fillProps !== null && fillProps !== void 0 ? fillProps : {}), 21267 forwardedContext: [...((_fillProps$forwardedC = fillProps?.forwardedContext) !== null && _fillProps$forwardedC !== void 0 ? _fillProps$forwardedC : []), [external_wp_components_namespaceObject.__unstableMotionContext.Provider, { 21268 value: motionContextValue 21269 }]] 21270 }; 21271 }, [motionContextValue, fillProps]); 21272 if (!Slot) { 21273 true ? external_wp_warning_default()(`Unknown InspectorControls group "$group}" provided.`) : 0; 21274 return null; 21275 } 21276 if (!fills?.length) { 21277 return null; 21278 } 21279 if (label) { 21280 return (0,external_React_.createElement)(BlockSupportToolsPanel, { 21281 group: group, 21282 label: label 21283 }, (0,external_React_.createElement)(BlockSupportSlotContainer, { 21284 ...props, 21285 fillProps: computedFillProps, 21286 Slot: Slot 21287 })); 21288 } 21289 return (0,external_React_.createElement)(Slot, { 21290 ...props, 21291 fillProps: computedFillProps, 21292 bubblesVirtually: true 21293 }); 21294 } 21295 21296 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls/index.js 21297 21298 /** 21299 * Internal dependencies 21300 */ 21301 21302 21303 const InspectorControls = InspectorControlsFill; 21304 InspectorControls.Slot = InspectorControlsSlot; 21305 21306 // This is just here for backward compatibility. 21307 const InspectorAdvancedControls = props => { 21308 return (0,external_React_.createElement)(InspectorControlsFill, { 21309 ...props, 21310 group: "advanced" 21311 }); 21312 }; 21313 InspectorAdvancedControls.Slot = props => { 21314 return (0,external_React_.createElement)(InspectorControlsSlot, { 21315 ...props, 21316 group: "advanced" 21317 }); 21318 }; 21319 InspectorAdvancedControls.slotName = 'InspectorAdvancedControls'; 21320 21321 /** 21322 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/inspector-controls/README.md 21323 */ 21324 /* harmony default export */ const inspector_controls = (InspectorControls); 21325 21326 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/anchor.js 21327 21328 /** 21329 * WordPress dependencies 21330 */ 21331 21332 21333 21334 21335 21336 21337 /** 21338 * Internal dependencies 21339 */ 21340 21341 21342 21343 /** 21344 * Regular expression matching invalid anchor characters for replacement. 21345 * 21346 * @type {RegExp} 21347 */ 21348 const ANCHOR_REGEX = /[\s#]/g; 21349 const ANCHOR_SCHEMA = { 21350 type: 'string', 21351 source: 'attribute', 21352 attribute: 'id', 21353 selector: '*' 21354 }; 21355 21356 /** 21357 * Filters registered block settings, extending attributes with anchor using ID 21358 * of the first node. 21359 * 21360 * @param {Object} settings Original block settings. 21361 * 21362 * @return {Object} Filtered block settings. 21363 */ 21364 function anchor_addAttribute(settings) { 21365 var _settings$attributes$; 21366 // Allow blocks to specify their own attribute definition with default values if needed. 21367 if ('type' in ((_settings$attributes$ = settings.attributes?.anchor) !== null && _settings$attributes$ !== void 0 ? _settings$attributes$ : {})) { 21368 return settings; 21369 } 21370 if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(settings, 'anchor')) { 21371 // Gracefully handle if settings.attributes is undefined. 21372 settings.attributes = { 21373 ...settings.attributes, 21374 anchor: ANCHOR_SCHEMA 21375 }; 21376 } 21377 return settings; 21378 } 21379 function BlockEditAnchorControlPure({ 21380 name: blockName, 21381 anchor, 21382 setAttributes 21383 }) { 21384 const blockEditingMode = useBlockEditingMode(); 21385 const isWeb = external_wp_element_namespaceObject.Platform.OS === 'web'; 21386 const textControl = (0,external_React_.createElement)(external_wp_components_namespaceObject.TextControl, { 21387 __nextHasNoMarginBottom: true, 21388 __next40pxDefaultSize: true, 21389 className: "html-anchor-control", 21390 label: (0,external_wp_i18n_namespaceObject.__)('HTML anchor'), 21391 help: (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_wp_i18n_namespaceObject.__)('Enter a word or two — without spaces — to make a unique web address just for this block, called an “anchor.” Then, you’ll be able to link directly to this section of your page.'), isWeb && (0,external_React_.createElement)(external_wp_components_namespaceObject.ExternalLink, { 21392 href: (0,external_wp_i18n_namespaceObject.__)('https://wordpress.org/documentation/article/page-jumps/') 21393 }, (0,external_wp_i18n_namespaceObject.__)('Learn more about anchors'))), 21394 value: anchor || '', 21395 placeholder: !isWeb ? (0,external_wp_i18n_namespaceObject.__)('Add an anchor') : null, 21396 onChange: nextValue => { 21397 nextValue = nextValue.replace(ANCHOR_REGEX, '-'); 21398 setAttributes({ 21399 anchor: nextValue 21400 }); 21401 }, 21402 autoCapitalize: "none", 21403 autoComplete: "off" 21404 }); 21405 return (0,external_React_.createElement)(external_React_.Fragment, null, isWeb && blockEditingMode === 'default' && (0,external_React_.createElement)(inspector_controls, { 21406 group: "advanced" 21407 }, textControl), !isWeb && blockName === 'core/heading' && (0,external_React_.createElement)(inspector_controls, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.PanelBody, { 21408 title: (0,external_wp_i18n_namespaceObject.__)('Heading settings') 21409 }, textControl))); 21410 } 21411 /* harmony default export */ const hooks_anchor = ({ 21412 addSaveProps, 21413 edit: BlockEditAnchorControlPure, 21414 attributeKeys: ['anchor'], 21415 hasSupport(name) { 21416 return (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, 'anchor'); 21417 } 21418 }); 21419 21420 /** 21421 * Override props assigned to save component to inject anchor ID, if block 21422 * supports anchor. This is only applied if the block's save result is an 21423 * element and not a markup string. 21424 * 21425 * @param {Object} extraProps Additional props applied to save element. 21426 * @param {Object} blockType Block type. 21427 * @param {Object} attributes Current block attributes. 21428 * 21429 * @return {Object} Filtered props applied to save element. 21430 */ 21431 function addSaveProps(extraProps, blockType, attributes) { 21432 if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, 'anchor')) { 21433 extraProps.id = attributes.anchor === '' ? null : attributes.anchor; 21434 } 21435 return extraProps; 21436 } 21437 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/anchor/attribute', anchor_addAttribute); 21438 21439 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/aria-label.js 21440 /** 21441 * WordPress dependencies 21442 */ 21443 21444 21445 const ARIA_LABEL_SCHEMA = { 21446 type: 'string', 21447 source: 'attribute', 21448 attribute: 'aria-label', 21449 selector: '*' 21450 }; 21451 21452 /** 21453 * Filters registered block settings, extending attributes with ariaLabel using aria-label 21454 * of the first node. 21455 * 21456 * @param {Object} settings Original block settings. 21457 * 21458 * @return {Object} Filtered block settings. 21459 */ 21460 function aria_label_addAttribute(settings) { 21461 // Allow blocks to specify their own attribute definition with default values if needed. 21462 if (settings?.attributes?.ariaLabel?.type) { 21463 return settings; 21464 } 21465 if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(settings, 'ariaLabel')) { 21466 // Gracefully handle if settings.attributes is undefined. 21467 settings.attributes = { 21468 ...settings.attributes, 21469 ariaLabel: ARIA_LABEL_SCHEMA 21470 }; 21471 } 21472 return settings; 21473 } 21474 21475 /** 21476 * Override props assigned to save component to inject aria-label, if block 21477 * supports ariaLabel. This is only applied if the block's save result is an 21478 * element and not a markup string. 21479 * 21480 * @param {Object} extraProps Additional props applied to save element. 21481 * @param {Object} blockType Block type. 21482 * @param {Object} attributes Current block attributes. 21483 * 21484 * @return {Object} Filtered props applied to save element. 21485 */ 21486 function aria_label_addSaveProps(extraProps, blockType, attributes) { 21487 if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, 'ariaLabel')) { 21488 extraProps['aria-label'] = attributes.ariaLabel === '' ? null : attributes.ariaLabel; 21489 } 21490 return extraProps; 21491 } 21492 /* harmony default export */ const aria_label = ({ 21493 addSaveProps: aria_label_addSaveProps, 21494 attributeKeys: ['ariaLabel'], 21495 hasSupport(name) { 21496 return (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, 'ariaLabel'); 21497 } 21498 }); 21499 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/ariaLabel/attribute', aria_label_addAttribute); 21500 21501 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/custom-class-name.js 21502 21503 /** 21504 * External dependencies 21505 */ 21506 21507 21508 /** 21509 * WordPress dependencies 21510 */ 21511 21512 21513 21514 21515 21516 /** 21517 * Internal dependencies 21518 */ 21519 21520 21521 21522 /** 21523 * Filters registered block settings, extending attributes to include `className`. 21524 * 21525 * @param {Object} settings Original block settings. 21526 * 21527 * @return {Object} Filtered block settings. 21528 */ 21529 function custom_class_name_addAttribute(settings) { 21530 if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(settings, 'customClassName', true)) { 21531 // Gracefully handle if settings.attributes is undefined. 21532 settings.attributes = { 21533 ...settings.attributes, 21534 className: { 21535 type: 'string' 21536 } 21537 }; 21538 } 21539 return settings; 21540 } 21541 function CustomClassNameControlsPure({ 21542 className, 21543 setAttributes 21544 }) { 21545 const blockEditingMode = useBlockEditingMode(); 21546 if (blockEditingMode !== 'default') { 21547 return null; 21548 } 21549 return (0,external_React_.createElement)(inspector_controls, { 21550 group: "advanced" 21551 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.TextControl, { 21552 __nextHasNoMarginBottom: true, 21553 __next40pxDefaultSize: true, 21554 autoComplete: "off", 21555 label: (0,external_wp_i18n_namespaceObject.__)('Additional CSS class(es)'), 21556 value: className || '', 21557 onChange: nextValue => { 21558 setAttributes({ 21559 className: nextValue !== '' ? nextValue : undefined 21560 }); 21561 }, 21562 help: (0,external_wp_i18n_namespaceObject.__)('Separate multiple classes with spaces.') 21563 })); 21564 } 21565 /* harmony default export */ const custom_class_name = ({ 21566 edit: CustomClassNameControlsPure, 21567 addSaveProps: custom_class_name_addSaveProps, 21568 attributeKeys: ['className'], 21569 hasSupport(name) { 21570 return (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, 'customClassName', true); 21571 } 21572 }); 21573 21574 /** 21575 * Override props assigned to save component to inject the className, if block 21576 * supports customClassName. This is only applied if the block's save result is an 21577 * element and not a markup string. 21578 * 21579 * @param {Object} extraProps Additional props applied to save element. 21580 * @param {Object} blockType Block type. 21581 * @param {Object} attributes Current block attributes. 21582 * 21583 * @return {Object} Filtered props applied to save element. 21584 */ 21585 function custom_class_name_addSaveProps(extraProps, blockType, attributes) { 21586 if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, 'customClassName', true) && attributes.className) { 21587 extraProps.className = classnames_default()(extraProps.className, attributes.className); 21588 } 21589 return extraProps; 21590 } 21591 function addTransforms(result, source, index, results) { 21592 if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(result.name, 'customClassName', true)) { 21593 return result; 21594 } 21595 21596 // If the condition verifies we are probably in the presence of a wrapping transform 21597 // e.g: nesting paragraphs in a group or columns and in that case the class should not be kept. 21598 if (results.length === 1 && result.innerBlocks.length === source.length) { 21599 return result; 21600 } 21601 21602 // If we are transforming one block to multiple blocks or multiple blocks to one block, 21603 // we ignore the class during the transform. 21604 if (results.length === 1 && source.length > 1 || results.length > 1 && source.length === 1) { 21605 return result; 21606 } 21607 21608 // If we are in presence of transform between one or more block in the source 21609 // that have one or more blocks in the result 21610 // we apply the class on source N to the result N, 21611 // if source N does not exists we do nothing. 21612 if (source[index]) { 21613 const originClassName = source[index]?.attributes.className; 21614 if (originClassName) { 21615 return { 21616 ...result, 21617 attributes: { 21618 ...result.attributes, 21619 className: originClassName 21620 } 21621 }; 21622 } 21623 } 21624 return result; 21625 } 21626 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/editor/custom-class-name/attribute', custom_class_name_addAttribute); 21627 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.switchToBlockType.transformedBlock', 'core/color/addTransforms', addTransforms); 21628 21629 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/generated-class-name.js 21630 /** 21631 * WordPress dependencies 21632 */ 21633 21634 21635 21636 /** 21637 * Override props assigned to save component to inject generated className if 21638 * block supports it. This is only applied if the block's save result is an 21639 * element and not a markup string. 21640 * 21641 * @param {Object} extraProps Additional props applied to save element. 21642 * @param {Object} blockType Block type. 21643 * 21644 * @return {Object} Filtered props applied to save element. 21645 */ 21646 function addGeneratedClassName(extraProps, blockType) { 21647 // Adding the generated className. 21648 if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, 'className', true)) { 21649 if (typeof extraProps.className === 'string') { 21650 // We have some extra classes and want to add the default classname 21651 // We use uniq to prevent duplicate classnames. 21652 21653 extraProps.className = [...new Set([(0,external_wp_blocks_namespaceObject.getBlockDefaultClassName)(blockType.name), ...extraProps.className.split(' ')])].join(' ').trim(); 21654 } else { 21655 // There is no string in the className variable, 21656 // so we just dump the default name in there. 21657 extraProps.className = (0,external_wp_blocks_namespaceObject.getBlockDefaultClassName)(blockType.name); 21658 } 21659 } 21660 return extraProps; 21661 } 21662 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.getSaveContent.extraProps', 'core/generated-class-name/save-props', addGeneratedClassName); 21663 21664 ;// CONCATENATED MODULE: external ["wp","blob"] 21665 const external_wp_blob_namespaceObject = window["wp"]["blob"]; 21666 ;// CONCATENATED MODULE: external ["wp","dom"] 21667 const external_wp_dom_namespaceObject = window["wp"]["dom"]; 21668 ;// CONCATENATED MODULE: external ["wp","notices"] 21669 const external_wp_notices_namespaceObject = window["wp"]["notices"]; 21670 ;// CONCATENATED MODULE: external ["wp","url"] 21671 const external_wp_url_namespaceObject = window["wp"]["url"]; 21672 ;// CONCATENATED MODULE: external ["wp","keycodes"] 21673 const external_wp_keycodes_namespaceObject = window["wp"]["keycodes"]; 21674 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/media.js 21675 21676 /** 21677 * WordPress dependencies 21678 */ 21679 21680 const media = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 21681 xmlns: "http://www.w3.org/2000/svg", 21682 viewBox: "0 0 24 24" 21683 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 21684 d: "m7 6.5 4 2.5-4 2.5z" 21685 }), (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 21686 fillRule: "evenodd", 21687 clipRule: "evenodd", 21688 d: "m5 3c-1.10457 0-2 .89543-2 2v14c0 1.1046.89543 2 2 2h14c1.1046 0 2-.8954 2-2v-14c0-1.10457-.8954-2-2-2zm14 1.5h-14c-.27614 0-.5.22386-.5.5v10.7072l3.62953-2.6465c.25108-.1831.58905-.1924.84981-.0234l2.92666 1.8969 3.5712-3.4719c.2911-.2831.7545-.2831 1.0456 0l2.9772 2.8945v-9.3568c0-.27614-.2239-.5-.5-.5zm-14.5 14.5v-1.4364l4.09643-2.987 2.99567 1.9417c.2936.1903.6798.1523.9307-.0917l3.4772-3.3806 3.4772 3.3806.0228-.0234v2.5968c0 .2761-.2239.5-.5.5h-14c-.27614 0-.5-.2239-.5-.5z" 21689 })); 21690 /* harmony default export */ const library_media = (media); 21691 21692 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/upload.js 21693 21694 /** 21695 * WordPress dependencies 21696 */ 21697 21698 const upload = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 21699 xmlns: "http://www.w3.org/2000/svg", 21700 viewBox: "0 0 24 24" 21701 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 21702 d: "M18.5 15v3.5H13V6.7l4.5 4.1 1-1.1-6.2-5.8-5.8 5.8 1 1.1 4-4v11.7h-6V15H4v5h16v-5z" 21703 })); 21704 /* harmony default export */ const library_upload = (upload); 21705 21706 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/post-featured-image.js 21707 21708 /** 21709 * WordPress dependencies 21710 */ 21711 21712 const postFeaturedImage = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 21713 xmlns: "http://www.w3.org/2000/svg", 21714 viewBox: "0 0 24 24" 21715 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 21716 d: "M19 3H5c-.6 0-1 .4-1 1v7c0 .5.4 1 1 1h14c.5 0 1-.4 1-1V4c0-.6-.4-1-1-1zM5.5 10.5v-.4l1.8-1.3 1.3.8c.3.2.7.2.9-.1L11 8.1l2.4 2.4H5.5zm13 0h-2.9l-4-4c-.3-.3-.8-.3-1.1 0L8.9 8l-1.2-.8c-.3-.2-.6-.2-.9 0l-1.3 1V4.5h13v6zM4 20h9v-1.5H4V20zm0-4h16v-1.5H4V16z" 21717 })); 21718 /* harmony default export */ const post_featured_image = (postFeaturedImage); 21719 21720 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/media-upload/index.js 21721 /** 21722 * WordPress dependencies 21723 */ 21724 21725 21726 /** 21727 * This is a placeholder for the media upload component necessary to make it possible to provide 21728 * an integration with the core blocks that handle media files. By default it renders nothing but 21729 * it provides a way to have it overridden with the `editor.MediaUpload` filter. 21730 * 21731 * @return {Component} The component to be rendered. 21732 */ 21733 const MediaUpload = () => null; 21734 21735 /** 21736 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/media-upload/README.md 21737 */ 21738 /* harmony default export */ const media_upload = ((0,external_wp_components_namespaceObject.withFilters)('editor.MediaUpload')(MediaUpload)); 21739 21740 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/media-upload/check.js 21741 /** 21742 * WordPress dependencies 21743 */ 21744 21745 21746 /** 21747 * Internal dependencies 21748 */ 21749 21750 function MediaUploadCheck({ 21751 fallback = null, 21752 children 21753 }) { 21754 const hasUploadPermissions = (0,external_wp_data_namespaceObject.useSelect)(select => { 21755 const { 21756 getSettings 21757 } = select(store); 21758 return !!getSettings().mediaUpload; 21759 }, []); 21760 return hasUploadPermissions ? children : fallback; 21761 } 21762 21763 /** 21764 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/media-upload/README.md 21765 */ 21766 /* harmony default export */ const check = (MediaUploadCheck); 21767 21768 ;// CONCATENATED MODULE: external ["wp","isShallowEqual"] 21769 const external_wp_isShallowEqual_namespaceObject = window["wp"]["isShallowEqual"]; 21770 var external_wp_isShallowEqual_default = /*#__PURE__*/__webpack_require__.n(external_wp_isShallowEqual_namespaceObject); 21771 ;// CONCATENATED MODULE: external ["wp","preferences"] 21772 const external_wp_preferences_namespaceObject = window["wp"]["preferences"]; 21773 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/keyboard-return.js 21774 21775 /** 21776 * WordPress dependencies 21777 */ 21778 21779 const keyboardReturn = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 21780 xmlns: "http://www.w3.org/2000/svg", 21781 viewBox: "-2 -2 24 24" 21782 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 21783 d: "M6.734 16.106l2.176-2.38-1.093-1.028-3.846 4.158 3.846 4.157 1.093-1.027-2.176-2.38h2.811c1.125 0 2.25.03 3.374 0 1.428-.001 3.362-.25 4.963-1.277 1.66-1.065 2.868-2.906 2.868-5.859 0-2.479-1.327-4.896-3.65-5.93-1.82-.813-3.044-.8-4.806-.788l-.567.002v1.5c.184 0 .368 0 .553-.002 1.82-.007 2.704-.014 4.21.657 1.854.827 2.76 2.657 2.76 4.561 0 2.472-.973 3.824-2.178 4.596-1.258.807-2.864 1.04-4.163 1.04h-.02c-1.115.03-2.229 0-3.344 0H6.734z" 21784 })); 21785 /* harmony default export */ const keyboard_return = (keyboardReturn); 21786 21787 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/chevron-left-small.js 21788 21789 /** 21790 * WordPress dependencies 21791 */ 21792 21793 const chevronLeftSmall = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 21794 xmlns: "http://www.w3.org/2000/svg", 21795 viewBox: "0 0 24 24" 21796 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 21797 d: "m13.1 16-3.4-4 3.4-4 1.1 1-2.6 3 2.6 3-1.1 1z" 21798 })); 21799 /* harmony default export */ const chevron_left_small = (chevronLeftSmall); 21800 21801 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/chevron-right-small.js 21802 21803 /** 21804 * WordPress dependencies 21805 */ 21806 21807 const chevronRightSmall = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 21808 xmlns: "http://www.w3.org/2000/svg", 21809 viewBox: "0 0 24 24" 21810 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 21811 d: "M10.8622 8.04053L14.2805 12.0286L10.8622 16.0167L9.72327 15.0405L12.3049 12.0286L9.72327 9.01672L10.8622 8.04053Z" 21812 })); 21813 /* harmony default export */ const chevron_right_small = (chevronRightSmall); 21814 21815 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/link-control/settings-drawer.js 21816 21817 /** 21818 * WordPress dependencies 21819 */ 21820 21821 21822 21823 21824 21825 function LinkSettingsDrawer({ 21826 children, 21827 settingsOpen, 21828 setSettingsOpen 21829 }) { 21830 const prefersReducedMotion = (0,external_wp_compose_namespaceObject.useReducedMotion)(); 21831 const MaybeAnimatePresence = prefersReducedMotion ? external_wp_element_namespaceObject.Fragment : external_wp_components_namespaceObject.__unstableAnimatePresence; 21832 const MaybeMotionDiv = prefersReducedMotion ? 'div' : external_wp_components_namespaceObject.__unstableMotion.div; 21833 const id = (0,external_wp_compose_namespaceObject.useInstanceId)(LinkSettingsDrawer); 21834 const settingsDrawerId = `link-control-settings-drawer-$id}`; 21835 return (0,external_React_.createElement)(external_wp_element_namespaceObject.Fragment, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 21836 className: "block-editor-link-control__drawer-toggle", 21837 "aria-expanded": settingsOpen, 21838 onClick: () => setSettingsOpen(!settingsOpen), 21839 icon: (0,external_wp_i18n_namespaceObject.isRTL)() ? chevron_left_small : chevron_right_small, 21840 "aria-controls": settingsDrawerId 21841 }, (0,external_wp_i18n_namespaceObject._x)('Advanced', 'Additional link settings')), (0,external_React_.createElement)(MaybeAnimatePresence, null, settingsOpen && (0,external_React_.createElement)(MaybeMotionDiv, { 21842 className: "block-editor-link-control__drawer", 21843 hidden: !settingsOpen, 21844 id: settingsDrawerId, 21845 initial: "collapsed", 21846 animate: "open", 21847 exit: "collapsed", 21848 variants: { 21849 open: { 21850 opacity: 1, 21851 height: 'auto' 21852 }, 21853 collapsed: { 21854 opacity: 0, 21855 height: 0 21856 } 21857 }, 21858 transition: { 21859 duration: 0.1 21860 } 21861 }, (0,external_React_.createElement)("div", { 21862 className: "block-editor-link-control__drawer-inner" 21863 }, children)))); 21864 } 21865 /* harmony default export */ const settings_drawer = (LinkSettingsDrawer); 21866 21867 // EXTERNAL MODULE: ./node_modules/dom-scroll-into-view/lib/index.js 21868 var lib = __webpack_require__(5428); 21869 var lib_default = /*#__PURE__*/__webpack_require__.n(lib); 21870 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/url-input/index.js 21871 21872 /** 21873 * External dependencies 21874 */ 21875 21876 21877 21878 /** 21879 * WordPress dependencies 21880 */ 21881 21882 21883 21884 21885 21886 21887 21888 21889 21890 /** 21891 * Internal dependencies 21892 */ 21893 21894 21895 /** 21896 * Whether the argument is a function. 21897 * 21898 * @param {*} maybeFunc The argument to check. 21899 * @return {boolean} True if the argument is a function, false otherwise. 21900 */ 21901 function isFunction(maybeFunc) { 21902 return typeof maybeFunc === 'function'; 21903 } 21904 class URLInput extends external_wp_element_namespaceObject.Component { 21905 constructor(props) { 21906 super(props); 21907 this.onChange = this.onChange.bind(this); 21908 this.onFocus = this.onFocus.bind(this); 21909 this.onKeyDown = this.onKeyDown.bind(this); 21910 this.selectLink = this.selectLink.bind(this); 21911 this.handleOnClick = this.handleOnClick.bind(this); 21912 this.bindSuggestionNode = this.bindSuggestionNode.bind(this); 21913 this.autocompleteRef = props.autocompleteRef || (0,external_wp_element_namespaceObject.createRef)(); 21914 this.inputRef = (0,external_wp_element_namespaceObject.createRef)(); 21915 this.updateSuggestions = (0,external_wp_compose_namespaceObject.debounce)(this.updateSuggestions.bind(this), 200); 21916 this.suggestionNodes = []; 21917 this.suggestionsRequest = null; 21918 this.state = { 21919 suggestions: [], 21920 showSuggestions: false, 21921 suggestionsValue: null, 21922 selectedSuggestion: null, 21923 suggestionsListboxId: '', 21924 suggestionOptionIdPrefix: '' 21925 }; 21926 } 21927 componentDidUpdate(prevProps) { 21928 const { 21929 showSuggestions, 21930 selectedSuggestion 21931 } = this.state; 21932 const { 21933 value, 21934 __experimentalShowInitialSuggestions = false 21935 } = this.props; 21936 21937 // Only have to worry about scrolling selected suggestion into view 21938 // when already expanded. 21939 if (showSuggestions && selectedSuggestion !== null && this.suggestionNodes[selectedSuggestion] && !this.scrollingIntoView) { 21940 this.scrollingIntoView = true; 21941 lib_default()(this.suggestionNodes[selectedSuggestion], this.autocompleteRef.current, { 21942 onlyScrollIfNeeded: true 21943 }); 21944 this.props.setTimeout(() => { 21945 this.scrollingIntoView = false; 21946 }, 100); 21947 } 21948 21949 // Update suggestions when the value changes. 21950 if (prevProps.value !== value && !this.props.disableSuggestions) { 21951 if (value?.length) { 21952 // If the new value is not empty we need to update with suggestions for it. 21953 this.updateSuggestions(value); 21954 } else if (__experimentalShowInitialSuggestions) { 21955 // If the new value is empty and we can show initial suggestions, then show initial suggestions. 21956 this.updateSuggestions(); 21957 } 21958 } 21959 } 21960 componentDidMount() { 21961 if (this.shouldShowInitialSuggestions()) { 21962 this.updateSuggestions(); 21963 } 21964 } 21965 componentWillUnmount() { 21966 this.suggestionsRequest?.cancel?.(); 21967 this.suggestionsRequest = null; 21968 } 21969 bindSuggestionNode(index) { 21970 return ref => { 21971 this.suggestionNodes[index] = ref; 21972 }; 21973 } 21974 shouldShowInitialSuggestions() { 21975 const { 21976 __experimentalShowInitialSuggestions = false, 21977 value 21978 } = this.props; 21979 return __experimentalShowInitialSuggestions && !(value && value.length); 21980 } 21981 updateSuggestions(value = '') { 21982 const { 21983 __experimentalFetchLinkSuggestions: fetchLinkSuggestions, 21984 __experimentalHandleURLSuggestions: handleURLSuggestions 21985 } = this.props; 21986 if (!fetchLinkSuggestions) { 21987 return; 21988 } 21989 21990 // Initial suggestions may only show if there is no value 21991 // (note: this includes whitespace). 21992 const isInitialSuggestions = !value?.length; 21993 21994 // Trim only now we've determined whether or not it originally had a "length" 21995 // (even if that value was all whitespace). 21996 value = value.trim(); 21997 21998 // Allow a suggestions request if: 21999 // - there are at least 2 characters in the search input (except manual searches where 22000 // search input length is not required to trigger a fetch) 22001 // - this is a direct entry (eg: a URL) 22002 if (!isInitialSuggestions && (value.length < 2 || !handleURLSuggestions && (0,external_wp_url_namespaceObject.isURL)(value))) { 22003 this.suggestionsRequest?.cancel?.(); 22004 this.suggestionsRequest = null; 22005 this.setState({ 22006 suggestions: [], 22007 showSuggestions: false, 22008 suggestionsValue: value, 22009 selectedSuggestion: null, 22010 loading: false 22011 }); 22012 return; 22013 } 22014 this.setState({ 22015 selectedSuggestion: null, 22016 loading: true 22017 }); 22018 const request = fetchLinkSuggestions(value, { 22019 isInitialSuggestions 22020 }); 22021 request.then(suggestions => { 22022 // A fetch Promise doesn't have an abort option. It's mimicked by 22023 // comparing the request reference in on the instance, which is 22024 // reset or deleted on subsequent requests or unmounting. 22025 if (this.suggestionsRequest !== request) { 22026 return; 22027 } 22028 this.setState({ 22029 suggestions, 22030 suggestionsValue: value, 22031 loading: false, 22032 showSuggestions: !!suggestions.length 22033 }); 22034 if (!!suggestions.length) { 22035 this.props.debouncedSpeak((0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: number of results. */ 22036 (0,external_wp_i18n_namespaceObject._n)('%d result found, use up and down arrow keys to navigate.', '%d results found, use up and down arrow keys to navigate.', suggestions.length), suggestions.length), 'assertive'); 22037 } else { 22038 this.props.debouncedSpeak((0,external_wp_i18n_namespaceObject.__)('No results.'), 'assertive'); 22039 } 22040 }).catch(() => { 22041 if (this.suggestionsRequest !== request) { 22042 return; 22043 } 22044 this.setState({ 22045 loading: false 22046 }); 22047 }).finally(() => { 22048 // If this is the current promise then reset the reference 22049 // to allow for checking if a new request is made. 22050 if (this.suggestionsRequest === request) { 22051 this.suggestionsRequest = null; 22052 } 22053 }); 22054 22055 // Note that this assignment is handled *before* the async search request 22056 // as a Promise always resolves on the next tick of the event loop. 22057 this.suggestionsRequest = request; 22058 } 22059 onChange(event) { 22060 this.props.onChange(event.target.value); 22061 } 22062 onFocus() { 22063 const { 22064 suggestions 22065 } = this.state; 22066 const { 22067 disableSuggestions, 22068 value 22069 } = this.props; 22070 22071 // When opening the link editor, if there's a value present, we want to load the suggestions pane with the results for this input search value 22072 // Don't re-run the suggestions on focus if there are already suggestions present (prevents searching again when tabbing between the input and buttons) 22073 // or there is already a request in progress. 22074 if (value && !disableSuggestions && !(suggestions && suggestions.length) && this.suggestionsRequest === null) { 22075 // Ensure the suggestions are updated with the current input value. 22076 this.updateSuggestions(value); 22077 } 22078 } 22079 onKeyDown(event) { 22080 this.props.onKeyDown?.(event); 22081 const { 22082 showSuggestions, 22083 selectedSuggestion, 22084 suggestions, 22085 loading 22086 } = this.state; 22087 22088 // If the suggestions are not shown or loading, we shouldn't handle the arrow keys 22089 // We shouldn't preventDefault to allow block arrow keys navigation. 22090 if (!showSuggestions || !suggestions.length || loading) { 22091 // In the Windows version of Firefox the up and down arrows don't move the caret 22092 // within an input field like they do for Mac Firefox/Chrome/Safari. This causes 22093 // a form of focus trapping that is disruptive to the user experience. This disruption 22094 // only happens if the caret is not in the first or last position in the text input. 22095 // See: https://github.com/WordPress/gutenberg/issues/5693#issuecomment-436684747 22096 switch (event.keyCode) { 22097 // When UP is pressed, if the caret is at the start of the text, move it to the 0 22098 // position. 22099 case external_wp_keycodes_namespaceObject.UP: 22100 { 22101 if (0 !== event.target.selectionStart) { 22102 event.preventDefault(); 22103 22104 // Set the input caret to position 0. 22105 event.target.setSelectionRange(0, 0); 22106 } 22107 break; 22108 } 22109 // When DOWN is pressed, if the caret is not at the end of the text, move it to the 22110 // last position. 22111 case external_wp_keycodes_namespaceObject.DOWN: 22112 { 22113 if (this.props.value.length !== event.target.selectionStart) { 22114 event.preventDefault(); 22115 22116 // Set the input caret to the last position. 22117 event.target.setSelectionRange(this.props.value.length, this.props.value.length); 22118 } 22119 break; 22120 } 22121 22122 // Submitting while loading should trigger onSubmit. 22123 case external_wp_keycodes_namespaceObject.ENTER: 22124 { 22125 if (this.props.onSubmit) { 22126 event.preventDefault(); 22127 this.props.onSubmit(null, event); 22128 } 22129 break; 22130 } 22131 } 22132 return; 22133 } 22134 const suggestion = this.state.suggestions[this.state.selectedSuggestion]; 22135 switch (event.keyCode) { 22136 case external_wp_keycodes_namespaceObject.UP: 22137 { 22138 event.preventDefault(); 22139 const previousIndex = !selectedSuggestion ? suggestions.length - 1 : selectedSuggestion - 1; 22140 this.setState({ 22141 selectedSuggestion: previousIndex 22142 }); 22143 break; 22144 } 22145 case external_wp_keycodes_namespaceObject.DOWN: 22146 { 22147 event.preventDefault(); 22148 const nextIndex = selectedSuggestion === null || selectedSuggestion === suggestions.length - 1 ? 0 : selectedSuggestion + 1; 22149 this.setState({ 22150 selectedSuggestion: nextIndex 22151 }); 22152 break; 22153 } 22154 case external_wp_keycodes_namespaceObject.TAB: 22155 { 22156 if (this.state.selectedSuggestion !== null) { 22157 this.selectLink(suggestion); 22158 // Announce a link has been selected when tabbing away from the input field. 22159 this.props.speak((0,external_wp_i18n_namespaceObject.__)('Link selected.')); 22160 } 22161 break; 22162 } 22163 case external_wp_keycodes_namespaceObject.ENTER: 22164 { 22165 event.preventDefault(); 22166 if (this.state.selectedSuggestion !== null) { 22167 this.selectLink(suggestion); 22168 if (this.props.onSubmit) { 22169 this.props.onSubmit(suggestion, event); 22170 } 22171 } else if (this.props.onSubmit) { 22172 this.props.onSubmit(null, event); 22173 } 22174 break; 22175 } 22176 } 22177 } 22178 selectLink(suggestion) { 22179 this.props.onChange(suggestion.url, suggestion); 22180 this.setState({ 22181 selectedSuggestion: null, 22182 showSuggestions: false 22183 }); 22184 } 22185 handleOnClick(suggestion) { 22186 this.selectLink(suggestion); 22187 // Move focus to the input field when a link suggestion is clicked. 22188 this.inputRef.current.focus(); 22189 } 22190 static getDerivedStateFromProps({ 22191 value, 22192 instanceId, 22193 disableSuggestions, 22194 __experimentalShowInitialSuggestions = false 22195 }, { 22196 showSuggestions 22197 }) { 22198 let shouldShowSuggestions = showSuggestions; 22199 const hasValue = value && value.length; 22200 if (!__experimentalShowInitialSuggestions && !hasValue) { 22201 shouldShowSuggestions = false; 22202 } 22203 if (disableSuggestions === true) { 22204 shouldShowSuggestions = false; 22205 } 22206 return { 22207 showSuggestions: shouldShowSuggestions, 22208 suggestionsListboxId: `block-editor-url-input-suggestions-$instanceId}`, 22209 suggestionOptionIdPrefix: `block-editor-url-input-suggestion-$instanceId}` 22210 }; 22211 } 22212 render() { 22213 return (0,external_React_.createElement)(external_React_.Fragment, null, this.renderControl(), this.renderSuggestions()); 22214 } 22215 renderControl() { 22216 const { 22217 /** Start opting into the new margin-free styles that will become the default in a future version. */ 22218 __nextHasNoMarginBottom = false, 22219 label = null, 22220 className, 22221 isFullWidth, 22222 instanceId, 22223 placeholder = (0,external_wp_i18n_namespaceObject.__)('Paste URL or type to search'), 22224 __experimentalRenderControl: renderControl, 22225 value = '', 22226 hideLabelFromVision = false 22227 } = this.props; 22228 const { 22229 loading, 22230 showSuggestions, 22231 selectedSuggestion, 22232 suggestionsListboxId, 22233 suggestionOptionIdPrefix 22234 } = this.state; 22235 const inputId = `url-input-control-$instanceId}`; 22236 const controlProps = { 22237 id: inputId, 22238 // Passes attribute to label for the for attribute 22239 label, 22240 className: classnames_default()('block-editor-url-input', className, { 22241 'is-full-width': isFullWidth 22242 }), 22243 hideLabelFromVision 22244 }; 22245 const inputProps = { 22246 id: inputId, 22247 value, 22248 required: true, 22249 className: 'block-editor-url-input__input', 22250 type: 'text', 22251 onChange: this.onChange, 22252 onFocus: this.onFocus, 22253 placeholder, 22254 onKeyDown: this.onKeyDown, 22255 role: 'combobox', 22256 'aria-label': label ? undefined : (0,external_wp_i18n_namespaceObject.__)('URL'), 22257 // Ensure input always has an accessible label 22258 'aria-expanded': showSuggestions, 22259 'aria-autocomplete': 'list', 22260 'aria-owns': suggestionsListboxId, 22261 'aria-activedescendant': selectedSuggestion !== null ? `$suggestionOptionIdPrefix}-$selectedSuggestion}` : undefined, 22262 ref: this.inputRef 22263 }; 22264 if (renderControl) { 22265 return renderControl(controlProps, inputProps, loading); 22266 } 22267 if (!__nextHasNoMarginBottom) { 22268 external_wp_deprecated_default()('Bottom margin styles for wp.blockEditor.URLInput', { 22269 since: '6.2', 22270 version: '6.5', 22271 hint: 'Set the `__nextHasNoMarginBottom` prop to true to start opting into the new styles, which will become the default in a future version' 22272 }); 22273 } 22274 return (0,external_React_.createElement)(external_wp_components_namespaceObject.BaseControl, { 22275 __nextHasNoMarginBottom: __nextHasNoMarginBottom, 22276 ...controlProps 22277 }, (0,external_React_.createElement)("input", { 22278 ...inputProps 22279 }), loading && (0,external_React_.createElement)(external_wp_components_namespaceObject.Spinner, null)); 22280 } 22281 renderSuggestions() { 22282 const { 22283 className, 22284 __experimentalRenderSuggestions: renderSuggestions 22285 } = this.props; 22286 const { 22287 showSuggestions, 22288 suggestions, 22289 suggestionsValue, 22290 selectedSuggestion, 22291 suggestionsListboxId, 22292 suggestionOptionIdPrefix, 22293 loading 22294 } = this.state; 22295 if (!showSuggestions || suggestions.length === 0) { 22296 return null; 22297 } 22298 const suggestionsListProps = { 22299 id: suggestionsListboxId, 22300 ref: this.autocompleteRef, 22301 role: 'listbox' 22302 }; 22303 const buildSuggestionItemProps = (suggestion, index) => { 22304 return { 22305 role: 'option', 22306 tabIndex: '-1', 22307 id: `$suggestionOptionIdPrefix}-$index}`, 22308 ref: this.bindSuggestionNode(index), 22309 'aria-selected': index === selectedSuggestion ? true : undefined 22310 }; 22311 }; 22312 if (isFunction(renderSuggestions)) { 22313 return renderSuggestions({ 22314 suggestions, 22315 selectedSuggestion, 22316 suggestionsListProps, 22317 buildSuggestionItemProps, 22318 isLoading: loading, 22319 handleSuggestionClick: this.handleOnClick, 22320 isInitialSuggestions: !suggestionsValue?.length, 22321 currentInputValue: suggestionsValue 22322 }); 22323 } 22324 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Popover, { 22325 placement: "bottom", 22326 focusOnMount: false 22327 }, (0,external_React_.createElement)("div", { 22328 ...suggestionsListProps, 22329 className: classnames_default()('block-editor-url-input__suggestions', `$className}__suggestions`) 22330 }, suggestions.map((suggestion, index) => (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 22331 ...buildSuggestionItemProps(suggestion, index), 22332 key: suggestion.id, 22333 className: classnames_default()('block-editor-url-input__suggestion', { 22334 'is-selected': index === selectedSuggestion 22335 }), 22336 onClick: () => this.handleOnClick(suggestion) 22337 }, suggestion.title)))); 22338 } 22339 } 22340 22341 /** 22342 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/url-input/README.md 22343 */ 22344 /* harmony default export */ const url_input = ((0,external_wp_compose_namespaceObject.compose)(external_wp_compose_namespaceObject.withSafeTimeout, external_wp_components_namespaceObject.withSpokenMessages, external_wp_compose_namespaceObject.withInstanceId, (0,external_wp_data_namespaceObject.withSelect)((select, props) => { 22345 // If a link suggestions handler is already provided then 22346 // bail. 22347 if (isFunction(props.__experimentalFetchLinkSuggestions)) { 22348 return; 22349 } 22350 const { 22351 getSettings 22352 } = select(store); 22353 return { 22354 __experimentalFetchLinkSuggestions: getSettings().__experimentalFetchLinkSuggestions 22355 }; 22356 }))(URLInput)); 22357 22358 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/plus.js 22359 22360 /** 22361 * WordPress dependencies 22362 */ 22363 22364 const plus = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 22365 xmlns: "http://www.w3.org/2000/svg", 22366 viewBox: "0 0 24 24" 22367 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 22368 d: "M11 12.5V17.5H12.5V12.5H17.5V11H12.5V6H11V11H6V12.5H11Z" 22369 })); 22370 /* harmony default export */ const library_plus = (plus); 22371 22372 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/link-control/search-create-button.js 22373 22374 /** 22375 * WordPress dependencies 22376 */ 22377 22378 22379 22380 22381 const LinkControlSearchCreate = ({ 22382 searchTerm, 22383 onClick, 22384 itemProps, 22385 buttonText 22386 }) => { 22387 if (!searchTerm) { 22388 return null; 22389 } 22390 let text; 22391 if (buttonText) { 22392 text = typeof buttonText === 'function' ? buttonText(searchTerm) : buttonText; 22393 } else { 22394 text = (0,external_wp_element_namespaceObject.createInterpolateElement)((0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: search term. */ 22395 (0,external_wp_i18n_namespaceObject.__)('Create: <mark>%s</mark>'), searchTerm), { 22396 mark: (0,external_React_.createElement)("mark", null) 22397 }); 22398 } 22399 return (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 22400 ...itemProps, 22401 iconPosition: "left", 22402 icon: library_plus, 22403 className: "block-editor-link-control__search-item", 22404 onClick: onClick 22405 }, text); 22406 }; 22407 /* harmony default export */ const search_create_button = (LinkControlSearchCreate); 22408 22409 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/post-list.js 22410 22411 /** 22412 * WordPress dependencies 22413 */ 22414 22415 const postList = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 22416 viewBox: "0 0 24 24", 22417 xmlns: "http://www.w3.org/2000/svg" 22418 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 22419 d: "M18 5.5H6a.5.5 0 0 0-.5.5v12a.5.5 0 0 0 .5.5h12a.5.5 0 0 0 .5-.5V6a.5.5 0 0 0-.5-.5ZM6 4h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Zm1 5h1.5v1.5H7V9Zm1.5 4.5H7V15h1.5v-1.5ZM10 9h7v1.5h-7V9Zm7 4.5h-7V15h7v-1.5Z" 22420 })); 22421 /* harmony default export */ const post_list = (postList); 22422 22423 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/page.js 22424 22425 /** 22426 * WordPress dependencies 22427 */ 22428 22429 const page = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 22430 xmlns: "http://www.w3.org/2000/svg", 22431 viewBox: "0 0 24 24" 22432 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 22433 d: "M15.5 7.5h-7V9h7V7.5Zm-7 3.5h7v1.5h-7V11Zm7 3.5h-7V16h7v-1.5Z" 22434 }), (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 22435 d: "M17 4H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2ZM7 5.5h10a.5.5 0 0 1 .5.5v12a.5.5 0 0 1-.5.5H7a.5.5 0 0 1-.5-.5V6a.5.5 0 0 1 .5-.5Z" 22436 })); 22437 /* harmony default export */ const library_page = (page); 22438 22439 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/tag.js 22440 22441 /** 22442 * WordPress dependencies 22443 */ 22444 22445 const tag = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 22446 xmlns: "http://www.w3.org/2000/svg", 22447 viewBox: "0 0 24 24" 22448 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 22449 d: "M4.75 4a.75.75 0 0 0-.75.75v7.826c0 .2.08.39.22.53l6.72 6.716a2.313 2.313 0 0 0 3.276-.001l5.61-5.611-.531-.53.532.528a2.315 2.315 0 0 0 0-3.264L13.104 4.22a.75.75 0 0 0-.53-.22H4.75ZM19 12.576a.815.815 0 0 1-.236.574l-5.61 5.611a.814.814 0 0 1-1.153 0L5.5 12.264V5.5h6.763l6.5 6.502a.816.816 0 0 1 .237.574ZM8.75 9.75a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z" 22450 })); 22451 /* harmony default export */ const library_tag = (tag); 22452 22453 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/category.js 22454 22455 /** 22456 * WordPress dependencies 22457 */ 22458 22459 const category = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 22460 viewBox: "0 0 24 24", 22461 xmlns: "http://www.w3.org/2000/svg" 22462 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 22463 d: "M6 5.5h3a.5.5 0 01.5.5v3a.5.5 0 01-.5.5H6a.5.5 0 01-.5-.5V6a.5.5 0 01.5-.5zM4 6a2 2 0 012-2h3a2 2 0 012 2v3a2 2 0 01-2 2H6a2 2 0 01-2-2V6zm11-.5h3a.5.5 0 01.5.5v3a.5.5 0 01-.5.5h-3a.5.5 0 01-.5-.5V6a.5.5 0 01.5-.5zM13 6a2 2 0 012-2h3a2 2 0 012 2v3a2 2 0 01-2 2h-3a2 2 0 01-2-2V6zm5 8.5h-3a.5.5 0 00-.5.5v3a.5.5 0 00.5.5h3a.5.5 0 00.5-.5v-3a.5.5 0 00-.5-.5zM15 13a2 2 0 00-2 2v3a2 2 0 002 2h3a2 2 0 002-2v-3a2 2 0 00-2-2h-3zm-9 1.5h3a.5.5 0 01.5.5v3a.5.5 0 01-.5.5H6a.5.5 0 01-.5-.5v-3a.5.5 0 01.5-.5zM4 15a2 2 0 012-2h3a2 2 0 012 2v3a2 2 0 01-2 2H6a2 2 0 01-2-2v-3z", 22464 fillRule: "evenodd", 22465 clipRule: "evenodd" 22466 })); 22467 /* harmony default export */ const library_category = (category); 22468 22469 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/file.js 22470 22471 /** 22472 * WordPress dependencies 22473 */ 22474 22475 const file = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 22476 viewBox: "0 0 24 24", 22477 xmlns: "http://www.w3.org/2000/svg" 22478 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 22479 fillRule: "evenodd", 22480 clipRule: "evenodd", 22481 d: "M12.848 8a1 1 0 0 1-.914-.594l-.723-1.63a.5.5 0 0 0-.447-.276H5a.5.5 0 0 0-.5.5v11.5a.5.5 0 0 0 .5.5h14a.5.5 0 0 0 .5-.5v-9A.5.5 0 0 0 19 8h-6.152Zm.612-1.5a.5.5 0 0 1-.462-.31l-.445-1.084A2 2 0 0 0 10.763 4H5a2 2 0 0 0-2 2v11.5a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-9a2 2 0 0 0-2-2h-5.54Z" 22482 })); 22483 /* harmony default export */ const library_file = (file); 22484 22485 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/globe.js 22486 22487 /** 22488 * WordPress dependencies 22489 */ 22490 22491 const globe = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 22492 xmlns: "http://www.w3.org/2000/svg", 22493 viewBox: "0 0 24 24" 22494 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 22495 d: "M12 3.3c-4.8 0-8.8 3.9-8.8 8.8 0 4.8 3.9 8.8 8.8 8.8 4.8 0 8.8-3.9 8.8-8.8s-4-8.8-8.8-8.8zm6.5 5.5h-2.6C15.4 7.3 14.8 6 14 5c2 .6 3.6 2 4.5 3.8zm.7 3.2c0 .6-.1 1.2-.2 1.8h-2.9c.1-.6.1-1.2.1-1.8s-.1-1.2-.1-1.8H19c.2.6.2 1.2.2 1.8zM12 18.7c-1-.7-1.8-1.9-2.3-3.5h4.6c-.5 1.6-1.3 2.9-2.3 3.5zm-2.6-4.9c-.1-.6-.1-1.1-.1-1.8 0-.6.1-1.2.1-1.8h5.2c.1.6.1 1.1.1 1.8s-.1 1.2-.1 1.8H9.4zM4.8 12c0-.6.1-1.2.2-1.8h2.9c-.1.6-.1 1.2-.1 1.8 0 .6.1 1.2.1 1.8H5c-.2-.6-.2-1.2-.2-1.8zM12 5.3c1 .7 1.8 1.9 2.3 3.5H9.7c.5-1.6 1.3-2.9 2.3-3.5zM10 5c-.8 1-1.4 2.3-1.8 3.8H5.5C6.4 7 8 5.6 10 5zM5.5 15.3h2.6c.4 1.5 1 2.8 1.8 3.7-1.8-.6-3.5-2-4.4-3.7zM14 19c.8-1 1.4-2.2 1.8-3.7h2.6C17.6 17 16 18.4 14 19z" 22496 })); 22497 /* harmony default export */ const library_globe = (globe); 22498 22499 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/home.js 22500 22501 /** 22502 * WordPress dependencies 22503 */ 22504 22505 const home = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 22506 xmlns: "http://www.w3.org/2000/svg", 22507 viewBox: "0 0 24 24" 22508 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 22509 d: "M12 4L4 7.9V20h16V7.9L12 4zm6.5 14.5H14V13h-4v5.5H5.5V8.8L12 5.7l6.5 3.1v9.7z" 22510 })); 22511 /* harmony default export */ const library_home = (home); 22512 22513 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/verse.js 22514 22515 /** 22516 * WordPress dependencies 22517 */ 22518 22519 const verse = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 22520 viewBox: "0 0 24 24", 22521 xmlns: "http://www.w3.org/2000/svg" 22522 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 22523 d: "M17.8 2l-.9.3c-.1 0-3.6 1-5.2 2.1C10 5.5 9.3 6.5 8.9 7.1c-.6.9-1.7 4.7-1.7 6.3l-.9 2.3c-.2.4 0 .8.4 1 .1 0 .2.1.3.1.3 0 .6-.2.7-.5l.6-1.5c.3 0 .7-.1 1.2-.2.7-.1 1.4-.3 2.2-.5.8-.2 1.6-.5 2.4-.8.7-.3 1.4-.7 1.9-1.2s.8-1.2 1-1.9c.2-.7.3-1.6.4-2.4.1-.8.1-1.7.2-2.5 0-.8.1-1.5.2-2.1V2zm-1.9 5.6c-.1.8-.2 1.5-.3 2.1-.2.6-.4 1-.6 1.3-.3.3-.8.6-1.4.9-.7.3-1.4.5-2.2.8-.6.2-1.3.3-1.8.4L15 7.5c.3-.3.6-.7 1-1.1 0 .4 0 .8-.1 1.2zM6 20h8v-1.5H6V20z" 22524 })); 22525 /* harmony default export */ const library_verse = (verse); 22526 22527 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/link-control/search-item.js 22528 22529 /** 22530 * WordPress dependencies 22531 */ 22532 22533 22534 22535 22536 22537 22538 const ICONS_MAP = { 22539 post: post_list, 22540 page: library_page, 22541 post_tag: library_tag, 22542 category: library_category, 22543 attachment: library_file 22544 }; 22545 function SearchItemIcon({ 22546 isURL, 22547 suggestion 22548 }) { 22549 let icon = null; 22550 if (isURL) { 22551 icon = library_globe; 22552 } else if (suggestion.type in ICONS_MAP) { 22553 icon = ICONS_MAP[suggestion.type]; 22554 if (suggestion.type === 'page') { 22555 if (suggestion.isFrontPage) { 22556 icon = library_home; 22557 } 22558 if (suggestion.isBlogHome) { 22559 icon = library_verse; 22560 } 22561 } 22562 } 22563 if (icon) { 22564 return (0,external_React_.createElement)(build_module_icon, { 22565 className: "block-editor-link-control__search-item-icon", 22566 icon: icon 22567 }); 22568 } 22569 return null; 22570 } 22571 22572 /** 22573 * Adds a leading slash to a url if it doesn't already have one. 22574 * @param {string} url the url to add a leading slash to. 22575 * @return {string} the url with a leading slash. 22576 */ 22577 function addLeadingSlash(url) { 22578 const trimmedURL = url?.trim(); 22579 if (!trimmedURL?.length) return url; 22580 return url?.replace(/^\/?/, '/'); 22581 } 22582 function removeTrailingSlash(url) { 22583 const trimmedURL = url?.trim(); 22584 if (!trimmedURL?.length) return url; 22585 return url?.replace(/\/$/, ''); 22586 } 22587 const partialRight = (fn, ...partialArgs) => (...args) => fn(...args, ...partialArgs); 22588 const defaultTo = d => v => { 22589 return v === null || v === undefined || v !== v ? d : v; 22590 }; 22591 22592 /** 22593 * Prepares a URL for display in the UI. 22594 * - decodes the URL. 22595 * - filters it (removes protocol, www, etc.). 22596 * - truncates it if necessary. 22597 * - adds a leading slash. 22598 * @param {string} url the url. 22599 * @return {string} the processed url to display. 22600 */ 22601 function getURLForDisplay(url) { 22602 if (!url) return url; 22603 return (0,external_wp_compose_namespaceObject.pipe)(external_wp_url_namespaceObject.safeDecodeURI, external_wp_url_namespaceObject.getPath, defaultTo(''), partialRight(external_wp_url_namespaceObject.filterURLForDisplay, 24), removeTrailingSlash, addLeadingSlash)(url); 22604 } 22605 const LinkControlSearchItem = ({ 22606 itemProps, 22607 suggestion, 22608 searchTerm, 22609 onClick, 22610 isURL = false, 22611 shouldShowType = false 22612 }) => { 22613 const info = isURL ? (0,external_wp_i18n_namespaceObject.__)('Press ENTER to add this link') : getURLForDisplay(suggestion.url); 22614 return (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 22615 ...itemProps, 22616 info: info, 22617 iconPosition: "left", 22618 icon: (0,external_React_.createElement)(SearchItemIcon, { 22619 suggestion: suggestion, 22620 isURL: isURL 22621 }), 22622 onClick: onClick, 22623 shortcut: shouldShowType && getVisualTypeName(suggestion), 22624 className: "block-editor-link-control__search-item" 22625 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.TextHighlight 22626 // The component expects a plain text string. 22627 , { 22628 text: (0,external_wp_dom_namespaceObject.__unstableStripHTML)(suggestion.title), 22629 highlight: searchTerm 22630 })); 22631 }; 22632 function getVisualTypeName(suggestion) { 22633 if (suggestion.isFrontPage) { 22634 return 'front page'; 22635 } 22636 if (suggestion.isBlogHome) { 22637 return 'blog home'; 22638 } 22639 22640 // Rename 'post_tag' to 'tag'. Ideally, the API would return the localised CPT or taxonomy label. 22641 return suggestion.type === 'post_tag' ? 'tag' : suggestion.type; 22642 } 22643 /* harmony default export */ const search_item = (LinkControlSearchItem); 22644 22645 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/link-control/constants.js 22646 /** 22647 * WordPress dependencies 22648 */ 22649 22650 22651 // Used as a unique identifier for the "Create" option within search results. 22652 // Used to help distinguish the "Create" suggestion within the search results in 22653 // order to handle it as a unique case. 22654 const CREATE_TYPE = '__CREATE__'; 22655 const TEL_TYPE = 'tel'; 22656 const URL_TYPE = 'link'; 22657 const MAILTO_TYPE = 'mailto'; 22658 const INTERNAL_TYPE = 'internal'; 22659 const LINK_ENTRY_TYPES = [URL_TYPE, MAILTO_TYPE, TEL_TYPE, INTERNAL_TYPE]; 22660 const DEFAULT_LINK_SETTINGS = [{ 22661 id: 'opensInNewTab', 22662 title: (0,external_wp_i18n_namespaceObject.__)('Open in new tab') 22663 }]; 22664 22665 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/link-control/search-results.js 22666 22667 /** 22668 * WordPress dependencies 22669 */ 22670 22671 22672 22673 /** 22674 * External dependencies 22675 */ 22676 22677 22678 /** 22679 * Internal dependencies 22680 */ 22681 22682 22683 22684 function LinkControlSearchResults({ 22685 instanceId, 22686 withCreateSuggestion, 22687 currentInputValue, 22688 handleSuggestionClick, 22689 suggestionsListProps, 22690 buildSuggestionItemProps, 22691 suggestions, 22692 selectedSuggestion, 22693 isLoading, 22694 isInitialSuggestions, 22695 createSuggestionButtonText, 22696 suggestionsQuery 22697 }) { 22698 const resultsListClasses = classnames_default()('block-editor-link-control__search-results', { 22699 'is-loading': isLoading 22700 }); 22701 const isSingleDirectEntryResult = suggestions.length === 1 && LINK_ENTRY_TYPES.includes(suggestions[0].type); 22702 const shouldShowCreateSuggestion = withCreateSuggestion && !isSingleDirectEntryResult && !isInitialSuggestions; 22703 // If the query has a specified type, then we can skip showing them in the result. See #24839. 22704 const shouldShowSuggestionsTypes = !suggestionsQuery?.type; 22705 22706 // According to guidelines aria-label should be added if the label 22707 // itself is not visible. 22708 // See: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/listbox_role 22709 const searchResultsLabelId = `block-editor-link-control-search-results-label-$instanceId}`; 22710 const labelText = isInitialSuggestions ? (0,external_wp_i18n_namespaceObject.__)('Suggestions') : (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: search term. */ 22711 (0,external_wp_i18n_namespaceObject.__)('Search results for "%s"'), currentInputValue); 22712 const searchResultsLabel = (0,external_React_.createElement)(external_wp_components_namespaceObject.VisuallyHidden, { 22713 id: searchResultsLabelId 22714 }, labelText); 22715 return (0,external_React_.createElement)("div", { 22716 className: "block-editor-link-control__search-results-wrapper" 22717 }, searchResultsLabel, (0,external_React_.createElement)("div", { 22718 ...suggestionsListProps, 22719 className: resultsListClasses, 22720 "aria-labelledby": searchResultsLabelId 22721 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuGroup, null, suggestions.map((suggestion, index) => { 22722 if (shouldShowCreateSuggestion && CREATE_TYPE === suggestion.type) { 22723 return (0,external_React_.createElement)(search_create_button, { 22724 searchTerm: currentInputValue, 22725 buttonText: createSuggestionButtonText, 22726 onClick: () => handleSuggestionClick(suggestion) 22727 // Intentionally only using `type` here as 22728 // the constant is enough to uniquely 22729 // identify the single "CREATE" suggestion. 22730 , 22731 key: suggestion.type, 22732 itemProps: buildSuggestionItemProps(suggestion, index), 22733 isSelected: index === selectedSuggestion 22734 }); 22735 } 22736 22737 // If we're not handling "Create" suggestions above then 22738 // we don't want them in the main results so exit early. 22739 if (CREATE_TYPE === suggestion.type) { 22740 return null; 22741 } 22742 return (0,external_React_.createElement)(search_item, { 22743 key: `$suggestion.id}-$suggestion.type}`, 22744 itemProps: buildSuggestionItemProps(suggestion, index), 22745 suggestion: suggestion, 22746 index: index, 22747 onClick: () => { 22748 handleSuggestionClick(suggestion); 22749 }, 22750 isSelected: index === selectedSuggestion, 22751 isURL: LINK_ENTRY_TYPES.includes(suggestion.type), 22752 searchTerm: currentInputValue, 22753 shouldShowType: shouldShowSuggestionsTypes, 22754 isFrontPage: suggestion?.isFrontPage, 22755 isBlogHome: suggestion?.isBlogHome 22756 }); 22757 })))); 22758 } 22759 22760 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/link-control/is-url-like.js 22761 /** 22762 * WordPress dependencies 22763 */ 22764 22765 22766 /** 22767 * Determines whether a given value could be a URL. Note this does not 22768 * guarantee the value is a URL only that it looks like it might be one. For 22769 * example, just because a string has `www.` in it doesn't make it a URL, 22770 * but it does make it highly likely that it will be so in the context of 22771 * creating a link it makes sense to treat it like one. 22772 * 22773 * @param {string} val the candidate for being URL-like (or not). 22774 * 22775 * @return {boolean} whether or not the value is potentially a URL. 22776 */ 22777 function isURLLike(val) { 22778 const hasSpaces = val.includes(' '); 22779 if (hasSpaces) { 22780 return false; 22781 } 22782 const protocol = (0,external_wp_url_namespaceObject.getProtocol)(val); 22783 const protocolIsValid = (0,external_wp_url_namespaceObject.isValidProtocol)(protocol); 22784 const mayBeTLD = hasPossibleTLD(val); 22785 const isWWW = val?.startsWith('www.'); 22786 const isInternal = val?.startsWith('#') && (0,external_wp_url_namespaceObject.isValidFragment)(val); 22787 return protocolIsValid || isWWW || isInternal || mayBeTLD; 22788 } 22789 22790 /** 22791 * Checks if a given URL has a valid Top-Level Domain (TLD). 22792 * 22793 * @param {string} url - The URL to check. 22794 * @param {number} maxLength - The maximum length of the TLD. 22795 * @return {boolean} Returns true if the URL has a valid TLD, false otherwise. 22796 */ 22797 function hasPossibleTLD(url, maxLength = 6) { 22798 // Clean the URL by removing anything after the first occurrence of "?" or "#". 22799 const cleanedURL = url.split(/[?#]/)[0]; 22800 22801 // Regular expression explanation: 22802 // - (?<=\S) : Positive lookbehind assertion to ensure there is at least one non-whitespace character before the TLD 22803 // - \. : Matches a literal dot (.) 22804 // - [a-zA-Z_]{2,maxLength} : Matches 2 to maxLength letters or underscores, representing the TLD 22805 // - (?:\/|$) : Non-capturing group that matches either a forward slash (/) or the end of the string 22806 const regex = new RegExp(`(?<=\\S)\\.(?:[a-zA-Z_]{2,$maxLength}})(?:\\/|$)`); 22807 return regex.test(cleanedURL); 22808 } 22809 22810 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/link-control/use-search-handler.js 22811 /** 22812 * WordPress dependencies 22813 */ 22814 22815 22816 22817 22818 /** 22819 * Internal dependencies 22820 */ 22821 22822 22823 22824 const handleNoop = () => Promise.resolve([]); 22825 const handleDirectEntry = val => { 22826 let type = URL_TYPE; 22827 const protocol = (0,external_wp_url_namespaceObject.getProtocol)(val) || ''; 22828 if (protocol.includes('mailto')) { 22829 type = MAILTO_TYPE; 22830 } 22831 if (protocol.includes('tel')) { 22832 type = TEL_TYPE; 22833 } 22834 if (val?.startsWith('#')) { 22835 type = INTERNAL_TYPE; 22836 } 22837 return Promise.resolve([{ 22838 id: val, 22839 title: val, 22840 url: type === 'URL' ? (0,external_wp_url_namespaceObject.prependHTTP)(val) : val, 22841 type 22842 }]); 22843 }; 22844 const handleEntitySearch = async (val, suggestionsQuery, fetchSearchSuggestions, withCreateSuggestion, pageOnFront, pageForPosts) => { 22845 const { 22846 isInitialSuggestions 22847 } = suggestionsQuery; 22848 const results = await fetchSearchSuggestions(val, suggestionsQuery); 22849 22850 // Identify front page and update type to match. 22851 results.map(result => { 22852 if (Number(result.id) === pageOnFront) { 22853 result.isFrontPage = true; 22854 return result; 22855 } else if (Number(result.id) === pageForPosts) { 22856 result.isBlogHome = true; 22857 return result; 22858 } 22859 return result; 22860 }); 22861 22862 // If displaying initial suggestions just return plain results. 22863 if (isInitialSuggestions) { 22864 return results; 22865 } 22866 22867 // Here we append a faux suggestion to represent a "CREATE" option. This 22868 // is detected in the rendering of the search results and handled as a 22869 // special case. This is currently necessary because the suggestions 22870 // dropdown will only appear if there are valid suggestions and 22871 // therefore unless the create option is a suggestion it will not 22872 // display in scenarios where there are no results returned from the 22873 // API. In addition promoting CREATE to a first class suggestion affords 22874 // the a11y benefits afforded by `URLInput` to all suggestions (eg: 22875 // keyboard handling, ARIA roles...etc). 22876 // 22877 // Note also that the value of the `title` and `url` properties must correspond 22878 // to the text value of the `<input>`. This is because `title` is used 22879 // when creating the suggestion. Similarly `url` is used when using keyboard to select 22880 // the suggestion (the <form> `onSubmit` handler falls-back to `url`). 22881 return isURLLike(val) || !withCreateSuggestion ? results : results.concat({ 22882 // the `id` prop is intentionally ommitted here because it 22883 // is never exposed as part of the component's public API. 22884 // see: https://github.com/WordPress/gutenberg/pull/19775#discussion_r378931316. 22885 title: val, 22886 // Must match the existing `<input>`s text value. 22887 url: val, 22888 // Must match the existing `<input>`s text value. 22889 type: CREATE_TYPE 22890 }); 22891 }; 22892 function useSearchHandler(suggestionsQuery, allowDirectEntry, withCreateSuggestion) { 22893 const { 22894 fetchSearchSuggestions, 22895 pageOnFront, 22896 pageForPosts 22897 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 22898 const { 22899 getSettings 22900 } = select(store); 22901 return { 22902 pageOnFront: getSettings().pageOnFront, 22903 pageForPosts: getSettings().pageForPosts, 22904 fetchSearchSuggestions: getSettings().__experimentalFetchLinkSuggestions 22905 }; 22906 }, []); 22907 const directEntryHandler = allowDirectEntry ? handleDirectEntry : handleNoop; 22908 return (0,external_wp_element_namespaceObject.useCallback)((val, { 22909 isInitialSuggestions 22910 }) => { 22911 return isURLLike(val) ? directEntryHandler(val, { 22912 isInitialSuggestions 22913 }) : handleEntitySearch(val, { 22914 ...suggestionsQuery, 22915 isInitialSuggestions 22916 }, fetchSearchSuggestions, withCreateSuggestion, pageOnFront, pageForPosts); 22917 }, [directEntryHandler, fetchSearchSuggestions, pageOnFront, pageForPosts, suggestionsQuery, withCreateSuggestion]); 22918 } 22919 22920 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/link-control/search-input.js 22921 22922 /** 22923 * WordPress dependencies 22924 */ 22925 22926 22927 22928 22929 /** 22930 * Internal dependencies 22931 */ 22932 22933 22934 22935 22936 22937 // Must be a function as otherwise URLInput will default 22938 // to the fetchLinkSuggestions passed in block editor settings 22939 // which will cause an unintended http request. 22940 const noopSearchHandler = () => Promise.resolve([]); 22941 const noop = () => {}; 22942 const LinkControlSearchInput = (0,external_wp_element_namespaceObject.forwardRef)(({ 22943 value, 22944 children, 22945 currentLink = {}, 22946 className = null, 22947 placeholder = null, 22948 withCreateSuggestion = false, 22949 onCreateSuggestion = noop, 22950 onChange = noop, 22951 onSelect = noop, 22952 showSuggestions = true, 22953 renderSuggestions = props => (0,external_React_.createElement)(LinkControlSearchResults, { 22954 ...props 22955 }), 22956 fetchSuggestions = null, 22957 allowDirectEntry = true, 22958 showInitialSuggestions = false, 22959 suggestionsQuery = {}, 22960 withURLSuggestion = true, 22961 createSuggestionButtonText, 22962 hideLabelFromVision = false 22963 }, ref) => { 22964 const genericSearchHandler = useSearchHandler(suggestionsQuery, allowDirectEntry, withCreateSuggestion, withURLSuggestion); 22965 const searchHandler = showSuggestions ? fetchSuggestions || genericSearchHandler : noopSearchHandler; 22966 const instanceId = (0,external_wp_compose_namespaceObject.useInstanceId)(LinkControlSearchInput); 22967 const [focusedSuggestion, setFocusedSuggestion] = (0,external_wp_element_namespaceObject.useState)(); 22968 22969 /** 22970 * Handles the user moving between different suggestions. Does not handle 22971 * choosing an individual item. 22972 * 22973 * @param {string} selection the url of the selected suggestion. 22974 * @param {Object} suggestion the suggestion object. 22975 */ 22976 const onInputChange = (selection, suggestion) => { 22977 onChange(selection); 22978 setFocusedSuggestion(suggestion); 22979 }; 22980 const handleRenderSuggestions = props => renderSuggestions({ 22981 ...props, 22982 instanceId, 22983 withCreateSuggestion, 22984 createSuggestionButtonText, 22985 suggestionsQuery, 22986 handleSuggestionClick: suggestion => { 22987 if (props.handleSuggestionClick) { 22988 props.handleSuggestionClick(suggestion); 22989 } 22990 onSuggestionSelected(suggestion); 22991 } 22992 }); 22993 const onSuggestionSelected = async selectedSuggestion => { 22994 let suggestion = selectedSuggestion; 22995 if (CREATE_TYPE === selectedSuggestion.type) { 22996 // Create a new page and call onSelect with the output from the onCreateSuggestion callback. 22997 try { 22998 suggestion = await onCreateSuggestion(selectedSuggestion.title); 22999 if (suggestion?.url) { 23000 onSelect(suggestion); 23001 } 23002 } catch (e) {} 23003 return; 23004 } 23005 if (allowDirectEntry || suggestion && Object.keys(suggestion).length >= 1) { 23006 const { 23007 id, 23008 url, 23009 ...restLinkProps 23010 } = currentLink !== null && currentLink !== void 0 ? currentLink : {}; 23011 onSelect( 23012 // Some direct entries don't have types or IDs, and we still need to clear the previous ones. 23013 { 23014 ...restLinkProps, 23015 ...suggestion 23016 }, suggestion); 23017 } 23018 }; 23019 return (0,external_React_.createElement)("div", { 23020 className: "block-editor-link-control__search-input-container" 23021 }, (0,external_React_.createElement)(url_input, { 23022 disableSuggestions: currentLink?.url === value, 23023 __nextHasNoMarginBottom: true, 23024 label: (0,external_wp_i18n_namespaceObject.__)('Link'), 23025 hideLabelFromVision: hideLabelFromVision, 23026 className: className, 23027 value: value, 23028 onChange: onInputChange, 23029 placeholder: placeholder !== null && placeholder !== void 0 ? placeholder : (0,external_wp_i18n_namespaceObject.__)('Search or type url'), 23030 __experimentalRenderSuggestions: showSuggestions ? handleRenderSuggestions : null, 23031 __experimentalFetchLinkSuggestions: searchHandler, 23032 __experimentalHandleURLSuggestions: true, 23033 __experimentalShowInitialSuggestions: showInitialSuggestions, 23034 onSubmit: (suggestion, event) => { 23035 const hasSuggestion = suggestion || focusedSuggestion; 23036 23037 // If there is no suggestion and the value (ie: any manually entered URL) is empty 23038 // then don't allow submission otherwise we get empty links. 23039 if (!hasSuggestion && !value?.trim()?.length) { 23040 event.preventDefault(); 23041 } else { 23042 onSuggestionSelected(hasSuggestion || { 23043 url: value 23044 }); 23045 } 23046 }, 23047 ref: ref 23048 }), children); 23049 }); 23050 /* harmony default export */ const search_input = (LinkControlSearchInput); 23051 23052 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/info.js 23053 23054 /** 23055 * WordPress dependencies 23056 */ 23057 23058 const info = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 23059 xmlns: "http://www.w3.org/2000/svg", 23060 viewBox: "0 0 24 24" 23061 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 23062 d: "M12 3.2c-4.8 0-8.8 3.9-8.8 8.8 0 4.8 3.9 8.8 8.8 8.8 4.8 0 8.8-3.9 8.8-8.8 0-4.8-4-8.8-8.8-8.8zm0 16c-4 0-7.2-3.3-7.2-7.2C4.8 8 8 4.8 12 4.8s7.2 3.3 7.2 7.2c0 4-3.2 7.2-7.2 7.2zM11 17h2v-6h-2v6zm0-8h2V7h-2v2z" 23063 })); 23064 /* harmony default export */ const library_info = (info); 23065 23066 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/pencil.js 23067 23068 /** 23069 * WordPress dependencies 23070 */ 23071 23072 const pencil = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 23073 xmlns: "http://www.w3.org/2000/svg", 23074 viewBox: "0 0 24 24" 23075 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 23076 d: "m19 7-3-3-8.5 8.5-1 4 4-1L19 7Zm-7 11.5H5V20h7v-1.5Z" 23077 })); 23078 /* harmony default export */ const library_pencil = (pencil); 23079 23080 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/edit.js 23081 /** 23082 * Internal dependencies 23083 */ 23084 23085 23086 /* harmony default export */ const edit = (library_pencil); 23087 23088 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/link-off.js 23089 23090 /** 23091 * WordPress dependencies 23092 */ 23093 23094 const linkOff = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 23095 xmlns: "http://www.w3.org/2000/svg", 23096 viewBox: "0 0 24 24" 23097 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 23098 d: "M17.031 4.703 15.576 4l-1.56 3H14v.03l-2.324 4.47H9.5V13h1.396l-1.502 2.889h-.95a3.694 3.694 0 0 1 0-7.389H10V7H8.444a5.194 5.194 0 1 0 0 10.389h.17L7.5 19.53l1.416.719L15.049 8.5h.507a3.694 3.694 0 0 1 0 7.39H14v1.5h1.556a5.194 5.194 0 0 0 .273-10.383l1.202-2.304Z" 23099 })); 23100 /* harmony default export */ const link_off = (linkOff); 23101 23102 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/copy-small.js 23103 23104 /** 23105 * WordPress dependencies 23106 */ 23107 23108 const copySmall = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 23109 xmlns: "http://www.w3.org/2000/svg", 23110 viewBox: "0 0 24 24" 23111 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 23112 fillRule: "evenodd", 23113 clipRule: "evenodd", 23114 d: "M5.625 5.5h9.75c.069 0 .125.056.125.125v9.75a.125.125 0 0 1-.125.125h-9.75a.125.125 0 0 1-.125-.125v-9.75c0-.069.056-.125.125-.125ZM4 5.625C4 4.728 4.728 4 5.625 4h9.75C16.273 4 17 4.728 17 5.625v9.75c0 .898-.727 1.625-1.625 1.625h-9.75A1.625 1.625 0 0 1 4 15.375v-9.75Zm14.5 11.656v-9H20v9C20 18.8 18.77 20 17.251 20H6.25v-1.5h11.001c.69 0 1.249-.528 1.249-1.219Z" 23115 })); 23116 /* harmony default export */ const copy_small = (copySmall); 23117 23118 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/link-control/viewer-slot.js 23119 /** 23120 * WordPress dependencies 23121 */ 23122 23123 const { 23124 Slot: ViewerSlot, 23125 Fill: ViewerFill 23126 } = (0,external_wp_components_namespaceObject.createSlotFill)('BlockEditorLinkControlViewer'); 23127 23128 /* harmony default export */ const viewer_slot = ((/* unused pure expression or super */ null && (ViewerSlot))); 23129 23130 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/link-control/use-rich-url-data.js 23131 /** 23132 * Internal dependencies 23133 */ 23134 23135 23136 /** 23137 * WordPress dependencies 23138 */ 23139 23140 23141 function use_rich_url_data_reducer(state, action) { 23142 switch (action.type) { 23143 case 'RESOLVED': 23144 return { 23145 ...state, 23146 isFetching: false, 23147 richData: action.richData 23148 }; 23149 case 'ERROR': 23150 return { 23151 ...state, 23152 isFetching: false, 23153 richData: null 23154 }; 23155 case 'LOADING': 23156 return { 23157 ...state, 23158 isFetching: true 23159 }; 23160 default: 23161 throw new Error(`Unexpected action type $action.type}`); 23162 } 23163 } 23164 function useRemoteUrlData(url) { 23165 const [state, dispatch] = (0,external_wp_element_namespaceObject.useReducer)(use_rich_url_data_reducer, { 23166 richData: null, 23167 isFetching: false 23168 }); 23169 const { 23170 fetchRichUrlData 23171 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 23172 const { 23173 getSettings 23174 } = select(store); 23175 return { 23176 fetchRichUrlData: getSettings().__experimentalFetchRichUrlData 23177 }; 23178 }, []); 23179 (0,external_wp_element_namespaceObject.useEffect)(() => { 23180 // Only make the request if we have an actual URL 23181 // and the fetching util is available. In some editors 23182 // there may not be such a util. 23183 if (url?.length && fetchRichUrlData && typeof AbortController !== 'undefined') { 23184 dispatch({ 23185 type: 'LOADING' 23186 }); 23187 const controller = new window.AbortController(); 23188 const signal = controller.signal; 23189 fetchRichUrlData(url, { 23190 signal 23191 }).then(urlData => { 23192 dispatch({ 23193 type: 'RESOLVED', 23194 richData: urlData 23195 }); 23196 }).catch(() => { 23197 // Avoid setting state on unmounted component 23198 if (!signal.aborted) { 23199 dispatch({ 23200 type: 'ERROR' 23201 }); 23202 } 23203 }); 23204 // Cleanup: when the URL changes the abort the current request. 23205 return () => { 23206 controller.abort(); 23207 }; 23208 } 23209 }, [url]); 23210 return state; 23211 } 23212 /* harmony default export */ const use_rich_url_data = (useRemoteUrlData); 23213 23214 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/link-control/link-preview.js 23215 23216 /** 23217 * External dependencies 23218 */ 23219 23220 23221 /** 23222 * WordPress dependencies 23223 */ 23224 23225 23226 23227 23228 23229 23230 23231 23232 23233 23234 /** 23235 * Internal dependencies 23236 */ 23237 23238 23239 function LinkPreview({ 23240 value, 23241 onEditClick, 23242 hasRichPreviews = false, 23243 hasUnlinkControl = false, 23244 onRemove 23245 }) { 23246 const showIconLabels = (0,external_wp_data_namespaceObject.useSelect)(select => select(external_wp_preferences_namespaceObject.store).get('core', 'showIconLabels'), []); 23247 23248 // Avoid fetching if rich previews are not desired. 23249 const showRichPreviews = hasRichPreviews ? value?.url : null; 23250 const { 23251 richData, 23252 isFetching 23253 } = use_rich_url_data(showRichPreviews); 23254 23255 // Rich data may be an empty object so test for that. 23256 const hasRichData = richData && Object.keys(richData).length; 23257 const displayURL = value && (0,external_wp_url_namespaceObject.filterURLForDisplay)((0,external_wp_url_namespaceObject.safeDecodeURI)(value.url), 24) || ''; 23258 23259 // url can be undefined if the href attribute is unset 23260 const isEmptyURL = !value?.url?.length; 23261 const displayTitle = !isEmptyURL && (0,external_wp_dom_namespaceObject.__unstableStripHTML)(richData?.title || value?.title || displayURL); 23262 let icon; 23263 if (richData?.icon) { 23264 icon = (0,external_React_.createElement)("img", { 23265 src: richData?.icon, 23266 alt: "" 23267 }); 23268 } else if (isEmptyURL) { 23269 icon = (0,external_React_.createElement)(build_module_icon, { 23270 icon: library_info, 23271 size: 32 23272 }); 23273 } else { 23274 icon = (0,external_React_.createElement)(build_module_icon, { 23275 icon: library_globe 23276 }); 23277 } 23278 const { 23279 createNotice 23280 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_notices_namespaceObject.store); 23281 const ref = (0,external_wp_compose_namespaceObject.useCopyToClipboard)(value.url, () => { 23282 createNotice('info', (0,external_wp_i18n_namespaceObject.__)('Link copied to clipboard.'), { 23283 isDismissible: true, 23284 type: 'snackbar' 23285 }); 23286 }); 23287 return (0,external_React_.createElement)("div", { 23288 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Currently selected'), 23289 className: classnames_default()('block-editor-link-control__search-item', { 23290 'is-current': true, 23291 'is-rich': hasRichData, 23292 'is-fetching': !!isFetching, 23293 'is-preview': true, 23294 'is-error': isEmptyURL, 23295 'is-url-title': displayTitle === displayURL 23296 }) 23297 }, (0,external_React_.createElement)("div", { 23298 className: "block-editor-link-control__search-item-top" 23299 }, (0,external_React_.createElement)("span", { 23300 className: "block-editor-link-control__search-item-header" 23301 }, (0,external_React_.createElement)("span", { 23302 className: classnames_default()('block-editor-link-control__search-item-icon', { 23303 'is-image': richData?.icon 23304 }) 23305 }, icon), (0,external_React_.createElement)("span", { 23306 className: "block-editor-link-control__search-item-details" 23307 }, !isEmptyURL ? (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.ExternalLink, { 23308 className: "block-editor-link-control__search-item-title", 23309 href: value.url 23310 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalTruncate, { 23311 numberOfLines: 1 23312 }, displayTitle)), value?.url && displayTitle !== displayURL && (0,external_React_.createElement)("span", { 23313 className: "block-editor-link-control__search-item-info" 23314 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalTruncate, { 23315 numberOfLines: 1 23316 }, displayURL))) : (0,external_React_.createElement)("span", { 23317 className: "block-editor-link-control__search-item-error-notice" 23318 }, (0,external_wp_i18n_namespaceObject.__)('Link is empty')))), (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 23319 icon: edit, 23320 label: (0,external_wp_i18n_namespaceObject.__)('Edit link'), 23321 onClick: onEditClick, 23322 size: "compact" 23323 }), hasUnlinkControl && (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 23324 icon: link_off, 23325 label: (0,external_wp_i18n_namespaceObject.__)('Remove link'), 23326 onClick: onRemove, 23327 size: "compact" 23328 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 23329 icon: copy_small, 23330 label: (0,external_wp_i18n_namespaceObject.sprintf)( 23331 // Translators: %s is a placeholder for the link URL and an optional colon, (if a Link URL is present). 23332 (0,external_wp_i18n_namespaceObject.__)('Copy link%s'), 23333 // Ends up looking like "Copy link: https://example.com". 23334 isEmptyURL || showIconLabels ? '' : ': ' + value.url), 23335 ref: ref, 23336 disabled: isEmptyURL, 23337 size: "compact" 23338 }), (0,external_React_.createElement)(ViewerSlot, { 23339 fillProps: value 23340 }))); 23341 } 23342 23343 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/link-control/settings.js 23344 23345 /** 23346 * WordPress dependencies 23347 */ 23348 23349 23350 const settings_noop = () => {}; 23351 const LinkControlSettings = ({ 23352 value, 23353 onChange = settings_noop, 23354 settings 23355 }) => { 23356 if (!settings || !settings.length) { 23357 return null; 23358 } 23359 const handleSettingChange = setting => newValue => { 23360 onChange({ 23361 ...value, 23362 [setting.id]: newValue 23363 }); 23364 }; 23365 const theSettings = settings.map(setting => (0,external_React_.createElement)(external_wp_components_namespaceObject.CheckboxControl, { 23366 __nextHasNoMarginBottom: true, 23367 className: "block-editor-link-control__setting", 23368 key: setting.id, 23369 label: setting.title, 23370 onChange: handleSettingChange(setting), 23371 checked: value ? !!value[setting.id] : false, 23372 help: setting?.help 23373 })); 23374 return (0,external_React_.createElement)("fieldset", { 23375 className: "block-editor-link-control__settings" 23376 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.VisuallyHidden, { 23377 as: "legend" 23378 }, (0,external_wp_i18n_namespaceObject.__)('Currently selected link settings')), theSettings); 23379 }; 23380 /* harmony default export */ const link_control_settings = (LinkControlSettings); 23381 23382 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/link-control/use-create-page.js 23383 /** 23384 * WordPress dependencies 23385 */ 23386 23387 23388 function useCreatePage(handleCreatePage) { 23389 const cancelableCreateSuggestion = (0,external_wp_element_namespaceObject.useRef)(); 23390 const [isCreatingPage, setIsCreatingPage] = (0,external_wp_element_namespaceObject.useState)(false); 23391 const [errorMessage, setErrorMessage] = (0,external_wp_element_namespaceObject.useState)(null); 23392 const createPage = async function (suggestionTitle) { 23393 setIsCreatingPage(true); 23394 setErrorMessage(null); 23395 try { 23396 // Make cancellable in order that we can avoid setting State 23397 // if the component unmounts during the call to `createSuggestion` 23398 cancelableCreateSuggestion.current = makeCancelable( 23399 // Using Promise.resolve to allow createSuggestion to return a 23400 // non-Promise based value. 23401 Promise.resolve(handleCreatePage(suggestionTitle))); 23402 return await cancelableCreateSuggestion.current.promise; 23403 } catch (error) { 23404 if (error && error.isCanceled) { 23405 return; // bail if canceled to avoid setting state 23406 } 23407 setErrorMessage(error.message || (0,external_wp_i18n_namespaceObject.__)('An unknown error occurred during creation. Please try again.')); 23408 throw error; 23409 } finally { 23410 setIsCreatingPage(false); 23411 } 23412 }; 23413 23414 /** 23415 * Handles cancelling any pending Promises that have been made cancelable. 23416 */ 23417 (0,external_wp_element_namespaceObject.useEffect)(() => { 23418 return () => { 23419 // componentDidUnmount 23420 if (cancelableCreateSuggestion.current) { 23421 cancelableCreateSuggestion.current.cancel(); 23422 } 23423 }; 23424 }, []); 23425 return { 23426 createPage, 23427 isCreatingPage, 23428 errorMessage 23429 }; 23430 } 23431 23432 /** 23433 * Creates a wrapper around a promise which allows it to be programmatically 23434 * cancelled. 23435 * See: https://reactjs.org/blog/2015/12/16/ismounted-antipattern.html 23436 * 23437 * @param {Promise} promise the Promise to make cancelable 23438 */ 23439 const makeCancelable = promise => { 23440 let hasCanceled_ = false; 23441 const wrappedPromise = new Promise((resolve, reject) => { 23442 promise.then(val => hasCanceled_ ? reject({ 23443 isCanceled: true 23444 }) : resolve(val), error => hasCanceled_ ? reject({ 23445 isCanceled: true 23446 }) : reject(error)); 23447 }); 23448 return { 23449 promise: wrappedPromise, 23450 cancel() { 23451 hasCanceled_ = true; 23452 } 23453 }; 23454 }; 23455 23456 // EXTERNAL MODULE: ./node_modules/fast-deep-equal/index.js 23457 var fast_deep_equal = __webpack_require__(5215); 23458 var fast_deep_equal_default = /*#__PURE__*/__webpack_require__.n(fast_deep_equal); 23459 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/link-control/use-internal-value.js 23460 /** 23461 * WordPress dependencies 23462 */ 23463 23464 23465 /** 23466 * External dependencies 23467 */ 23468 23469 function useInternalValue(value) { 23470 const [internalValue, setInternalValue] = (0,external_wp_element_namespaceObject.useState)(value || {}); 23471 const [previousValue, setPreviousValue] = (0,external_wp_element_namespaceObject.useState)(value); 23472 23473 // If the value prop changes, update the internal state. 23474 // See: 23475 // - https://github.com/WordPress/gutenberg/pull/51387#issuecomment-1722927384. 23476 // - https://react.dev/reference/react/useState#storing-information-from-previous-renders. 23477 if (!fast_deep_equal_default()(value, previousValue)) { 23478 setPreviousValue(value); 23479 setInternalValue(value); 23480 } 23481 const setInternalURLInputValue = nextValue => { 23482 setInternalValue({ 23483 ...internalValue, 23484 url: nextValue 23485 }); 23486 }; 23487 const setInternalTextInputValue = nextValue => { 23488 setInternalValue({ 23489 ...internalValue, 23490 title: nextValue 23491 }); 23492 }; 23493 const createSetInternalSettingValueHandler = settingsKeys => nextValue => { 23494 // Only apply settings values which are defined in the settings prop. 23495 const settingsUpdates = Object.keys(nextValue).reduce((acc, key) => { 23496 if (settingsKeys.includes(key)) { 23497 acc[key] = nextValue[key]; 23498 } 23499 return acc; 23500 }, {}); 23501 setInternalValue({ 23502 ...internalValue, 23503 ...settingsUpdates 23504 }); 23505 }; 23506 return [internalValue, setInternalValue, setInternalURLInputValue, setInternalTextInputValue, createSetInternalSettingValueHandler]; 23507 } 23508 23509 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/link-control/index.js 23510 23511 /** 23512 * External dependencies 23513 */ 23514 23515 23516 /** 23517 * WordPress dependencies 23518 */ 23519 23520 23521 23522 23523 23524 23525 23526 23527 23528 23529 /** 23530 * Internal dependencies 23531 */ 23532 23533 23534 23535 23536 23537 23538 23539 23540 23541 /** 23542 * Default properties associated with a link control value. 23543 * 23544 * @typedef WPLinkControlDefaultValue 23545 * 23546 * @property {string} url Link URL. 23547 * @property {string=} title Link title. 23548 * @property {boolean=} opensInNewTab Whether link should open in a new browser 23549 * tab. This value is only assigned if not 23550 * providing a custom `settings` prop. 23551 */ 23552 23553 /* eslint-disable jsdoc/valid-types */ 23554 /** 23555 * Custom settings values associated with a link. 23556 * 23557 * @typedef {{[setting:string]:any}} WPLinkControlSettingsValue 23558 */ 23559 /* eslint-enable */ 23560 23561 /** 23562 * Custom settings values associated with a link. 23563 * 23564 * @typedef WPLinkControlSetting 23565 * 23566 * @property {string} id Identifier to use as property for setting value. 23567 * @property {string} title Human-readable label to show in user interface. 23568 */ 23569 23570 /** 23571 * Properties associated with a link control value, composed as a union of the 23572 * default properties and any custom settings values. 23573 * 23574 * @typedef {WPLinkControlDefaultValue&WPLinkControlSettingsValue} WPLinkControlValue 23575 */ 23576 23577 /** @typedef {(nextValue:WPLinkControlValue)=>void} WPLinkControlOnChangeProp */ 23578 23579 /** 23580 * Properties associated with a search suggestion used within the LinkControl. 23581 * 23582 * @typedef WPLinkControlSuggestion 23583 * 23584 * @property {string} id Identifier to use to uniquely identify the suggestion. 23585 * @property {string} type Identifies the type of the suggestion (eg: `post`, 23586 * `page`, `url`...etc) 23587 * @property {string} title Human-readable label to show in user interface. 23588 * @property {string} url A URL for the suggestion. 23589 */ 23590 23591 /** @typedef {(title:string)=>WPLinkControlSuggestion} WPLinkControlCreateSuggestionProp */ 23592 23593 /** 23594 * @typedef WPLinkControlProps 23595 * 23596 * @property {(WPLinkControlSetting[])=} settings An array of settings objects. Each object will used to 23597 * render a `ToggleControl` for that setting. 23598 * @property {boolean=} forceIsEditingLink If passed as either `true` or `false`, controls the 23599 * internal editing state of the component to respective 23600 * show or not show the URL input field. 23601 * @property {WPLinkControlValue=} value Current link value. 23602 * @property {WPLinkControlOnChangeProp=} onChange Value change handler, called with the updated value if 23603 * the user selects a new link or updates settings. 23604 * @property {boolean=} noDirectEntry Whether to allow turning a URL-like search query directly into a link. 23605 * @property {boolean=} showSuggestions Whether to present suggestions when typing the URL. 23606 * @property {boolean=} showInitialSuggestions Whether to present initial suggestions immediately. 23607 * @property {boolean=} withCreateSuggestion Whether to allow creation of link value from suggestion. 23608 * @property {Object=} suggestionsQuery Query parameters to pass along to wp.blockEditor.__experimentalFetchLinkSuggestions. 23609 * @property {boolean=} noURLSuggestion Whether to add a fallback suggestion which treats the search query as a URL. 23610 * @property {boolean=} hasTextControl Whether to add a text field to the UI to update the value.title. 23611 * @property {string|Function|undefined} createSuggestionButtonText The text to use in the button that calls createSuggestion. 23612 * @property {Function} renderControlBottom Optional controls to be rendered at the bottom of the component. 23613 */ 23614 23615 const link_control_noop = () => {}; 23616 const PREFERENCE_SCOPE = 'core/block-editor'; 23617 const PREFERENCE_KEY = 'linkControlSettingsDrawer'; 23618 23619 /** 23620 * Renders a link control. A link control is a controlled input which maintains 23621 * a value associated with a link (HTML anchor element) and relevant settings 23622 * for how that link is expected to behave. 23623 * 23624 * @param {WPLinkControlProps} props Component props. 23625 */ 23626 function LinkControl({ 23627 searchInputPlaceholder, 23628 value, 23629 settings = DEFAULT_LINK_SETTINGS, 23630 onChange = link_control_noop, 23631 onRemove, 23632 onCancel, 23633 noDirectEntry = false, 23634 showSuggestions = true, 23635 showInitialSuggestions, 23636 forceIsEditingLink, 23637 createSuggestion, 23638 withCreateSuggestion, 23639 inputValue: propInputValue = '', 23640 suggestionsQuery = {}, 23641 noURLSuggestion = false, 23642 createSuggestionButtonText, 23643 hasRichPreviews = false, 23644 hasTextControl = false, 23645 renderControlBottom = null 23646 }) { 23647 if (withCreateSuggestion === undefined && createSuggestion) { 23648 withCreateSuggestion = true; 23649 } 23650 const [settingsOpen, setSettingsOpen] = (0,external_wp_element_namespaceObject.useState)(false); 23651 const { 23652 advancedSettingsPreference 23653 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 23654 var _prefsStore$get; 23655 const prefsStore = select(external_wp_preferences_namespaceObject.store); 23656 return { 23657 advancedSettingsPreference: (_prefsStore$get = prefsStore.get(PREFERENCE_SCOPE, PREFERENCE_KEY)) !== null && _prefsStore$get !== void 0 ? _prefsStore$get : false 23658 }; 23659 }, []); 23660 const { 23661 set: setPreference 23662 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_preferences_namespaceObject.store); 23663 23664 /** 23665 * Sets the open/closed state of the Advanced Settings Drawer, 23666 * optionlly persisting the state to the user's preferences. 23667 * 23668 * Note that Block Editor components can be consumed by non-WordPress 23669 * environments which may not have preferences setup. 23670 * Therefore a local state is also used as a fallback. 23671 * 23672 * @param {boolean} prefVal the open/closed state of the Advanced Settings Drawer. 23673 */ 23674 const setSettingsOpenWithPreference = prefVal => { 23675 if (setPreference) { 23676 setPreference(PREFERENCE_SCOPE, PREFERENCE_KEY, prefVal); 23677 } 23678 setSettingsOpen(prefVal); 23679 }; 23680 23681 // Block Editor components can be consumed by non-WordPress environments 23682 // which may not have these preferences setup. 23683 // Therefore a local state is used as a fallback. 23684 const isSettingsOpen = advancedSettingsPreference || settingsOpen; 23685 const isMounting = (0,external_wp_element_namespaceObject.useRef)(true); 23686 const wrapperNode = (0,external_wp_element_namespaceObject.useRef)(); 23687 const textInputRef = (0,external_wp_element_namespaceObject.useRef)(); 23688 const isEndingEditWithFocus = (0,external_wp_element_namespaceObject.useRef)(false); 23689 const settingsKeys = settings.map(({ 23690 id 23691 }) => id); 23692 const [internalControlValue, setInternalControlValue, setInternalURLInputValue, setInternalTextInputValue, createSetInternalSettingValueHandler] = useInternalValue(value); 23693 const valueHasChanges = value && !(0,external_wp_isShallowEqual_namespaceObject.isShallowEqualObjects)(internalControlValue, value); 23694 const [isEditingLink, setIsEditingLink] = (0,external_wp_element_namespaceObject.useState)(forceIsEditingLink !== undefined ? forceIsEditingLink : !value || !value.url); 23695 const { 23696 createPage, 23697 isCreatingPage, 23698 errorMessage 23699 } = useCreatePage(createSuggestion); 23700 (0,external_wp_element_namespaceObject.useEffect)(() => { 23701 if (forceIsEditingLink === undefined) { 23702 return; 23703 } 23704 setIsEditingLink(forceIsEditingLink); 23705 }, [forceIsEditingLink]); 23706 (0,external_wp_element_namespaceObject.useEffect)(() => { 23707 // We don't auto focus into the Link UI on mount 23708 // because otherwise using the keyboard to select text 23709 // *within* the link format is not possible. 23710 if (isMounting.current) { 23711 isMounting.current = false; 23712 return; 23713 } 23714 23715 // Scenario - when: 23716 // - switching between editable and non editable LinkControl 23717 // - clicking on a link 23718 // ...then move focus to the *first* element to avoid focus loss 23719 // and to ensure focus is *within* the Link UI. 23720 const nextFocusTarget = external_wp_dom_namespaceObject.focus.focusable.find(wrapperNode.current)[0] || wrapperNode.current; 23721 nextFocusTarget.focus(); 23722 isEndingEditWithFocus.current = false; 23723 }, [isEditingLink, isCreatingPage]); 23724 const hasLinkValue = value?.url?.trim()?.length > 0; 23725 23726 /** 23727 * Cancels editing state and marks that focus may need to be restored after 23728 * the next render, if focus was within the wrapper when editing finished. 23729 */ 23730 const stopEditing = () => { 23731 isEndingEditWithFocus.current = !!wrapperNode.current?.contains(wrapperNode.current.ownerDocument.activeElement); 23732 setIsEditingLink(false); 23733 }; 23734 const handleSelectSuggestion = updatedValue => { 23735 // Suggestions may contains "settings" values (e.g. `opensInNewTab`) 23736 // which should not overide any existing settings values set by the 23737 // user. This filters out any settings values from the suggestion. 23738 const nonSettingsChanges = Object.keys(updatedValue).reduce((acc, key) => { 23739 if (!settingsKeys.includes(key)) { 23740 acc[key] = updatedValue[key]; 23741 } 23742 return acc; 23743 }, {}); 23744 onChange({ 23745 ...internalControlValue, 23746 ...nonSettingsChanges, 23747 // As title is not a setting, it must be manually applied 23748 // in such a way as to preserve the users changes over 23749 // any "title" value provided by the "suggestion". 23750 title: internalControlValue?.title || updatedValue?.title 23751 }); 23752 stopEditing(); 23753 }; 23754 const handleSubmit = () => { 23755 if (valueHasChanges) { 23756 // Submit the original value with new stored values applied 23757 // on top. URL is a special case as it may also be a prop. 23758 onChange({ 23759 ...value, 23760 ...internalControlValue, 23761 url: currentUrlInputValue 23762 }); 23763 } 23764 stopEditing(); 23765 }; 23766 const handleSubmitWithEnter = event => { 23767 const { 23768 keyCode 23769 } = event; 23770 if (keyCode === external_wp_keycodes_namespaceObject.ENTER && !currentInputIsEmpty // Disallow submitting empty values. 23771 ) { 23772 event.preventDefault(); 23773 handleSubmit(); 23774 } 23775 }; 23776 const resetInternalValues = () => { 23777 setInternalControlValue(value); 23778 }; 23779 const handleCancel = event => { 23780 event.preventDefault(); 23781 event.stopPropagation(); 23782 23783 // Ensure that any unsubmitted input changes are reset. 23784 resetInternalValues(); 23785 if (hasLinkValue) { 23786 // If there is a link then exist editing mode and show preview. 23787 stopEditing(); 23788 } else { 23789 // If there is no link value, then remove the link entirely. 23790 onRemove?.(); 23791 } 23792 onCancel?.(); 23793 }; 23794 const currentUrlInputValue = propInputValue || internalControlValue?.url || ''; 23795 const currentInputIsEmpty = !currentUrlInputValue?.trim()?.length; 23796 const shownUnlinkControl = onRemove && value && !isEditingLink && !isCreatingPage; 23797 const showActions = isEditingLink && hasLinkValue; 23798 23799 // Only show text control once a URL value has been committed 23800 // and it isn't just empty whitespace. 23801 // See https://github.com/WordPress/gutenberg/pull/33849/#issuecomment-932194927. 23802 const showTextControl = hasLinkValue && hasTextControl; 23803 const isEditing = (isEditingLink || !value) && !isCreatingPage; 23804 const isDisabled = !valueHasChanges || currentInputIsEmpty; 23805 const showSettings = !!settings?.length && isEditingLink && hasLinkValue; 23806 return (0,external_React_.createElement)("div", { 23807 tabIndex: -1, 23808 ref: wrapperNode, 23809 className: "block-editor-link-control" 23810 }, isCreatingPage && (0,external_React_.createElement)("div", { 23811 className: "block-editor-link-control__loading" 23812 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Spinner, null), " ", (0,external_wp_i18n_namespaceObject.__)('Creating'), "\u2026"), isEditing && (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)("div", { 23813 className: classnames_default()({ 23814 'block-editor-link-control__search-input-wrapper': true, 23815 'has-text-control': showTextControl, 23816 'has-actions': showActions 23817 }) 23818 }, showTextControl && (0,external_React_.createElement)(external_wp_components_namespaceObject.TextControl, { 23819 __nextHasNoMarginBottom: true, 23820 ref: textInputRef, 23821 className: "block-editor-link-control__field block-editor-link-control__text-content", 23822 label: (0,external_wp_i18n_namespaceObject.__)('Text'), 23823 value: internalControlValue?.title, 23824 onChange: setInternalTextInputValue, 23825 onKeyDown: handleSubmitWithEnter, 23826 size: "__unstable-large" 23827 }), (0,external_React_.createElement)(search_input, { 23828 currentLink: value, 23829 className: "block-editor-link-control__field block-editor-link-control__search-input", 23830 placeholder: searchInputPlaceholder, 23831 value: currentUrlInputValue, 23832 withCreateSuggestion: withCreateSuggestion, 23833 onCreateSuggestion: createPage, 23834 onChange: setInternalURLInputValue, 23835 onSelect: handleSelectSuggestion, 23836 showInitialSuggestions: showInitialSuggestions, 23837 allowDirectEntry: !noDirectEntry, 23838 showSuggestions: showSuggestions, 23839 suggestionsQuery: suggestionsQuery, 23840 withURLSuggestion: !noURLSuggestion, 23841 createSuggestionButtonText: createSuggestionButtonText, 23842 hideLabelFromVision: !showTextControl 23843 }), !showActions && (0,external_React_.createElement)("div", { 23844 className: "block-editor-link-control__search-enter" 23845 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 23846 onClick: isDisabled ? link_control_noop : handleSubmit, 23847 label: (0,external_wp_i18n_namespaceObject.__)('Submit'), 23848 icon: keyboard_return, 23849 className: "block-editor-link-control__search-submit", 23850 "aria-disabled": isDisabled 23851 }))), errorMessage && (0,external_React_.createElement)(external_wp_components_namespaceObject.Notice, { 23852 className: "block-editor-link-control__search-error", 23853 status: "error", 23854 isDismissible: false 23855 }, errorMessage)), value && !isEditingLink && !isCreatingPage && (0,external_React_.createElement)(LinkPreview, { 23856 key: value?.url // force remount when URL changes to avoid race conditions for rich previews 23857 , 23858 value: value, 23859 onEditClick: () => setIsEditingLink(true), 23860 hasRichPreviews: hasRichPreviews, 23861 hasUnlinkControl: shownUnlinkControl, 23862 onRemove: () => { 23863 onRemove(); 23864 setIsEditingLink(true); 23865 } 23866 }), showSettings && (0,external_React_.createElement)("div", { 23867 className: "block-editor-link-control__tools" 23868 }, !currentInputIsEmpty && (0,external_React_.createElement)(settings_drawer, { 23869 settingsOpen: isSettingsOpen, 23870 setSettingsOpen: setSettingsOpenWithPreference 23871 }, (0,external_React_.createElement)(link_control_settings, { 23872 value: internalControlValue, 23873 settings: settings, 23874 onChange: createSetInternalSettingValueHandler(settingsKeys) 23875 }))), showActions && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, { 23876 justify: "right", 23877 className: "block-editor-link-control__search-actions" 23878 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 23879 variant: "tertiary", 23880 onClick: handleCancel 23881 }, (0,external_wp_i18n_namespaceObject.__)('Cancel')), (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 23882 variant: "primary", 23883 onClick: isDisabled ? link_control_noop : handleSubmit, 23884 className: "block-editor-link-control__search-submit", 23885 "aria-disabled": isDisabled 23886 }, (0,external_wp_i18n_namespaceObject.__)('Save'))), !isCreatingPage && renderControlBottom && renderControlBottom()); 23887 } 23888 LinkControl.ViewerFill = ViewerFill; 23889 LinkControl.DEFAULT_LINK_SETTINGS = DEFAULT_LINK_SETTINGS; 23890 /* harmony default export */ const link_control = (LinkControl); 23891 23892 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/media-replace-flow/index.js 23893 23894 /** 23895 * External dependencies 23896 */ 23897 23898 23899 /** 23900 * WordPress dependencies 23901 */ 23902 23903 23904 23905 23906 23907 23908 23909 23910 23911 23912 23913 /** 23914 * Internal dependencies 23915 */ 23916 23917 23918 23919 23920 const media_replace_flow_noop = () => {}; 23921 let uniqueId = 0; 23922 const MediaReplaceFlow = ({ 23923 mediaURL, 23924 mediaId, 23925 mediaIds, 23926 allowedTypes, 23927 accept, 23928 onError, 23929 onSelect, 23930 onSelectURL, 23931 onToggleFeaturedImage, 23932 useFeaturedImage, 23933 onFilesUpload = media_replace_flow_noop, 23934 name = (0,external_wp_i18n_namespaceObject.__)('Replace'), 23935 createNotice, 23936 removeNotice, 23937 children, 23938 multiple = false, 23939 addToGallery, 23940 handleUpload = true, 23941 popoverProps 23942 }) => { 23943 const mediaUpload = (0,external_wp_data_namespaceObject.useSelect)(select => { 23944 return select(store).getSettings().mediaUpload; 23945 }, []); 23946 const canUpload = !!mediaUpload; 23947 const editMediaButtonRef = (0,external_wp_element_namespaceObject.useRef)(); 23948 const errorNoticeID = `block-editor/media-replace-flow/error-notice/${++uniqueId}`; 23949 const onUploadError = message => { 23950 const safeMessage = (0,external_wp_dom_namespaceObject.__unstableStripHTML)(message); 23951 if (onError) { 23952 onError(safeMessage); 23953 return; 23954 } 23955 // We need to set a timeout for showing the notice 23956 // so that VoiceOver and possibly other screen readers 23957 // can announce the error afer the toolbar button 23958 // regains focus once the upload dialog closes. 23959 // Otherwise VO simply skips over the notice and announces 23960 // the focused element and the open menu. 23961 setTimeout(() => { 23962 createNotice('error', safeMessage, { 23963 speak: true, 23964 id: errorNoticeID, 23965 isDismissible: true 23966 }); 23967 }, 1000); 23968 }; 23969 const selectMedia = (media, closeMenu) => { 23970 if (useFeaturedImage && onToggleFeaturedImage) { 23971 onToggleFeaturedImage(); 23972 } 23973 closeMenu(); 23974 // Calling `onSelect` after the state update since it might unmount the component. 23975 onSelect(media); 23976 (0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.__)('The media file has been replaced')); 23977 removeNotice(errorNoticeID); 23978 }; 23979 const uploadFiles = (event, closeMenu) => { 23980 const files = event.target.files; 23981 if (!handleUpload) { 23982 closeMenu(); 23983 return onSelect(files); 23984 } 23985 onFilesUpload(files); 23986 mediaUpload({ 23987 allowedTypes, 23988 filesList: files, 23989 onFileChange: ([media]) => { 23990 selectMedia(media, closeMenu); 23991 }, 23992 onError: onUploadError 23993 }); 23994 }; 23995 const openOnArrowDown = event => { 23996 if (event.keyCode === external_wp_keycodes_namespaceObject.DOWN) { 23997 event.preventDefault(); 23998 event.target.click(); 23999 } 24000 }; 24001 const onlyAllowsImages = () => { 24002 if (!allowedTypes || allowedTypes.length === 0) { 24003 return false; 24004 } 24005 return allowedTypes.every(allowedType => allowedType === 'image' || allowedType.startsWith('image/')); 24006 }; 24007 const gallery = multiple && onlyAllowsImages(); 24008 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Dropdown, { 24009 popoverProps: popoverProps, 24010 contentClassName: "block-editor-media-replace-flow__options", 24011 renderToggle: ({ 24012 isOpen, 24013 onToggle 24014 }) => (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarButton, { 24015 ref: editMediaButtonRef, 24016 "aria-expanded": isOpen, 24017 "aria-haspopup": "true", 24018 onClick: onToggle, 24019 onKeyDown: openOnArrowDown 24020 }, name), 24021 renderContent: ({ 24022 onClose 24023 }) => (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.NavigableMenu, { 24024 className: "block-editor-media-replace-flow__media-upload-menu" 24025 }, (0,external_React_.createElement)(check, null, (0,external_React_.createElement)(media_upload, { 24026 gallery: gallery, 24027 addToGallery: addToGallery, 24028 multiple: multiple, 24029 value: multiple ? mediaIds : mediaId, 24030 onSelect: media => selectMedia(media, onClose), 24031 allowedTypes: allowedTypes, 24032 render: ({ 24033 open 24034 }) => (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 24035 icon: library_media, 24036 onClick: open 24037 }, (0,external_wp_i18n_namespaceObject.__)('Open Media Library')) 24038 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.FormFileUpload, { 24039 onChange: event => { 24040 uploadFiles(event, onClose); 24041 }, 24042 accept: accept, 24043 multiple: !!multiple, 24044 render: ({ 24045 openFileDialog 24046 }) => { 24047 return (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 24048 icon: library_upload, 24049 onClick: () => { 24050 openFileDialog(); 24051 } 24052 }, (0,external_wp_i18n_namespaceObject.__)('Upload')); 24053 } 24054 })), onToggleFeaturedImage && (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 24055 icon: post_featured_image, 24056 onClick: onToggleFeaturedImage, 24057 isPressed: useFeaturedImage 24058 }, (0,external_wp_i18n_namespaceObject.__)('Use featured image')), children), onSelectURL && 24059 // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions 24060 (0,external_React_.createElement)("form", { 24061 className: classnames_default()('block-editor-media-flow__url-input', { 24062 'has-siblings': canUpload || onToggleFeaturedImage 24063 }) 24064 }, (0,external_React_.createElement)("span", { 24065 className: "block-editor-media-replace-flow__image-url-label" 24066 }, (0,external_wp_i18n_namespaceObject.__)('Current media URL:')), (0,external_React_.createElement)(link_control, { 24067 value: { 24068 url: mediaURL 24069 }, 24070 settings: [], 24071 showSuggestions: false, 24072 onChange: ({ 24073 url 24074 }) => { 24075 onSelectURL(url); 24076 editMediaButtonRef.current.focus(); 24077 } 24078 }))) 24079 }); 24080 }; 24081 24082 /** 24083 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/media-replace-flow/README.md 24084 */ 24085 /* harmony default export */ const media_replace_flow = ((0,external_wp_compose_namespaceObject.compose)([(0,external_wp_data_namespaceObject.withDispatch)(dispatch => { 24086 const { 24087 createNotice, 24088 removeNotice 24089 } = dispatch(external_wp_notices_namespaceObject.store); 24090 return { 24091 createNotice, 24092 removeNotice 24093 }; 24094 }), (0,external_wp_components_namespaceObject.withFilters)('editor.MediaReplaceFlow')])(MediaReplaceFlow)); 24095 24096 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/background.js 24097 24098 /** 24099 * External dependencies 24100 */ 24101 24102 24103 /** 24104 * WordPress dependencies 24105 */ 24106 24107 24108 24109 24110 24111 24112 24113 24114 24115 24116 /** 24117 * Internal dependencies 24118 */ 24119 24120 24121 24122 24123 24124 const BACKGROUND_SUPPORT_KEY = 'background'; 24125 const IMAGE_BACKGROUND_TYPE = 'image'; 24126 24127 /** 24128 * Checks if there is a current value in the background image block support 24129 * attributes. 24130 * 24131 * @param {Object} style Style attribute. 24132 * @return {boolean} Whether or not the block has a background image value set. 24133 */ 24134 function hasBackgroundImageValue(style) { 24135 const hasValue = !!style?.background?.backgroundImage?.id || !!style?.background?.backgroundImage?.url; 24136 return hasValue; 24137 } 24138 24139 /** 24140 * Checks if there is a current value in the background size block support 24141 * attributes. Background size values include background size as well 24142 * as background position. 24143 * 24144 * @param {Object} style Style attribute. 24145 * @return {boolean} Whether or not the block has a background size value set. 24146 */ 24147 function hasBackgroundSizeValue(style) { 24148 return style?.background?.backgroundPosition !== undefined || style?.background?.backgroundSize !== undefined; 24149 } 24150 24151 /** 24152 * Determine whether there is block support for background. 24153 * 24154 * @param {string} blockName Block name. 24155 * @param {string} feature Background image feature to check for. 24156 * 24157 * @return {boolean} Whether there is support. 24158 */ 24159 function hasBackgroundSupport(blockName, feature = 'any') { 24160 if (external_wp_element_namespaceObject.Platform.OS !== 'web') { 24161 return false; 24162 } 24163 const support = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockName, BACKGROUND_SUPPORT_KEY); 24164 if (support === true) { 24165 return true; 24166 } 24167 if (feature === 'any') { 24168 return !!support?.backgroundImage || !!support?.backgroundSize || !!support?.backgroundRepeat; 24169 } 24170 return !!support?.[feature]; 24171 } 24172 24173 /** 24174 * Resets the background image block support attributes. This can be used when disabling 24175 * the background image controls for a block via a `ToolsPanel`. 24176 * 24177 * @param {Object} style Style attribute. 24178 * @param {Function} setAttributes Function to set block's attributes. 24179 */ 24180 function resetBackgroundImage(style = {}, setAttributes) { 24181 setAttributes({ 24182 style: utils_cleanEmptyObject({ 24183 ...style, 24184 background: { 24185 ...style?.background, 24186 backgroundImage: undefined 24187 } 24188 }) 24189 }); 24190 } 24191 24192 /** 24193 * Resets the background size block support attributes. This can be used when disabling 24194 * the background size controls for a block via a `ToolsPanel`. 24195 * 24196 * @param {Object} style Style attribute. 24197 * @param {Function} setAttributes Function to set block's attributes. 24198 */ 24199 function resetBackgroundSize(style = {}, setAttributes) { 24200 setAttributes({ 24201 style: utils_cleanEmptyObject({ 24202 ...style, 24203 background: { 24204 ...style?.background, 24205 backgroundPosition: undefined, 24206 backgroundRepeat: undefined, 24207 backgroundSize: undefined 24208 } 24209 }) 24210 }); 24211 } 24212 24213 /** 24214 * Generates a CSS class name if an background image is set. 24215 * 24216 * @param {Object} style A block's style attribute. 24217 * 24218 * @return {string} CSS class name. 24219 */ 24220 function getBackgroundImageClasses(style) { 24221 return hasBackgroundImageValue(style) ? 'has-background' : ''; 24222 } 24223 function InspectorImagePreview({ 24224 label, 24225 filename, 24226 url: imgUrl 24227 }) { 24228 const imgLabel = label || (0,external_wp_url_namespaceObject.getFilename)(imgUrl); 24229 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalItemGroup, { 24230 as: "span" 24231 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, { 24232 justify: "flex-start", 24233 as: "span" 24234 }, (0,external_React_.createElement)("span", { 24235 className: classnames_default()('block-editor-hooks__background__inspector-image-indicator-wrapper', { 24236 'has-image': imgUrl 24237 }), 24238 "aria-hidden": true 24239 }, imgUrl && (0,external_React_.createElement)("span", { 24240 className: "block-editor-hooks__background__inspector-image-indicator", 24241 style: { 24242 backgroundImage: `url($imgUrl})` 24243 } 24244 })), (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexItem, { 24245 as: "span" 24246 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalTruncate, { 24247 numberOfLines: 1, 24248 className: "block-editor-hooks__background__inspector-media-replace-title" 24249 }, imgLabel), (0,external_React_.createElement)(external_wp_components_namespaceObject.VisuallyHidden, { 24250 as: "span" 24251 }, filename ? (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: file name */ 24252 (0,external_wp_i18n_namespaceObject.__)('Selected image: %s'), filename) : (0,external_wp_i18n_namespaceObject.__)('No image selected'))))); 24253 } 24254 function BackgroundImagePanelItem({ 24255 clientId, 24256 isShownByDefault, 24257 setAttributes 24258 }) { 24259 const { 24260 style, 24261 mediaUpload 24262 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 24263 const { 24264 getBlockAttributes, 24265 getSettings 24266 } = select(store); 24267 return { 24268 style: getBlockAttributes(clientId)?.style, 24269 mediaUpload: getSettings().mediaUpload 24270 }; 24271 }, [clientId]); 24272 const { 24273 id, 24274 title, 24275 url 24276 } = style?.background?.backgroundImage || {}; 24277 const replaceContainerRef = (0,external_wp_element_namespaceObject.useRef)(); 24278 const { 24279 createErrorNotice 24280 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_notices_namespaceObject.store); 24281 const onUploadError = message => { 24282 createErrorNotice(message, { 24283 type: 'snackbar' 24284 }); 24285 }; 24286 const onSelectMedia = media => { 24287 if (!media || !media.url) { 24288 const newStyle = { 24289 ...style, 24290 background: { 24291 ...style?.background, 24292 backgroundImage: undefined 24293 } 24294 }; 24295 const newAttributes = { 24296 style: utils_cleanEmptyObject(newStyle) 24297 }; 24298 setAttributes(newAttributes); 24299 return; 24300 } 24301 if ((0,external_wp_blob_namespaceObject.isBlobURL)(media.url)) { 24302 return; 24303 } 24304 24305 // For media selections originated from a file upload. 24306 if (media.media_type && media.media_type !== IMAGE_BACKGROUND_TYPE || !media.media_type && media.type && media.type !== IMAGE_BACKGROUND_TYPE) { 24307 onUploadError((0,external_wp_i18n_namespaceObject.__)('Only images can be used as a background image.')); 24308 return; 24309 } 24310 const newStyle = { 24311 ...style, 24312 background: { 24313 ...style?.background, 24314 backgroundImage: { 24315 url: media.url, 24316 id: media.id, 24317 source: 'file', 24318 title: media.title || undefined 24319 } 24320 } 24321 }; 24322 const newAttributes = { 24323 style: utils_cleanEmptyObject(newStyle) 24324 }; 24325 setAttributes(newAttributes); 24326 }; 24327 const onFilesDrop = filesList => { 24328 mediaUpload({ 24329 allowedTypes: ['image'], 24330 filesList, 24331 onFileChange([image]) { 24332 if ((0,external_wp_blob_namespaceObject.isBlobURL)(image?.url)) { 24333 return; 24334 } 24335 onSelectMedia(image); 24336 }, 24337 onError: onUploadError 24338 }); 24339 }; 24340 const resetAllFilter = (0,external_wp_element_namespaceObject.useCallback)(previousValue => { 24341 return { 24342 ...previousValue, 24343 style: { 24344 ...previousValue.style, 24345 background: undefined 24346 } 24347 }; 24348 }, []); 24349 const hasValue = hasBackgroundImageValue(style); 24350 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 24351 className: "single-column", 24352 hasValue: () => hasValue, 24353 label: (0,external_wp_i18n_namespaceObject.__)('Background image'), 24354 onDeselect: () => resetBackgroundImage(style, setAttributes), 24355 isShownByDefault: isShownByDefault, 24356 resetAllFilter: resetAllFilter, 24357 panelId: clientId 24358 }, (0,external_React_.createElement)("div", { 24359 className: "block-editor-hooks__background__inspector-media-replace-container", 24360 ref: replaceContainerRef 24361 }, (0,external_React_.createElement)(media_replace_flow, { 24362 mediaId: id, 24363 mediaURL: url, 24364 allowedTypes: [IMAGE_BACKGROUND_TYPE], 24365 accept: "image/*", 24366 onSelect: onSelectMedia, 24367 name: (0,external_React_.createElement)(InspectorImagePreview, { 24368 label: (0,external_wp_i18n_namespaceObject.__)('Background image'), 24369 filename: title, 24370 url: url 24371 }), 24372 variant: "secondary" 24373 }, hasValue && (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 24374 onClick: () => { 24375 const [toggleButton] = external_wp_dom_namespaceObject.focus.tabbable.find(replaceContainerRef.current); 24376 // Focus the toggle button and close the dropdown menu. 24377 // This ensures similar behaviour as to selecting an image, where the dropdown is 24378 // closed and focus is redirected to the dropdown toggle button. 24379 toggleButton?.focus(); 24380 toggleButton?.click(); 24381 resetBackgroundImage(style, setAttributes); 24382 } 24383 }, (0,external_wp_i18n_namespaceObject.__)('Reset '))), (0,external_React_.createElement)(external_wp_components_namespaceObject.DropZone, { 24384 onFilesDrop: onFilesDrop, 24385 label: (0,external_wp_i18n_namespaceObject.__)('Drop to upload') 24386 }))); 24387 } 24388 function backgroundSizeHelpText(value) { 24389 if (value === 'cover' || value === undefined) { 24390 return (0,external_wp_i18n_namespaceObject.__)('Image covers the space evenly.'); 24391 } 24392 if (value === 'contain') { 24393 return (0,external_wp_i18n_namespaceObject.__)('Image is contained without distortion.'); 24394 } 24395 return (0,external_wp_i18n_namespaceObject.__)('Specify a fixed width.'); 24396 } 24397 const coordsToBackgroundPosition = value => { 24398 if (!value || isNaN(value.x) && isNaN(value.y)) { 24399 return undefined; 24400 } 24401 const x = isNaN(value.x) ? 0.5 : value.x; 24402 const y = isNaN(value.y) ? 0.5 : value.y; 24403 return `${x * 100}% ${y * 100}%`; 24404 }; 24405 const backgroundPositionToCoords = value => { 24406 if (!value) { 24407 return { 24408 x: undefined, 24409 y: undefined 24410 }; 24411 } 24412 let [x, y] = value.split(' ').map(v => parseFloat(v) / 100); 24413 x = isNaN(x) ? undefined : x; 24414 y = isNaN(y) ? x : y; 24415 return { 24416 x, 24417 y 24418 }; 24419 }; 24420 function BackgroundSizePanelItem({ 24421 clientId, 24422 isShownByDefault, 24423 setAttributes 24424 }) { 24425 const style = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getBlockAttributes(clientId)?.style, [clientId]); 24426 const sizeValue = style?.background?.backgroundSize; 24427 const repeatValue = style?.background?.backgroundRepeat; 24428 24429 // An `undefined` value is treated as `cover` by the toggle group control. 24430 // An empty string is treated as `auto` by the toggle group control. This 24431 // allows a user to select "Size" and then enter a custom value, with an 24432 // empty value being treated as `auto`. 24433 const currentValueForToggle = sizeValue !== undefined && sizeValue !== 'cover' && sizeValue !== 'contain' || sizeValue === '' ? 'auto' : sizeValue || 'cover'; 24434 24435 // If the current value is `cover` and the repeat value is `undefined`, then 24436 // the toggle should be unchecked as the default state. Otherwise, the toggle 24437 // should reflect the current repeat value. 24438 const repeatCheckedValue = repeatValue === 'no-repeat' || currentValueForToggle === 'cover' && repeatValue === undefined ? false : true; 24439 const hasValue = hasBackgroundSizeValue(style); 24440 const resetAllFilter = (0,external_wp_element_namespaceObject.useCallback)(previousValue => { 24441 return { 24442 ...previousValue, 24443 style: { 24444 ...previousValue.style, 24445 background: { 24446 ...previousValue.style?.background, 24447 backgroundRepeat: undefined, 24448 backgroundSize: undefined 24449 } 24450 } 24451 }; 24452 }, []); 24453 const updateBackgroundSize = next => { 24454 // When switching to 'contain' toggle the repeat off. 24455 let nextRepeat = repeatValue; 24456 if (next === 'contain') { 24457 nextRepeat = 'no-repeat'; 24458 } 24459 if ((currentValueForToggle === 'cover' || currentValueForToggle === 'contain') && next === 'auto') { 24460 nextRepeat = undefined; 24461 } 24462 setAttributes({ 24463 style: utils_cleanEmptyObject({ 24464 ...style, 24465 background: { 24466 ...style?.background, 24467 backgroundRepeat: nextRepeat, 24468 backgroundSize: next 24469 } 24470 }) 24471 }); 24472 }; 24473 const updateBackgroundPosition = next => { 24474 setAttributes({ 24475 style: utils_cleanEmptyObject({ 24476 ...style, 24477 background: { 24478 ...style?.background, 24479 backgroundPosition: coordsToBackgroundPosition(next) 24480 } 24481 }) 24482 }); 24483 }; 24484 const toggleIsRepeated = () => { 24485 setAttributes({ 24486 style: utils_cleanEmptyObject({ 24487 ...style, 24488 background: { 24489 ...style?.background, 24490 backgroundRepeat: repeatCheckedValue === true ? 'no-repeat' : undefined 24491 } 24492 }) 24493 }); 24494 }; 24495 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalVStack, { 24496 as: external_wp_components_namespaceObject.__experimentalToolsPanelItem, 24497 spacing: 2, 24498 className: "single-column", 24499 hasValue: () => hasValue, 24500 label: (0,external_wp_i18n_namespaceObject.__)('Size'), 24501 onDeselect: () => resetBackgroundSize(style, setAttributes), 24502 isShownByDefault: isShownByDefault, 24503 resetAllFilter: resetAllFilter, 24504 panelId: clientId 24505 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.FocalPointPicker, { 24506 __next40pxDefaultSize: true, 24507 label: (0,external_wp_i18n_namespaceObject.__)('Position'), 24508 url: style?.background?.backgroundImage?.url, 24509 value: backgroundPositionToCoords(style?.background?.backgroundPosition), 24510 onChange: updateBackgroundPosition 24511 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToggleGroupControl, { 24512 size: '__unstable-large', 24513 label: (0,external_wp_i18n_namespaceObject.__)('Size'), 24514 value: currentValueForToggle, 24515 onChange: updateBackgroundSize, 24516 isBlock: true, 24517 help: backgroundSizeHelpText(sizeValue) 24518 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOption, { 24519 key: 'cover', 24520 value: 'cover', 24521 label: (0,external_wp_i18n_namespaceObject.__)('Cover') 24522 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOption, { 24523 key: 'contain', 24524 value: 'contain', 24525 label: (0,external_wp_i18n_namespaceObject.__)('Contain') 24526 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOption, { 24527 key: 'fixed', 24528 value: 'auto', 24529 label: (0,external_wp_i18n_namespaceObject.__)('Fixed') 24530 })), sizeValue !== undefined && sizeValue !== 'cover' && sizeValue !== 'contain' ? (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalUnitControl, { 24531 size: '__unstable-large', 24532 onChange: updateBackgroundSize, 24533 value: sizeValue 24534 }) : null, currentValueForToggle !== 'cover' && (0,external_React_.createElement)(external_wp_components_namespaceObject.ToggleControl, { 24535 label: (0,external_wp_i18n_namespaceObject.__)('Repeat'), 24536 checked: repeatCheckedValue, 24537 onChange: toggleIsRepeated 24538 })); 24539 } 24540 function BackgroundImagePanel(props) { 24541 const [backgroundImage, backgroundSize] = use_settings_useSettings('background.backgroundImage', 'background.backgroundSize'); 24542 if (!backgroundImage || !hasBackgroundSupport(props.name, 'backgroundImage')) { 24543 return null; 24544 } 24545 const showBackgroundSize = !!(backgroundSize && hasBackgroundSupport(props.name, 'backgroundSize')); 24546 const defaultControls = (0,external_wp_blocks_namespaceObject.getBlockSupport)(props.name, [BACKGROUND_SUPPORT_KEY, '__experimentalDefaultControls']); 24547 return (0,external_React_.createElement)(inspector_controls, { 24548 group: "background" 24549 }, (0,external_React_.createElement)(BackgroundImagePanelItem, { 24550 isShownByDefault: defaultControls?.backgroundImage, 24551 ...props 24552 }), showBackgroundSize && (0,external_React_.createElement)(BackgroundSizePanelItem, { 24553 isShownByDefault: defaultControls?.backgroundSize, 24554 ...props 24555 })); 24556 } 24557 24558 ;// CONCATENATED MODULE: ./node_modules/colord/index.mjs 24559 var r={grad:.9,turn:360,rad:360/(2*Math.PI)},t=function(r){return"string"==typeof r?r.length>0:"number"==typeof r},n=function(r,t,n){return void 0===t&&(t=0),void 0===n&&(n=Math.pow(10,t)),Math.round(n*r)/n+0},e=function(r,t,n){return void 0===t&&(t=0),void 0===n&&(n=1),r>n?n:r>t?r:t},u=function(r){return(r=isFinite(r)?r%360:0)>0?r:r+360},a=function(r){return{r:e(r.r,0,255),g:e(r.g,0,255),b:e(r.b,0,255),a:e(r.a)}},o=function(r){return{r:n(r.r),g:n(r.g),b:n(r.b),a:n(r.a,3)}},i=/^#([0-9a-f]{3,8})$/i,s=function(r){var t=r.toString(16);return t.length<2?"0"+t:t},h=function(r){var t=r.r,n=r.g,e=r.b,u=r.a,a=Math.max(t,n,e),o=a-Math.min(t,n,e),i=o?a===t?(n-e)/o:a===n?2+(e-t)/o:4+(t-n)/o:0;return{h:60*(i<0?i+6:i),s:a?o/a*100:0,v:a/255*100,a:u}},b=function(r){var t=r.h,n=r.s,e=r.v,u=r.a;t=t/360*6,n/=100,e/=100;var a=Math.floor(t),o=e*(1-n),i=e*(1-(t-a)*n),s=e*(1-(1-t+a)*n),h=a%6;return{r:255*[e,i,o,o,s,e][h],g:255*[s,e,e,i,o,o][h],b:255*[o,o,s,e,e,i][h],a:u}},g=function(r){return{h:u(r.h),s:e(r.s,0,100),l:e(r.l,0,100),a:e(r.a)}},d=function(r){return{h:n(r.h),s:n(r.s),l:n(r.l),a:n(r.a,3)}},f=function(r){return b((n=(t=r).s,{h:t.h,s:(n*=((e=t.l)<50?e:100-e)/100)>0?2*n/(e+n)*100:0,v:e+n,a:t.a}));var t,n,e},c=function(r){return{h:(t=h(r)).h,s:(u=(200-(n=t.s))*(e=t.v)/100)>0&&u<200?n*e/100/(u<=100?u:200-u)*100:0,l:u/2,a:t.a};var t,n,e,u},l=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s*,\s*([+-]?\d*\.?\d+)%\s*,\s*([+-]?\d*\.?\d+)%\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,p=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s+([+-]?\d*\.?\d+)%\s+([+-]?\d*\.?\d+)%\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,v=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,m=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,y={string:[[function(r){var t=i.exec(r);return t?(r=t[1]).length<=4?{r:parseInt(r[0]+r[0],16),g:parseInt(r[1]+r[1],16),b:parseInt(r[2]+r[2],16),a:4===r.length?n(parseInt(r[3]+r[3],16)/255,2):1}:6===r.length||8===r.length?{r:parseInt(r.substr(0,2),16),g:parseInt(r.substr(2,2),16),b:parseInt(r.substr(4,2),16),a:8===r.length?n(parseInt(r.substr(6,2),16)/255,2):1}:null:null},"hex"],[function(r){var t=v.exec(r)||m.exec(r);return t?t[2]!==t[4]||t[4]!==t[6]?null:a({r:Number(t[1])/(t[2]?100/255:1),g:Number(t[3])/(t[4]?100/255:1),b:Number(t[5])/(t[6]?100/255:1),a:void 0===t[7]?1:Number(t[7])/(t[8]?100:1)}):null},"rgb"],[function(t){var n=l.exec(t)||p.exec(t);if(!n)return null;var e,u,a=g({h:(e=n[1],u=n[2],void 0===u&&(u="deg"),Number(e)*(r[u]||1)),s:Number(n[3]),l:Number(n[4]),a:void 0===n[5]?1:Number(n[5])/(n[6]?100:1)});return f(a)},"hsl"]],object:[[function(r){var n=r.r,e=r.g,u=r.b,o=r.a,i=void 0===o?1:o;return t(n)&&t(e)&&t(u)?a({r:Number(n),g:Number(e),b:Number(u),a:Number(i)}):null},"rgb"],[function(r){var n=r.h,e=r.s,u=r.l,a=r.a,o=void 0===a?1:a;if(!t(n)||!t(e)||!t(u))return null;var i=g({h:Number(n),s:Number(e),l:Number(u),a:Number(o)});return f(i)},"hsl"],[function(r){var n=r.h,a=r.s,o=r.v,i=r.a,s=void 0===i?1:i;if(!t(n)||!t(a)||!t(o))return null;var h=function(r){return{h:u(r.h),s:e(r.s,0,100),v:e(r.v,0,100),a:e(r.a)}}({h:Number(n),s:Number(a),v:Number(o),a:Number(s)});return b(h)},"hsv"]]},N=function(r,t){for(var n=0;n<t.length;n++){var e=t[n][0](r);if(e)return[e,t[n][1]]}return[null,void 0]},x=function(r){return"string"==typeof r?N(r.trim(),y.string):"object"==typeof r&&null!==r?N(r,y.object):[null,void 0]},I=function(r){return x(r)[1]},M=function(r,t){var n=c(r);return{h:n.h,s:e(n.s+100*t,0,100),l:n.l,a:n.a}},H=function(r){return(299*r.r+587*r.g+114*r.b)/1e3/255},$=function(r,t){var n=c(r);return{h:n.h,s:n.s,l:e(n.l+100*t,0,100),a:n.a}},colord_j=function(){function r(r){this.parsed=x(r)[0],this.rgba=this.parsed||{r:0,g:0,b:0,a:1}}return r.prototype.isValid=function(){return null!==this.parsed},r.prototype.brightness=function(){return n(H(this.rgba),2)},r.prototype.isDark=function(){return H(this.rgba)<.5},r.prototype.isLight=function(){return H(this.rgba)>=.5},r.prototype.toHex=function(){return r=o(this.rgba),t=r.r,e=r.g,u=r.b,i=(a=r.a)<1?s(n(255*a)):"","#"+s(t)+s(e)+s(u)+i;var r,t,e,u,a,i},r.prototype.toRgb=function(){return o(this.rgba)},r.prototype.toRgbString=function(){return r=o(this.rgba),t=r.r,n=r.g,e=r.b,(u=r.a)<1?"rgba("+t+", "+n+", "+e+", "+u+")":"rgb("+t+", "+n+", "+e+")";var r,t,n,e,u},r.prototype.toHsl=function(){return d(c(this.rgba))},r.prototype.toHslString=function(){return r=d(c(this.rgba)),t=r.h,n=r.s,e=r.l,(u=r.a)<1?"hsla("+t+", "+n+"%, "+e+"%, "+u+")":"hsl("+t+", "+n+"%, "+e+"%)";var r,t,n,e,u},r.prototype.toHsv=function(){return r=h(this.rgba),{h:n(r.h),s:n(r.s),v:n(r.v),a:n(r.a,3)};var r},r.prototype.invert=function(){return w({r:255-(r=this.rgba).r,g:255-r.g,b:255-r.b,a:r.a});var r},r.prototype.saturate=function(r){return void 0===r&&(r=.1),w(M(this.rgba,r))},r.prototype.desaturate=function(r){return void 0===r&&(r=.1),w(M(this.rgba,-r))},r.prototype.grayscale=function(){return w(M(this.rgba,-1))},r.prototype.lighten=function(r){return void 0===r&&(r=.1),w($(this.rgba,r))},r.prototype.darken=function(r){return void 0===r&&(r=.1),w($(this.rgba,-r))},r.prototype.rotate=function(r){return void 0===r&&(r=15),this.hue(this.hue()+r)},r.prototype.alpha=function(r){return"number"==typeof r?w({r:(t=this.rgba).r,g:t.g,b:t.b,a:r}):n(this.rgba.a,3);var t},r.prototype.hue=function(r){var t=c(this.rgba);return"number"==typeof r?w({h:r,s:t.s,l:t.l,a:t.a}):n(t.h)},r.prototype.isEqual=function(r){return this.toHex()===w(r).toHex()},r}(),w=function(r){return r instanceof colord_j?r:new colord_j(r)},S=[],k=function(r){r.forEach(function(r){S.indexOf(r)<0&&(r(colord_j,y),S.push(r))})},E=function(){return new colord_j({r:255*Math.random(),g:255*Math.random(),b:255*Math.random()})}; 24560 24561 ;// CONCATENATED MODULE: ./node_modules/colord/plugins/names.mjs 24562 /* harmony default export */ function names(e,f){var a={white:"#ffffff",bisque:"#ffe4c4",blue:"#0000ff",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",antiquewhite:"#faebd7",aqua:"#00ffff",azure:"#f0ffff",whitesmoke:"#f5f5f5",papayawhip:"#ffefd5",plum:"#dda0dd",blanchedalmond:"#ffebcd",black:"#000000",gold:"#ffd700",goldenrod:"#daa520",gainsboro:"#dcdcdc",cornsilk:"#fff8dc",cornflowerblue:"#6495ed",burlywood:"#deb887",aquamarine:"#7fffd4",beige:"#f5f5dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkkhaki:"#bdb76b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",peachpuff:"#ffdab9",darkmagenta:"#8b008b",darkred:"#8b0000",darkorchid:"#9932cc",darkorange:"#ff8c00",darkslateblue:"#483d8b",gray:"#808080",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",deeppink:"#ff1493",deepskyblue:"#00bfff",wheat:"#f5deb3",firebrick:"#b22222",floralwhite:"#fffaf0",ghostwhite:"#f8f8ff",darkviolet:"#9400d3",magenta:"#ff00ff",green:"#008000",dodgerblue:"#1e90ff",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",blueviolet:"#8a2be2",forestgreen:"#228b22",lawngreen:"#7cfc00",indianred:"#cd5c5c",indigo:"#4b0082",fuchsia:"#ff00ff",brown:"#a52a2a",maroon:"#800000",mediumblue:"#0000cd",lightcoral:"#f08080",darkturquoise:"#00ced1",lightcyan:"#e0ffff",ivory:"#fffff0",lightyellow:"#ffffe0",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",linen:"#faf0e6",mediumaquamarine:"#66cdaa",lemonchiffon:"#fffacd",lime:"#00ff00",khaki:"#f0e68c",mediumseagreen:"#3cb371",limegreen:"#32cd32",mediumspringgreen:"#00fa9a",lightskyblue:"#87cefa",lightblue:"#add8e6",midnightblue:"#191970",lightpink:"#ffb6c1",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",mintcream:"#f5fffa",lightslategray:"#778899",lightslategrey:"#778899",navajowhite:"#ffdead",navy:"#000080",mediumvioletred:"#c71585",powderblue:"#b0e0e6",palegoldenrod:"#eee8aa",oldlace:"#fdf5e6",paleturquoise:"#afeeee",mediumturquoise:"#48d1cc",mediumorchid:"#ba55d3",rebeccapurple:"#663399",lightsteelblue:"#b0c4de",mediumslateblue:"#7b68ee",thistle:"#d8bfd8",tan:"#d2b48c",orchid:"#da70d6",mediumpurple:"#9370db",purple:"#800080",pink:"#ffc0cb",skyblue:"#87ceeb",springgreen:"#00ff7f",palegreen:"#98fb98",red:"#ff0000",yellow:"#ffff00",slateblue:"#6a5acd",lavenderblush:"#fff0f5",peru:"#cd853f",palevioletred:"#db7093",violet:"#ee82ee",teal:"#008080",slategray:"#708090",slategrey:"#708090",aliceblue:"#f0f8ff",darkseagreen:"#8fbc8f",darkolivegreen:"#556b2f",greenyellow:"#adff2f",seagreen:"#2e8b57",seashell:"#fff5ee",tomato:"#ff6347",silver:"#c0c0c0",sienna:"#a0522d",lavender:"#e6e6fa",lightgreen:"#90ee90",orange:"#ffa500",orangered:"#ff4500",steelblue:"#4682b4",royalblue:"#4169e1",turquoise:"#40e0d0",yellowgreen:"#9acd32",salmon:"#fa8072",saddlebrown:"#8b4513",sandybrown:"#f4a460",rosybrown:"#bc8f8f",darksalmon:"#e9967a",lightgoldenrodyellow:"#fafad2",snow:"#fffafa",lightgrey:"#d3d3d3",lightgray:"#d3d3d3",dimgray:"#696969",dimgrey:"#696969",olivedrab:"#6b8e23",olive:"#808000"},r={};for(var d in a)r[a[d]]=d;var l={};e.prototype.toName=function(f){if(!(this.rgba.a||this.rgba.r||this.rgba.g||this.rgba.b))return"transparent";var d,i,n=r[this.toHex()];if(n)return n;if(null==f?void 0:f.closest){var o=this.toRgb(),t=1/0,b="black";if(!l.length)for(var c in a)l[c]=new e(a[c]).toRgb();for(var g in a){var u=(d=o,i=l[g],Math.pow(d.r-i.r,2)+Math.pow(d.g-i.g,2)+Math.pow(d.b-i.b,2));u<t&&(t=u,b=g)}return b}};f.string.push([function(f){var r=f.toLowerCase(),d="transparent"===r?"#0000":a[r];return d?new e(d).toRgb():null},"name"])} 24563 24564 ;// CONCATENATED MODULE: ./node_modules/colord/plugins/a11y.mjs 24565 var a11y_o=function(o){var t=o/255;return t<.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)},a11y_t=function(t){return.2126*a11y_o(t.r)+.7152*a11y_o(t.g)+.0722*a11y_o(t.b)};/* harmony default export */ function a11y(o){o.prototype.luminance=function(){return o=a11y_t(this.rgba),void 0===(r=2)&&(r=0),void 0===n&&(n=Math.pow(10,r)),Math.round(n*o)/n+0;var o,r,n},o.prototype.contrast=function(r){void 0===r&&(r="#FFF");var n,a,i,e,v,u,d,c=r instanceof o?r:new o(r);return e=this.rgba,v=c.toRgb(),u=a11y_t(e),d=a11y_t(v),n=u>d?(u+.05)/(d+.05):(d+.05)/(u+.05),void 0===(a=2)&&(a=0),void 0===i&&(i=Math.pow(10,a)),Math.floor(i*n)/i+0},o.prototype.isReadable=function(o,t){return void 0===o&&(o="#FFF"),void 0===t&&(t={}),this.contrast(o)>=(e=void 0===(i=(r=t).size)?"normal":i,"AAA"===(a=void 0===(n=r.level)?"AA":n)&&"normal"===e?7:"AA"===a&&"large"===e?3:4.5);var r,n,a,i,e}} 24566 24567 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/colors/utils.js 24568 /** 24569 * External dependencies 24570 */ 24571 24572 24573 24574 24575 /** 24576 * WordPress dependencies 24577 */ 24578 24579 24580 /** 24581 * Internal dependencies 24582 */ 24583 24584 k([names, a11y]); 24585 24586 /** 24587 * Provided an array of color objects as set by the theme or by the editor defaults, 24588 * and the values of the defined color or custom color returns a color object describing the color. 24589 * 24590 * @param {Array} colors Array of color objects as set by the theme or by the editor defaults. 24591 * @param {?string} definedColor A string containing the color slug. 24592 * @param {?string} customColor A string containing the customColor value. 24593 * 24594 * @return {?Object} If definedColor is passed and the name is found in colors, 24595 * the color object exactly as set by the theme or editor defaults is returned. 24596 * Otherwise, an object that just sets the color is defined. 24597 */ 24598 const getColorObjectByAttributeValues = (colors, definedColor, customColor) => { 24599 if (definedColor) { 24600 const colorObj = colors?.find(color => color.slug === definedColor); 24601 if (colorObj) { 24602 return colorObj; 24603 } 24604 } 24605 return { 24606 color: customColor 24607 }; 24608 }; 24609 24610 /** 24611 * Provided an array of color objects as set by the theme or by the editor defaults, and a color value returns the color object matching that value or undefined. 24612 * 24613 * @param {Array} colors Array of color objects as set by the theme or by the editor defaults. 24614 * @param {?string} colorValue A string containing the color value. 24615 * 24616 * @return {?Object} Color object included in the colors array whose color property equals colorValue. 24617 * Returns undefined if no color object matches this requirement. 24618 */ 24619 const getColorObjectByColorValue = (colors, colorValue) => { 24620 return colors?.find(color => color.color === colorValue); 24621 }; 24622 24623 /** 24624 * Returns a class based on the context a color is being used and its slug. 24625 * 24626 * @param {string} colorContextName Context/place where color is being used e.g: background, text etc... 24627 * @param {string} colorSlug Slug of the color. 24628 * 24629 * @return {?string} String with the class corresponding to the color in the provided context. 24630 * Returns undefined if either colorContextName or colorSlug are not provided. 24631 */ 24632 function getColorClassName(colorContextName, colorSlug) { 24633 if (!colorContextName || !colorSlug) { 24634 return undefined; 24635 } 24636 const { 24637 kebabCase 24638 } = unlock(external_wp_components_namespaceObject.privateApis); 24639 return `has-$kebabCase(colorSlug)}-$colorContextName}`; 24640 } 24641 24642 /** 24643 * Given an array of color objects and a color value returns the color value of the most readable color in the array. 24644 * 24645 * @param {Array} colors Array of color objects as set by the theme or by the editor defaults. 24646 * @param {?string} colorValue A string containing the color value. 24647 * 24648 * @return {string} String with the color value of the most readable color. 24649 */ 24650 function getMostReadableColor(colors, colorValue) { 24651 const colordColor = w(colorValue); 24652 const getColorContrast = ({ 24653 color 24654 }) => colordColor.contrast(color); 24655 const maxContrast = Math.max(...colors.map(getColorContrast)); 24656 return colors.find(color => getColorContrast(color) === maxContrast).color; 24657 } 24658 24659 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/colors-gradients/use-multiple-origin-colors-and-gradients.js 24660 /** 24661 * WordPress dependencies 24662 */ 24663 24664 24665 24666 /** 24667 * Internal dependencies 24668 */ 24669 24670 24671 /** 24672 * Retrieves color and gradient related settings. 24673 * 24674 * The arrays for colors and gradients are made up of color palettes from each 24675 * origin i.e. "Core", "Theme", and "User". 24676 * 24677 * @return {Object} Color and gradient related settings. 24678 */ 24679 function useMultipleOriginColorsAndGradients() { 24680 const [enableCustomColors, customColors, themeColors, defaultColors, shouldDisplayDefaultColors, enableCustomGradients, customGradients, themeGradients, defaultGradients, shouldDisplayDefaultGradients] = use_settings_useSettings('color.custom', 'color.palette.custom', 'color.palette.theme', 'color.palette.default', 'color.defaultPalette', 'color.customGradient', 'color.gradients.custom', 'color.gradients.theme', 'color.gradients.default', 'color.defaultGradients'); 24681 const colorGradientSettings = { 24682 disableCustomColors: !enableCustomColors, 24683 disableCustomGradients: !enableCustomGradients 24684 }; 24685 colorGradientSettings.colors = (0,external_wp_element_namespaceObject.useMemo)(() => { 24686 const result = []; 24687 if (themeColors && themeColors.length) { 24688 result.push({ 24689 name: (0,external_wp_i18n_namespaceObject._x)('Theme', 'Indicates this palette comes from the theme.'), 24690 colors: themeColors 24691 }); 24692 } 24693 if (shouldDisplayDefaultColors && defaultColors && defaultColors.length) { 24694 result.push({ 24695 name: (0,external_wp_i18n_namespaceObject._x)('Default', 'Indicates this palette comes from WordPress.'), 24696 colors: defaultColors 24697 }); 24698 } 24699 if (customColors && customColors.length) { 24700 result.push({ 24701 name: (0,external_wp_i18n_namespaceObject._x)('Custom', 'Indicates this palette comes from the theme.'), 24702 colors: customColors 24703 }); 24704 } 24705 return result; 24706 }, [customColors, themeColors, defaultColors, shouldDisplayDefaultColors]); 24707 colorGradientSettings.gradients = (0,external_wp_element_namespaceObject.useMemo)(() => { 24708 const result = []; 24709 if (themeGradients && themeGradients.length) { 24710 result.push({ 24711 name: (0,external_wp_i18n_namespaceObject._x)('Theme', 'Indicates this palette comes from the theme.'), 24712 gradients: themeGradients 24713 }); 24714 } 24715 if (shouldDisplayDefaultGradients && defaultGradients && defaultGradients.length) { 24716 result.push({ 24717 name: (0,external_wp_i18n_namespaceObject._x)('Default', 'Indicates this palette comes from WordPress.'), 24718 gradients: defaultGradients 24719 }); 24720 } 24721 if (customGradients && customGradients.length) { 24722 result.push({ 24723 name: (0,external_wp_i18n_namespaceObject._x)('Custom', 'Indicates this palette is created by the user.'), 24724 gradients: customGradients 24725 }); 24726 } 24727 return result; 24728 }, [customGradients, themeGradients, defaultGradients, shouldDisplayDefaultGradients]); 24729 colorGradientSettings.hasColorsOrGradients = !!colorGradientSettings.colors.length || !!colorGradientSettings.gradients.length; 24730 return colorGradientSettings; 24731 } 24732 24733 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/border-radius-control/utils.js 24734 /** 24735 * WordPress dependencies 24736 */ 24737 24738 24739 /** 24740 * Gets the (non-undefined) item with the highest occurrence within an array 24741 * Based in part on: https://stackoverflow.com/a/20762713 24742 * 24743 * Undefined values are always sorted to the end by `sort`, so this function 24744 * returns the first element, to always prioritize real values over undefined 24745 * values. 24746 * 24747 * See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#description 24748 * 24749 * @param {Array<any>} inputArray Array of items to check. 24750 * @return {any} The item with the most occurrences. 24751 */ 24752 function utils_mode(inputArray) { 24753 const arr = [...inputArray]; 24754 return arr.sort((a, b) => inputArray.filter(v => v === b).length - inputArray.filter(v => v === a).length).shift(); 24755 } 24756 24757 /** 24758 * Returns the most common CSS unit from the current CSS unit selections. 24759 * 24760 * - If a single flat border radius is set, its unit will be used 24761 * - If individual corner selections, the most common of those will be used 24762 * - Failing any unit selections a default of 'px' is returned. 24763 * 24764 * @param {Object} selectedUnits Unit selections for flat radius & each corner. 24765 * @return {string} Most common CSS unit from current selections. Default: `px`. 24766 */ 24767 function getAllUnit(selectedUnits = {}) { 24768 const { 24769 flat, 24770 ...cornerUnits 24771 } = selectedUnits; 24772 return flat || utils_mode(Object.values(cornerUnits).filter(Boolean)) || 'px'; 24773 } 24774 24775 /** 24776 * Gets the 'all' input value and unit from values data. 24777 * 24778 * @param {Object|string} values Radius values. 24779 * @return {string} A value + unit for the 'all' input. 24780 */ 24781 function getAllValue(values = {}) { 24782 /** 24783 * Border radius support was originally a single pixel value. 24784 * 24785 * To maintain backwards compatibility treat this case as the all value. 24786 */ 24787 if (typeof values === 'string') { 24788 return values; 24789 } 24790 const parsedQuantitiesAndUnits = Object.values(values).map(value => (0,external_wp_components_namespaceObject.__experimentalParseQuantityAndUnitFromRawValue)(value)); 24791 const allValues = parsedQuantitiesAndUnits.map(value => { 24792 var _value$; 24793 return (_value$ = value[0]) !== null && _value$ !== void 0 ? _value$ : ''; 24794 }); 24795 const allUnits = parsedQuantitiesAndUnits.map(value => value[1]); 24796 const value = allValues.every(v => v === allValues[0]) ? allValues[0] : ''; 24797 const unit = utils_mode(allUnits); 24798 const allValue = value === 0 || value ? `$value}$unit}` : undefined; 24799 return allValue; 24800 } 24801 24802 /** 24803 * Checks to determine if values are mixed. 24804 * 24805 * @param {Object} values Radius values. 24806 * @return {boolean} Whether values are mixed. 24807 */ 24808 function hasMixedValues(values = {}) { 24809 const allValue = getAllValue(values); 24810 const isMixed = typeof values === 'string' ? false : isNaN(parseFloat(allValue)); 24811 return isMixed; 24812 } 24813 24814 /** 24815 * Checks to determine if values are defined. 24816 * 24817 * @param {Object} values Radius values. 24818 * @return {boolean} Whether values are mixed. 24819 */ 24820 function hasDefinedValues(values) { 24821 if (!values) { 24822 return false; 24823 } 24824 24825 // A string value represents a shorthand value. 24826 if (typeof values === 'string') { 24827 return true; 24828 } 24829 24830 // An object represents longhand border radius values, if any are set 24831 // flag values as being defined. 24832 const filteredValues = Object.values(values).filter(value => { 24833 return !!value || value === 0; 24834 }); 24835 return !!filteredValues.length; 24836 } 24837 24838 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/border-radius-control/all-input-control.js 24839 24840 /** 24841 * WordPress dependencies 24842 */ 24843 24844 24845 24846 /** 24847 * Internal dependencies 24848 */ 24849 24850 function AllInputControl({ 24851 onChange, 24852 selectedUnits, 24853 setSelectedUnits, 24854 values, 24855 ...props 24856 }) { 24857 let allValue = getAllValue(values); 24858 if (allValue === undefined) { 24859 // If we don't have any value set the unit to any current selection 24860 // or the most common unit from the individual radii values. 24861 allValue = getAllUnit(selectedUnits); 24862 } 24863 const hasValues = hasDefinedValues(values); 24864 const isMixed = hasValues && hasMixedValues(values); 24865 const allPlaceholder = isMixed ? (0,external_wp_i18n_namespaceObject.__)('Mixed') : null; 24866 24867 // Filter out CSS-unit-only values to prevent invalid styles. 24868 const handleOnChange = next => { 24869 const isNumeric = !isNaN(parseFloat(next)); 24870 const nextValue = isNumeric ? next : undefined; 24871 onChange(nextValue); 24872 }; 24873 24874 // Store current unit selection for use as fallback for individual 24875 // radii controls. 24876 const handleOnUnitChange = unit => { 24877 setSelectedUnits({ 24878 topLeft: unit, 24879 topRight: unit, 24880 bottomLeft: unit, 24881 bottomRight: unit 24882 }); 24883 }; 24884 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalUnitControl, { 24885 ...props, 24886 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Border radius'), 24887 disableUnits: isMixed, 24888 isOnly: true, 24889 value: allValue, 24890 onChange: handleOnChange, 24891 onUnitChange: handleOnUnitChange, 24892 placeholder: allPlaceholder, 24893 size: '__unstable-large' 24894 }); 24895 } 24896 24897 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/border-radius-control/input-controls.js 24898 24899 /** 24900 * WordPress dependencies 24901 */ 24902 24903 24904 const CORNERS = { 24905 topLeft: (0,external_wp_i18n_namespaceObject.__)('Top left'), 24906 topRight: (0,external_wp_i18n_namespaceObject.__)('Top right'), 24907 bottomLeft: (0,external_wp_i18n_namespaceObject.__)('Bottom left'), 24908 bottomRight: (0,external_wp_i18n_namespaceObject.__)('Bottom right') 24909 }; 24910 function BoxInputControls({ 24911 onChange, 24912 selectedUnits, 24913 setSelectedUnits, 24914 values: valuesProp, 24915 ...props 24916 }) { 24917 const createHandleOnChange = corner => next => { 24918 if (!onChange) { 24919 return; 24920 } 24921 24922 // Filter out CSS-unit-only values to prevent invalid styles. 24923 const isNumeric = !isNaN(parseFloat(next)); 24924 const nextValue = isNumeric ? next : undefined; 24925 onChange({ 24926 ...values, 24927 [corner]: nextValue 24928 }); 24929 }; 24930 const createHandleOnUnitChange = side => next => { 24931 const newUnits = { 24932 ...selectedUnits 24933 }; 24934 newUnits[side] = next; 24935 setSelectedUnits(newUnits); 24936 }; 24937 24938 // For shorthand style & backwards compatibility, handle flat string value. 24939 const values = typeof valuesProp !== 'string' ? valuesProp : { 24940 topLeft: valuesProp, 24941 topRight: valuesProp, 24942 bottomLeft: valuesProp, 24943 bottomRight: valuesProp 24944 }; 24945 24946 // Controls are wrapped in tooltips as visible labels aren't desired here. 24947 // Tooltip rendering also requires the UnitControl to be wrapped. See: 24948 // https://github.com/WordPress/gutenberg/pull/24966#issuecomment-685875026 24949 return (0,external_React_.createElement)("div", { 24950 className: "components-border-radius-control__input-controls-wrapper" 24951 }, Object.entries(CORNERS).map(([corner, label]) => { 24952 const [parsedQuantity, parsedUnit] = (0,external_wp_components_namespaceObject.__experimentalParseQuantityAndUnitFromRawValue)(values[corner]); 24953 const computedUnit = values[corner] ? parsedUnit : selectedUnits[corner] || selectedUnits.flat; 24954 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Tooltip, { 24955 text: label, 24956 placement: "top", 24957 key: corner 24958 }, (0,external_React_.createElement)("div", { 24959 className: "components-border-radius-control__tooltip-wrapper" 24960 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalUnitControl, { 24961 ...props, 24962 "aria-label": label, 24963 value: [parsedQuantity, computedUnit].join(''), 24964 onChange: createHandleOnChange(corner), 24965 onUnitChange: createHandleOnUnitChange(corner), 24966 size: '__unstable-large' 24967 }))); 24968 })); 24969 } 24970 24971 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/link.js 24972 24973 /** 24974 * WordPress dependencies 24975 */ 24976 24977 const link_link = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 24978 xmlns: "http://www.w3.org/2000/svg", 24979 viewBox: "0 0 24 24" 24980 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 24981 d: "M10 17.389H8.444A5.194 5.194 0 1 1 8.444 7H10v1.5H8.444a3.694 3.694 0 0 0 0 7.389H10v1.5ZM14 7h1.556a5.194 5.194 0 0 1 0 10.39H14v-1.5h1.556a3.694 3.694 0 0 0 0-7.39H14V7Zm-4.5 6h5v-1.5h-5V13Z" 24982 })); 24983 /* harmony default export */ const library_link = (link_link); 24984 24985 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/border-radius-control/linked-button.js 24986 24987 /** 24988 * WordPress dependencies 24989 */ 24990 24991 24992 24993 function LinkedButton({ 24994 isLinked, 24995 ...props 24996 }) { 24997 const label = isLinked ? (0,external_wp_i18n_namespaceObject.__)('Unlink radii') : (0,external_wp_i18n_namespaceObject.__)('Link radii'); 24998 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Tooltip, { 24999 text: label 25000 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 25001 ...props, 25002 className: "component-border-radius-control__linked-button", 25003 size: "small", 25004 icon: isLinked ? library_link : link_off, 25005 iconSize: 24, 25006 "aria-label": label 25007 })); 25008 } 25009 25010 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/border-radius-control/index.js 25011 25012 /** 25013 * WordPress dependencies 25014 */ 25015 25016 25017 25018 25019 /** 25020 * Internal dependencies 25021 */ 25022 25023 25024 25025 25026 25027 const border_radius_control_DEFAULT_VALUES = { 25028 topLeft: undefined, 25029 topRight: undefined, 25030 bottomLeft: undefined, 25031 bottomRight: undefined 25032 }; 25033 const MIN_BORDER_RADIUS_VALUE = 0; 25034 const MAX_BORDER_RADIUS_VALUES = { 25035 px: 100, 25036 em: 20, 25037 rem: 20 25038 }; 25039 25040 /** 25041 * Control to display border radius options. 25042 * 25043 * @param {Object} props Component props. 25044 * @param {Function} props.onChange Callback to handle onChange. 25045 * @param {Object} props.values Border radius values. 25046 * 25047 * @return {Element} Custom border radius control. 25048 */ 25049 function BorderRadiusControl({ 25050 onChange, 25051 values 25052 }) { 25053 const [isLinked, setIsLinked] = (0,external_wp_element_namespaceObject.useState)(!hasDefinedValues(values) || !hasMixedValues(values)); 25054 25055 // Tracking selected units via internal state allows filtering of CSS unit 25056 // only values from being saved while maintaining preexisting unit selection 25057 // behaviour. Filtering CSS unit only values prevents invalid style values. 25058 const [selectedUnits, setSelectedUnits] = (0,external_wp_element_namespaceObject.useState)({ 25059 flat: typeof values === 'string' ? (0,external_wp_components_namespaceObject.__experimentalParseQuantityAndUnitFromRawValue)(values)[1] : undefined, 25060 topLeft: (0,external_wp_components_namespaceObject.__experimentalParseQuantityAndUnitFromRawValue)(values?.topLeft)[1], 25061 topRight: (0,external_wp_components_namespaceObject.__experimentalParseQuantityAndUnitFromRawValue)(values?.topRight)[1], 25062 bottomLeft: (0,external_wp_components_namespaceObject.__experimentalParseQuantityAndUnitFromRawValue)(values?.bottomLeft)[1], 25063 bottomRight: (0,external_wp_components_namespaceObject.__experimentalParseQuantityAndUnitFromRawValue)(values?.bottomRight)[1] 25064 }); 25065 const [availableUnits] = use_settings_useSettings('spacing.units'); 25066 const units = (0,external_wp_components_namespaceObject.__experimentalUseCustomUnits)({ 25067 availableUnits: availableUnits || ['px', 'em', 'rem'] 25068 }); 25069 const unit = getAllUnit(selectedUnits); 25070 const unitConfig = units && units.find(item => item.value === unit); 25071 const step = unitConfig?.step || 1; 25072 const [allValue] = (0,external_wp_components_namespaceObject.__experimentalParseQuantityAndUnitFromRawValue)(getAllValue(values)); 25073 const toggleLinked = () => setIsLinked(!isLinked); 25074 const handleSliderChange = next => { 25075 onChange(next !== undefined ? `$next}$unit}` : undefined); 25076 }; 25077 return (0,external_React_.createElement)("fieldset", { 25078 className: "components-border-radius-control" 25079 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.BaseControl.VisualLabel, { 25080 as: "legend" 25081 }, (0,external_wp_i18n_namespaceObject.__)('Radius')), (0,external_React_.createElement)("div", { 25082 className: "components-border-radius-control__wrapper" 25083 }, isLinked ? (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(AllInputControl, { 25084 className: "components-border-radius-control__unit-control", 25085 values: values, 25086 min: MIN_BORDER_RADIUS_VALUE, 25087 onChange: onChange, 25088 selectedUnits: selectedUnits, 25089 setSelectedUnits: setSelectedUnits, 25090 units: units 25091 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.RangeControl, { 25092 label: (0,external_wp_i18n_namespaceObject.__)('Border radius'), 25093 hideLabelFromVision: true, 25094 className: "components-border-radius-control__range-control", 25095 value: allValue !== null && allValue !== void 0 ? allValue : '', 25096 min: MIN_BORDER_RADIUS_VALUE, 25097 max: MAX_BORDER_RADIUS_VALUES[unit], 25098 initialPosition: 0, 25099 withInputField: false, 25100 onChange: handleSliderChange, 25101 step: step, 25102 __nextHasNoMarginBottom: true 25103 })) : (0,external_React_.createElement)(BoxInputControls, { 25104 min: MIN_BORDER_RADIUS_VALUE, 25105 onChange: onChange, 25106 selectedUnits: selectedUnits, 25107 setSelectedUnits: setSelectedUnits, 25108 values: values || border_radius_control_DEFAULT_VALUES, 25109 units: units 25110 }), (0,external_React_.createElement)(LinkedButton, { 25111 onClick: toggleLinked, 25112 isLinked: isLinked 25113 }))); 25114 } 25115 25116 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/check.js 25117 25118 /** 25119 * WordPress dependencies 25120 */ 25121 25122 const check_check = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 25123 xmlns: "http://www.w3.org/2000/svg", 25124 viewBox: "0 0 24 24" 25125 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 25126 d: "M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z" 25127 })); 25128 /* harmony default export */ const library_check = (check_check); 25129 25130 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/shadow.js 25131 25132 /** 25133 * WordPress dependencies 25134 */ 25135 25136 const shadow = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 25137 viewBox: "0 0 24 24", 25138 xmlns: "http://www.w3.org/2000/svg" 25139 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 25140 d: "M12 8c-2.2 0-4 1.8-4 4s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4zm0 6.5c-1.4 0-2.5-1.1-2.5-2.5s1.1-2.5 2.5-2.5 2.5 1.1 2.5 2.5-1.1 2.5-2.5 2.5zM12.8 3h-1.5v3h1.5V3zm-1.6 18h1.5v-3h-1.5v3zm6.8-9.8v1.5h3v-1.5h-3zm-12 0H3v1.5h3v-1.5zm9.7 5.6 2.1 2.1 1.1-1.1-2.1-2.1-1.1 1.1zM8.3 7.2 6.2 5.1 5.1 6.2l2.1 2.1 1.1-1.1zM5.1 17.8l1.1 1.1 2.1-2.1-1.1-1.1-2.1 2.1zM18.9 6.2l-1.1-1.1-2.1 2.1 1.1 1.1 2.1-2.1z" 25141 })); 25142 /* harmony default export */ const library_shadow = (shadow); 25143 25144 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/global-styles/shadow-panel-components.js 25145 25146 /** 25147 * WordPress dependencies 25148 */ 25149 25150 25151 25152 25153 25154 /** 25155 * External dependencies 25156 */ 25157 25158 25159 /** 25160 * Internal dependencies 25161 */ 25162 25163 25164 /** 25165 * Shared reference to an empty array for cases where it is important to avoid 25166 * returning a new array reference on every invocation. 25167 * 25168 * @type {Array} 25169 */ 25170 const shadow_panel_components_EMPTY_ARRAY = []; 25171 function ShadowPopoverContainer({ 25172 shadow, 25173 onShadowChange, 25174 settings 25175 }) { 25176 const shadows = useShadowPresets(settings); 25177 return (0,external_React_.createElement)("div", { 25178 className: "block-editor-global-styles__shadow-popover-container" 25179 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalVStack, { 25180 spacing: 4 25181 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHeading, { 25182 level: 5 25183 }, (0,external_wp_i18n_namespaceObject.__)('Drop shadow')), (0,external_React_.createElement)(ShadowPresets, { 25184 presets: shadows, 25185 activeShadow: shadow, 25186 onSelect: onShadowChange 25187 }), (0,external_React_.createElement)("div", { 25188 className: "block-editor-global-styles__clear-shadow" 25189 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 25190 variant: "tertiary", 25191 onClick: () => onShadowChange(undefined) 25192 }, (0,external_wp_i18n_namespaceObject.__)('Clear'))))); 25193 } 25194 function ShadowPresets({ 25195 presets, 25196 activeShadow, 25197 onSelect 25198 }) { 25199 const { 25200 CompositeV2: Composite, 25201 useCompositeStoreV2: useCompositeStore 25202 } = unlock(external_wp_components_namespaceObject.privateApis); 25203 const compositeStore = useCompositeStore(); 25204 return !presets ? null : (0,external_React_.createElement)(Composite, { 25205 store: compositeStore, 25206 role: "listbox", 25207 className: "block-editor-global-styles__shadow__list", 25208 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Drop shadows') 25209 }, presets.map(({ 25210 name, 25211 slug, 25212 shadow 25213 }) => (0,external_React_.createElement)(ShadowIndicator, { 25214 key: slug, 25215 label: name, 25216 isActive: shadow === activeShadow, 25217 type: slug === 'unset' ? 'unset' : 'preset', 25218 onSelect: () => onSelect(shadow === activeShadow ? undefined : shadow), 25219 shadow: shadow 25220 }))); 25221 } 25222 function ShadowIndicator({ 25223 type, 25224 label, 25225 isActive, 25226 onSelect, 25227 shadow 25228 }) { 25229 const { 25230 CompositeItemV2: CompositeItem 25231 } = unlock(external_wp_components_namespaceObject.privateApis); 25232 return (0,external_React_.createElement)(CompositeItem, { 25233 role: "option", 25234 "aria-label": label, 25235 "aria-selected": isActive, 25236 className: classnames_default()('block-editor-global-styles__shadow__item', { 25237 'is-active': isActive 25238 }), 25239 render: (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 25240 className: classnames_default()('block-editor-global-styles__shadow-indicator', { 25241 unset: type === 'unset' 25242 }), 25243 onClick: onSelect, 25244 label: label, 25245 style: { 25246 boxShadow: shadow 25247 }, 25248 showTooltip: true 25249 }, isActive && (0,external_React_.createElement)(build_module_icon, { 25250 icon: library_check 25251 })) 25252 }); 25253 } 25254 function ShadowPopover({ 25255 shadow, 25256 onShadowChange, 25257 settings 25258 }) { 25259 const popoverProps = { 25260 placement: 'left-start', 25261 offset: 36, 25262 shift: true 25263 }; 25264 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Dropdown, { 25265 popoverProps: popoverProps, 25266 className: "block-editor-global-styles__shadow-dropdown", 25267 renderToggle: renderShadowToggle(), 25268 renderContent: () => (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalDropdownContentWrapper, { 25269 paddingSize: "medium" 25270 }, (0,external_React_.createElement)(ShadowPopoverContainer, { 25271 shadow: shadow, 25272 onShadowChange: onShadowChange, 25273 settings: settings 25274 })) 25275 }); 25276 } 25277 function renderShadowToggle() { 25278 return ({ 25279 onToggle, 25280 isOpen 25281 }) => { 25282 const toggleProps = { 25283 onClick: onToggle, 25284 className: classnames_default()({ 25285 'is-open': isOpen 25286 }), 25287 'aria-expanded': isOpen 25288 }; 25289 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 25290 ...toggleProps 25291 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, { 25292 justify: "flex-start" 25293 }, (0,external_React_.createElement)(build_module_icon, { 25294 className: "block-editor-global-styles__toggle-icon", 25295 icon: library_shadow, 25296 size: 24 25297 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexItem, null, (0,external_wp_i18n_namespaceObject.__)('Drop shadow')))); 25298 }; 25299 } 25300 function useShadowPresets(settings) { 25301 return (0,external_wp_element_namespaceObject.useMemo)(() => { 25302 var _settings$shadow$pres; 25303 if (!settings?.shadow) { 25304 return shadow_panel_components_EMPTY_ARRAY; 25305 } 25306 const defaultPresetsEnabled = settings?.shadow?.defaultPresets; 25307 const { 25308 default: defaultShadows, 25309 theme: themeShadows 25310 } = (_settings$shadow$pres = settings?.shadow?.presets) !== null && _settings$shadow$pres !== void 0 ? _settings$shadow$pres : {}; 25311 const unsetShadow = { 25312 name: (0,external_wp_i18n_namespaceObject.__)('Unset'), 25313 slug: 'unset', 25314 shadow: 'none' 25315 }; 25316 const shadowPresets = [...(defaultPresetsEnabled && defaultShadows || shadow_panel_components_EMPTY_ARRAY), ...(themeShadows || shadow_panel_components_EMPTY_ARRAY)]; 25317 if (shadowPresets.length) { 25318 shadowPresets.unshift(unsetShadow); 25319 } 25320 return shadowPresets; 25321 }, [settings]); 25322 } 25323 25324 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/global-styles/border-panel.js 25325 25326 /** 25327 * WordPress dependencies 25328 */ 25329 25330 25331 25332 25333 /** 25334 * Internal dependencies 25335 */ 25336 25337 25338 25339 25340 25341 25342 25343 function useHasBorderPanel(settings) { 25344 const controls = Object.values(useHasBorderPanelControls(settings)); 25345 return controls.some(Boolean); 25346 } 25347 function useHasBorderPanelControls(settings) { 25348 const controls = { 25349 hasBorderColor: useHasBorderColorControl(settings), 25350 hasBorderRadius: useHasBorderRadiusControl(settings), 25351 hasBorderStyle: useHasBorderStyleControl(settings), 25352 hasBorderWidth: useHasBorderWidthControl(settings), 25353 hasShadow: useHasShadowControl(settings) 25354 }; 25355 return controls; 25356 } 25357 function useHasBorderColorControl(settings) { 25358 return settings?.border?.color; 25359 } 25360 function useHasBorderRadiusControl(settings) { 25361 return settings?.border?.radius; 25362 } 25363 function useHasBorderStyleControl(settings) { 25364 return settings?.border?.style; 25365 } 25366 function useHasBorderWidthControl(settings) { 25367 return settings?.border?.width; 25368 } 25369 function useHasShadowControl(settings) { 25370 const shadows = useShadowPresets(settings); 25371 return !!settings?.shadow && shadows.length > 0; 25372 } 25373 function BorderToolsPanel({ 25374 resetAllFilter, 25375 onChange, 25376 value, 25377 panelId, 25378 children, 25379 label 25380 }) { 25381 const resetAll = () => { 25382 const updatedValue = resetAllFilter(value); 25383 onChange(updatedValue); 25384 }; 25385 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanel, { 25386 label: label, 25387 resetAll: resetAll, 25388 panelId: panelId, 25389 dropdownMenuProps: TOOLSPANEL_DROPDOWNMENU_PROPS 25390 }, children); 25391 } 25392 const border_panel_DEFAULT_CONTROLS = { 25393 radius: true, 25394 color: true, 25395 width: true, 25396 shadow: false 25397 }; 25398 function BorderPanel({ 25399 as: Wrapper = BorderToolsPanel, 25400 value, 25401 onChange, 25402 inheritedValue = value, 25403 settings, 25404 panelId, 25405 name, 25406 defaultControls = border_panel_DEFAULT_CONTROLS 25407 }) { 25408 var _settings$shadow$pres, _overrideOrigins; 25409 const colors = useColorsPerOrigin(settings); 25410 const decodeValue = (0,external_wp_element_namespaceObject.useCallback)(rawValue => getValueFromVariable({ 25411 settings 25412 }, '', rawValue), [settings]); 25413 const encodeColorValue = colorValue => { 25414 const allColors = colors.flatMap(({ 25415 colors: originColors 25416 }) => originColors); 25417 const colorObject = allColors.find(({ 25418 color 25419 }) => color === colorValue); 25420 return colorObject ? 'var:preset|color|' + colorObject.slug : colorValue; 25421 }; 25422 const border = (0,external_wp_element_namespaceObject.useMemo)(() => { 25423 if ((0,external_wp_components_namespaceObject.__experimentalHasSplitBorders)(inheritedValue?.border)) { 25424 const borderValue = { 25425 ...inheritedValue?.border 25426 }; 25427 ['top', 'right', 'bottom', 'left'].forEach(side => { 25428 borderValue[side] = { 25429 ...borderValue[side], 25430 color: decodeValue(borderValue[side]?.color) 25431 }; 25432 }); 25433 return borderValue; 25434 } 25435 return { 25436 ...inheritedValue?.border, 25437 color: inheritedValue?.border?.color ? decodeValue(inheritedValue?.border?.color) : undefined 25438 }; 25439 }, [inheritedValue?.border, decodeValue]); 25440 const setBorder = newBorder => onChange({ 25441 ...value, 25442 border: newBorder 25443 }); 25444 const showBorderColor = useHasBorderColorControl(settings); 25445 const showBorderStyle = useHasBorderStyleControl(settings); 25446 const showBorderWidth = useHasBorderWidthControl(settings); 25447 25448 // Border radius. 25449 const showBorderRadius = useHasBorderRadiusControl(settings); 25450 const borderRadiusValues = decodeValue(border?.radius); 25451 const setBorderRadius = newBorderRadius => setBorder({ 25452 ...border, 25453 radius: newBorderRadius 25454 }); 25455 const hasBorderRadius = () => { 25456 const borderValues = value?.border?.radius; 25457 if (typeof borderValues === 'object') { 25458 return Object.entries(borderValues).some(Boolean); 25459 } 25460 return !!borderValues; 25461 }; 25462 const hasShadowControl = useHasShadowControl(settings); 25463 25464 // Shadow 25465 const shadow = decodeValue(inheritedValue?.shadow); 25466 const shadowPresets = (_settings$shadow$pres = settings?.shadow?.presets) !== null && _settings$shadow$pres !== void 0 ? _settings$shadow$pres : {}; 25467 const overriddenShadowPresets = (_overrideOrigins = overrideOrigins(shadowPresets)) !== null && _overrideOrigins !== void 0 ? _overrideOrigins : []; 25468 const setShadow = newValue => { 25469 const slug = overriddenShadowPresets?.find(({ 25470 shadow: shadowName 25471 }) => shadowName === newValue)?.slug; 25472 onChange(setImmutably(value, ['shadow'], slug ? `var:preset|shadow|$slug}` : newValue || undefined)); 25473 }; 25474 const hasShadow = () => !!value?.shadow; 25475 const resetShadow = () => setShadow(undefined); 25476 const resetBorder = () => { 25477 if (hasBorderRadius()) { 25478 return setBorder({ 25479 radius: value?.border?.radius 25480 }); 25481 } 25482 setBorder(undefined); 25483 }; 25484 const onBorderChange = newBorder => { 25485 // Ensure we have a visible border style when a border width or 25486 // color is being selected. 25487 const updatedBorder = { 25488 ...newBorder 25489 }; 25490 if ((0,external_wp_components_namespaceObject.__experimentalHasSplitBorders)(updatedBorder)) { 25491 ['top', 'right', 'bottom', 'left'].forEach(side => { 25492 if (updatedBorder[side]) { 25493 updatedBorder[side] = { 25494 ...updatedBorder[side], 25495 color: encodeColorValue(updatedBorder[side]?.color) 25496 }; 25497 } 25498 }); 25499 } else if (updatedBorder) { 25500 updatedBorder.color = encodeColorValue(updatedBorder.color); 25501 } 25502 25503 // As radius is maintained separately to color, style, and width 25504 // maintain its value. Undefined values here will be cleaned when 25505 // global styles are saved. 25506 setBorder({ 25507 radius: border?.radius, 25508 ...updatedBorder 25509 }); 25510 }; 25511 const resetAllFilter = (0,external_wp_element_namespaceObject.useCallback)(previousValue => { 25512 return { 25513 ...previousValue, 25514 border: undefined, 25515 shadow: undefined 25516 }; 25517 }, []); 25518 const showBorderByDefault = defaultControls?.color || defaultControls?.width; 25519 const hasBorderControl = showBorderColor || showBorderStyle || showBorderWidth || showBorderRadius; 25520 const label = useBorderPanelLabel({ 25521 blockName: name, 25522 hasShadowControl, 25523 hasBorderControl 25524 }); 25525 return (0,external_React_.createElement)(Wrapper, { 25526 resetAllFilter: resetAllFilter, 25527 value: value, 25528 onChange: onChange, 25529 panelId: panelId, 25530 label: label 25531 }, (showBorderWidth || showBorderColor) && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 25532 hasValue: () => (0,external_wp_components_namespaceObject.__experimentalIsDefinedBorder)(value?.border), 25533 label: (0,external_wp_i18n_namespaceObject.__)('Border'), 25534 onDeselect: () => resetBorder(), 25535 isShownByDefault: showBorderByDefault, 25536 panelId: panelId 25537 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalBorderBoxControl, { 25538 colors: colors, 25539 enableAlpha: true, 25540 enableStyle: showBorderStyle, 25541 onChange: onBorderChange, 25542 popoverOffset: 40, 25543 popoverPlacement: "left-start", 25544 value: border, 25545 __experimentalIsRenderedInSidebar: true, 25546 size: '__unstable-large', 25547 hideLabelFromVision: !hasShadowControl, 25548 label: (0,external_wp_i18n_namespaceObject.__)('Border') 25549 })), showBorderRadius && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 25550 hasValue: hasBorderRadius, 25551 label: (0,external_wp_i18n_namespaceObject.__)('Radius'), 25552 onDeselect: () => setBorderRadius(undefined), 25553 isShownByDefault: defaultControls.radius, 25554 panelId: panelId 25555 }, (0,external_React_.createElement)(BorderRadiusControl, { 25556 values: borderRadiusValues, 25557 onChange: newValue => { 25558 setBorderRadius(newValue || undefined); 25559 } 25560 })), hasShadowControl && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 25561 label: (0,external_wp_i18n_namespaceObject.__)('Shadow'), 25562 hasValue: hasShadow, 25563 onDeselect: resetShadow, 25564 isShownByDefault: defaultControls.shadow, 25565 panelId: panelId 25566 }, hasBorderControl ? (0,external_React_.createElement)(external_wp_components_namespaceObject.BaseControl.VisualLabel, { 25567 as: "legend" 25568 }, (0,external_wp_i18n_namespaceObject.__)('Shadow')) : null, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalItemGroup, { 25569 isBordered: true, 25570 isSeparated: true 25571 }, (0,external_React_.createElement)(ShadowPopover, { 25572 shadow: shadow, 25573 onShadowChange: setShadow, 25574 settings: settings 25575 })))); 25576 } 25577 25578 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/border.js 25579 25580 /** 25581 * External dependencies 25582 */ 25583 25584 25585 /** 25586 * WordPress dependencies 25587 */ 25588 25589 25590 25591 25592 25593 25594 /** 25595 * Internal dependencies 25596 */ 25597 25598 25599 25600 25601 25602 25603 25604 const BORDER_SUPPORT_KEY = '__experimentalBorder'; 25605 const SHADOW_SUPPORT_KEY = 'shadow'; 25606 const getColorByProperty = (colors, property, value) => { 25607 let matchedColor; 25608 colors.some(origin => origin.colors.some(color => { 25609 if (color[property] === value) { 25610 matchedColor = color; 25611 return true; 25612 } 25613 return false; 25614 })); 25615 return matchedColor; 25616 }; 25617 const getMultiOriginColor = ({ 25618 colors, 25619 namedColor, 25620 customColor 25621 }) => { 25622 // Search each origin (default, theme, or user) for matching color by name. 25623 if (namedColor) { 25624 const colorObject = getColorByProperty(colors, 'slug', namedColor); 25625 if (colorObject) { 25626 return colorObject; 25627 } 25628 } 25629 25630 // Skip if no custom color or matching named color. 25631 if (!customColor) { 25632 return { 25633 color: undefined 25634 }; 25635 } 25636 25637 // Attempt to find color via custom color value or build new object. 25638 const colorObject = getColorByProperty(colors, 'color', customColor); 25639 return colorObject ? colorObject : { 25640 color: customColor 25641 }; 25642 }; 25643 function getColorSlugFromVariable(value) { 25644 const namedColor = /var:preset\|color\|(.+)/.exec(value); 25645 if (namedColor && namedColor[1]) { 25646 return namedColor[1]; 25647 } 25648 return null; 25649 } 25650 function styleToAttributes(style) { 25651 if ((0,external_wp_components_namespaceObject.__experimentalHasSplitBorders)(style?.border)) { 25652 return { 25653 style, 25654 borderColor: undefined 25655 }; 25656 } 25657 const borderColorValue = style?.border?.color; 25658 const borderColorSlug = borderColorValue?.startsWith('var:preset|color|') ? borderColorValue.substring('var:preset|color|'.length) : undefined; 25659 const updatedStyle = { 25660 ...style 25661 }; 25662 updatedStyle.border = { 25663 ...updatedStyle.border, 25664 color: borderColorSlug ? undefined : borderColorValue 25665 }; 25666 return { 25667 style: utils_cleanEmptyObject(updatedStyle), 25668 borderColor: borderColorSlug 25669 }; 25670 } 25671 function attributesToStyle(attributes) { 25672 if ((0,external_wp_components_namespaceObject.__experimentalHasSplitBorders)(attributes.style?.border)) { 25673 return attributes.style; 25674 } 25675 return { 25676 ...attributes.style, 25677 border: { 25678 ...attributes.style?.border, 25679 color: attributes.borderColor ? 'var:preset|color|' + attributes.borderColor : attributes.style?.border?.color 25680 } 25681 }; 25682 } 25683 function BordersInspectorControl({ 25684 label, 25685 children, 25686 resetAllFilter 25687 }) { 25688 const attributesResetAllFilter = (0,external_wp_element_namespaceObject.useCallback)(attributes => { 25689 const existingStyle = attributesToStyle(attributes); 25690 const updatedStyle = resetAllFilter(existingStyle); 25691 return { 25692 ...attributes, 25693 ...styleToAttributes(updatedStyle) 25694 }; 25695 }, [resetAllFilter]); 25696 return (0,external_React_.createElement)(inspector_controls, { 25697 group: "border", 25698 resetAllFilter: attributesResetAllFilter, 25699 label: label 25700 }, children); 25701 } 25702 function border_BorderPanel({ 25703 clientId, 25704 name, 25705 setAttributes, 25706 settings 25707 }) { 25708 const isEnabled = useHasBorderPanel(settings); 25709 function selector(select) { 25710 const { 25711 style, 25712 borderColor 25713 } = select(store).getBlockAttributes(clientId) || {}; 25714 return { 25715 style, 25716 borderColor 25717 }; 25718 } 25719 const { 25720 style, 25721 borderColor 25722 } = (0,external_wp_data_namespaceObject.useSelect)(selector, [clientId]); 25723 const value = (0,external_wp_element_namespaceObject.useMemo)(() => { 25724 return attributesToStyle({ 25725 style, 25726 borderColor 25727 }); 25728 }, [style, borderColor]); 25729 const onChange = newStyle => { 25730 setAttributes(styleToAttributes(newStyle)); 25731 }; 25732 if (!isEnabled) { 25733 return null; 25734 } 25735 const defaultControls = { 25736 ...(0,external_wp_blocks_namespaceObject.getBlockSupport)(name, [BORDER_SUPPORT_KEY, '__experimentalDefaultControls']), 25737 ...(0,external_wp_blocks_namespaceObject.getBlockSupport)(name, [SHADOW_SUPPORT_KEY, '__experimentalDefaultControls']) 25738 }; 25739 return (0,external_React_.createElement)(BorderPanel, { 25740 as: BordersInspectorControl, 25741 panelId: clientId, 25742 settings: settings, 25743 value: value, 25744 onChange: onChange, 25745 defaultControls: defaultControls 25746 }); 25747 } 25748 25749 /** 25750 * Determine whether there is block support for border properties. 25751 * 25752 * @param {string} blockName Block name. 25753 * @param {string} feature Border feature to check support for. 25754 * 25755 * @return {boolean} Whether there is support. 25756 */ 25757 function hasBorderSupport(blockName, feature = 'any') { 25758 if (external_wp_element_namespaceObject.Platform.OS !== 'web') { 25759 return false; 25760 } 25761 const support = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockName, BORDER_SUPPORT_KEY); 25762 if (support === true) { 25763 return true; 25764 } 25765 if (feature === 'any') { 25766 return !!(support?.color || support?.radius || support?.width || support?.style); 25767 } 25768 return !!support?.[feature]; 25769 } 25770 25771 /** 25772 * Determine whether there is block support for shadow properties. 25773 * 25774 * @param {string} blockName Block name. 25775 * 25776 * @return {boolean} Whether there is support. 25777 */ 25778 function hasShadowSupport(blockName) { 25779 return hasBlockSupport(blockName, SHADOW_SUPPORT_KEY); 25780 } 25781 function useBorderPanelLabel({ 25782 blockName, 25783 hasBorderControl, 25784 hasShadowControl 25785 } = {}) { 25786 const settings = useBlockSettings(blockName); 25787 const controls = useHasBorderPanelControls(settings); 25788 if (!hasBorderControl && !hasShadowControl && blockName) { 25789 hasBorderControl = controls?.hasBorderColor || controls?.hasBorderStyle || controls?.hasBorderWidth || controls?.hasBorderRadius; 25790 hasShadowControl = controls?.hasShadow; 25791 } 25792 if (hasBorderControl && hasShadowControl) { 25793 return (0,external_wp_i18n_namespaceObject.__)('Border & Shadow'); 25794 } 25795 if (hasShadowControl) { 25796 return (0,external_wp_i18n_namespaceObject.__)('Shadow'); 25797 } 25798 return (0,external_wp_i18n_namespaceObject.__)('Border'); 25799 } 25800 25801 /** 25802 * Returns a new style object where the specified border attribute has been 25803 * removed. 25804 * 25805 * @param {Object} style Styles from block attributes. 25806 * @param {string} attribute The border style attribute to clear. 25807 * 25808 * @return {Object} Style object with the specified attribute removed. 25809 */ 25810 function removeBorderAttribute(style, attribute) { 25811 return cleanEmptyObject({ 25812 ...style, 25813 border: { 25814 ...style?.border, 25815 [attribute]: undefined 25816 } 25817 }); 25818 } 25819 25820 /** 25821 * Filters registered block settings, extending attributes to include 25822 * `borderColor` if needed. 25823 * 25824 * @param {Object} settings Original block settings. 25825 * 25826 * @return {Object} Updated block settings. 25827 */ 25828 function addAttributes(settings) { 25829 if (!hasBorderSupport(settings, 'color')) { 25830 return settings; 25831 } 25832 25833 // Allow blocks to specify default value if needed. 25834 if (settings.attributes.borderColor) { 25835 return settings; 25836 } 25837 25838 // Add new borderColor attribute to block settings. 25839 return { 25840 ...settings, 25841 attributes: { 25842 ...settings.attributes, 25843 borderColor: { 25844 type: 'string' 25845 } 25846 } 25847 }; 25848 } 25849 25850 /** 25851 * Override props assigned to save component to inject border color. 25852 * 25853 * @param {Object} props Additional props applied to save element. 25854 * @param {Object|string} blockNameOrType Block type definition. 25855 * @param {Object} attributes Block's attributes. 25856 * 25857 * @return {Object} Filtered props to apply to save element. 25858 */ 25859 function border_addSaveProps(props, blockNameOrType, attributes) { 25860 if (!hasBorderSupport(blockNameOrType, 'color') || shouldSkipSerialization(blockNameOrType, BORDER_SUPPORT_KEY, 'color')) { 25861 return props; 25862 } 25863 const borderClasses = getBorderClasses(attributes); 25864 const newClassName = classnames_default()(props.className, borderClasses); 25865 25866 // If we are clearing the last of the previous classes in `className` 25867 // set it to `undefined` to avoid rendering empty DOM attributes. 25868 props.className = newClassName ? newClassName : undefined; 25869 return props; 25870 } 25871 25872 /** 25873 * Generates a CSS class name consisting of all the applicable border color 25874 * classes given the current block attributes. 25875 * 25876 * @param {Object} attributes Block's attributes. 25877 * 25878 * @return {string} CSS class name. 25879 */ 25880 function getBorderClasses(attributes) { 25881 const { 25882 borderColor, 25883 style 25884 } = attributes; 25885 const borderColorClass = getColorClassName('border-color', borderColor); 25886 return classnames_default()({ 25887 'has-border-color': borderColor || style?.border?.color, 25888 [borderColorClass]: !!borderColorClass 25889 }); 25890 } 25891 function border_useBlockProps({ 25892 name, 25893 borderColor, 25894 style 25895 }) { 25896 const { 25897 colors 25898 } = useMultipleOriginColorsAndGradients(); 25899 if (!hasBorderSupport(name, 'color') || shouldSkipSerialization(name, BORDER_SUPPORT_KEY, 'color')) { 25900 return {}; 25901 } 25902 const { 25903 color: borderColorValue 25904 } = getMultiOriginColor({ 25905 colors, 25906 namedColor: borderColor 25907 }); 25908 const { 25909 color: borderTopColor 25910 } = getMultiOriginColor({ 25911 colors, 25912 namedColor: getColorSlugFromVariable(style?.border?.top?.color) 25913 }); 25914 const { 25915 color: borderRightColor 25916 } = getMultiOriginColor({ 25917 colors, 25918 namedColor: getColorSlugFromVariable(style?.border?.right?.color) 25919 }); 25920 const { 25921 color: borderBottomColor 25922 } = getMultiOriginColor({ 25923 colors, 25924 namedColor: getColorSlugFromVariable(style?.border?.bottom?.color) 25925 }); 25926 const { 25927 color: borderLeftColor 25928 } = getMultiOriginColor({ 25929 colors, 25930 namedColor: getColorSlugFromVariable(style?.border?.left?.color) 25931 }); 25932 const extraStyles = { 25933 borderTopColor: borderTopColor || borderColorValue, 25934 borderRightColor: borderRightColor || borderColorValue, 25935 borderBottomColor: borderBottomColor || borderColorValue, 25936 borderLeftColor: borderLeftColor || borderColorValue 25937 }; 25938 return border_addSaveProps({ 25939 style: utils_cleanEmptyObject(extraStyles) || {} 25940 }, name, { 25941 borderColor, 25942 style 25943 }); 25944 } 25945 /* harmony default export */ const border = ({ 25946 useBlockProps: border_useBlockProps, 25947 addSaveProps: border_addSaveProps, 25948 attributeKeys: ['borderColor', 'style'], 25949 hasSupport(name) { 25950 return hasBorderSupport(name, 'color'); 25951 } 25952 }); 25953 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/border/addAttributes', addAttributes); 25954 25955 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/gradients/use-gradient.js 25956 /** 25957 * WordPress dependencies 25958 */ 25959 25960 25961 25962 /** 25963 * Internal dependencies 25964 */ 25965 25966 25967 25968 function __experimentalGetGradientClass(gradientSlug) { 25969 if (!gradientSlug) { 25970 return undefined; 25971 } 25972 return `has-$gradientSlug}-gradient-background`; 25973 } 25974 25975 /** 25976 * Retrieves the gradient value per slug. 25977 * 25978 * @param {Array} gradients Gradient Palette 25979 * @param {string} slug Gradient slug 25980 * 25981 * @return {string} Gradient value. 25982 */ 25983 function getGradientValueBySlug(gradients, slug) { 25984 const gradient = gradients?.find(g => g.slug === slug); 25985 return gradient && gradient.gradient; 25986 } 25987 function __experimentalGetGradientObjectByGradientValue(gradients, value) { 25988 const gradient = gradients?.find(g => g.gradient === value); 25989 return gradient; 25990 } 25991 25992 /** 25993 * Retrieves the gradient slug per slug. 25994 * 25995 * @param {Array} gradients Gradient Palette 25996 * @param {string} value Gradient value 25997 * @return {string} Gradient slug. 25998 */ 25999 function getGradientSlugByValue(gradients, value) { 26000 const gradient = __experimentalGetGradientObjectByGradientValue(gradients, value); 26001 return gradient && gradient.slug; 26002 } 26003 function __experimentalUseGradient({ 26004 gradientAttribute = 'gradient', 26005 customGradientAttribute = 'customGradient' 26006 } = {}) { 26007 const { 26008 clientId 26009 } = useBlockEditContext(); 26010 const [userGradientPalette, themeGradientPalette, defaultGradientPalette] = use_settings_useSettings('color.gradients.custom', 'color.gradients.theme', 'color.gradients.default'); 26011 const allGradients = (0,external_wp_element_namespaceObject.useMemo)(() => [...(userGradientPalette || []), ...(themeGradientPalette || []), ...(defaultGradientPalette || [])], [userGradientPalette, themeGradientPalette, defaultGradientPalette]); 26012 const { 26013 gradient, 26014 customGradient 26015 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 26016 const { 26017 getBlockAttributes 26018 } = select(store); 26019 const attributes = getBlockAttributes(clientId) || {}; 26020 return { 26021 customGradient: attributes[customGradientAttribute], 26022 gradient: attributes[gradientAttribute] 26023 }; 26024 }, [clientId, gradientAttribute, customGradientAttribute]); 26025 const { 26026 updateBlockAttributes 26027 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 26028 const setGradient = (0,external_wp_element_namespaceObject.useCallback)(newGradientValue => { 26029 const slug = getGradientSlugByValue(allGradients, newGradientValue); 26030 if (slug) { 26031 updateBlockAttributes(clientId, { 26032 [gradientAttribute]: slug, 26033 [customGradientAttribute]: undefined 26034 }); 26035 return; 26036 } 26037 updateBlockAttributes(clientId, { 26038 [gradientAttribute]: undefined, 26039 [customGradientAttribute]: newGradientValue 26040 }); 26041 }, [allGradients, clientId, updateBlockAttributes]); 26042 const gradientClass = __experimentalGetGradientClass(gradient); 26043 let gradientValue; 26044 if (gradient) { 26045 gradientValue = getGradientValueBySlug(allGradients, gradient); 26046 } else { 26047 gradientValue = customGradient; 26048 } 26049 return { 26050 gradientClass, 26051 gradientValue, 26052 setGradient 26053 }; 26054 } 26055 26056 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/colors-gradients/control.js 26057 26058 /** 26059 * External dependencies 26060 */ 26061 26062 26063 /** 26064 * WordPress dependencies 26065 */ 26066 26067 26068 26069 /** 26070 * Internal dependencies 26071 */ 26072 26073 26074 const colorsAndGradientKeys = ['colors', 'disableCustomColors', 'gradients', 'disableCustomGradients']; 26075 const TAB_IDS = { 26076 color: 'color', 26077 gradient: 'gradient' 26078 }; 26079 function ColorGradientControlInner({ 26080 colors, 26081 gradients, 26082 disableCustomColors, 26083 disableCustomGradients, 26084 __experimentalIsRenderedInSidebar, 26085 className, 26086 label, 26087 onColorChange, 26088 onGradientChange, 26089 colorValue, 26090 gradientValue, 26091 clearable, 26092 showTitle = true, 26093 enableAlpha, 26094 headingLevel 26095 }) { 26096 const canChooseAColor = onColorChange && (colors && colors.length > 0 || !disableCustomColors); 26097 const canChooseAGradient = onGradientChange && (gradients && gradients.length > 0 || !disableCustomGradients); 26098 if (!canChooseAColor && !canChooseAGradient) { 26099 return null; 26100 } 26101 const tabPanels = { 26102 [TAB_IDS.color]: (0,external_React_.createElement)(external_wp_components_namespaceObject.ColorPalette, { 26103 value: colorValue, 26104 onChange: canChooseAGradient ? newColor => { 26105 onColorChange(newColor); 26106 onGradientChange(); 26107 } : onColorChange, 26108 colors, 26109 disableCustomColors, 26110 __experimentalIsRenderedInSidebar: __experimentalIsRenderedInSidebar, 26111 clearable: clearable, 26112 enableAlpha: enableAlpha, 26113 headingLevel: headingLevel 26114 }), 26115 [TAB_IDS.gradient]: (0,external_React_.createElement)(external_wp_components_namespaceObject.GradientPicker, { 26116 value: gradientValue, 26117 onChange: canChooseAColor ? newGradient => { 26118 onGradientChange(newGradient); 26119 onColorChange(); 26120 } : onGradientChange, 26121 gradients, 26122 disableCustomGradients, 26123 __experimentalIsRenderedInSidebar: __experimentalIsRenderedInSidebar, 26124 clearable: clearable, 26125 headingLevel: headingLevel 26126 }) 26127 }; 26128 const renderPanelType = type => (0,external_React_.createElement)("div", { 26129 className: "block-editor-color-gradient-control__panel" 26130 }, tabPanels[type]); 26131 26132 // Unlocking `Tabs` too early causes the `unlock` method to receive an empty 26133 // object, due to circular dependencies. 26134 // See https://github.com/WordPress/gutenberg/issues/52692 26135 const { 26136 Tabs 26137 } = unlock(external_wp_components_namespaceObject.privateApis); 26138 return (0,external_React_.createElement)(external_wp_components_namespaceObject.BaseControl, { 26139 __nextHasNoMarginBottom: true, 26140 className: classnames_default()('block-editor-color-gradient-control', className) 26141 }, (0,external_React_.createElement)("fieldset", { 26142 className: "block-editor-color-gradient-control__fieldset" 26143 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalVStack, { 26144 spacing: 1 26145 }, showTitle && (0,external_React_.createElement)("legend", null, (0,external_React_.createElement)("div", { 26146 className: "block-editor-color-gradient-control__color-indicator" 26147 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.BaseControl.VisualLabel, null, label))), canChooseAColor && canChooseAGradient && (0,external_React_.createElement)("div", null, (0,external_React_.createElement)(Tabs, { 26148 initialTabId: gradientValue ? TAB_IDS.gradient : !!canChooseAColor && TAB_IDS.color 26149 }, (0,external_React_.createElement)(Tabs.TabList, null, (0,external_React_.createElement)(Tabs.Tab, { 26150 tabId: TAB_IDS.color 26151 }, (0,external_wp_i18n_namespaceObject.__)('Solid')), (0,external_React_.createElement)(Tabs.Tab, { 26152 tabId: TAB_IDS.gradient 26153 }, (0,external_wp_i18n_namespaceObject.__)('Gradient'))), (0,external_React_.createElement)(Tabs.TabPanel, { 26154 tabId: TAB_IDS.color, 26155 className: 'block-editor-color-gradient-control__panel', 26156 focusable: false 26157 }, tabPanels.color), (0,external_React_.createElement)(Tabs.TabPanel, { 26158 tabId: TAB_IDS.gradient, 26159 className: 'block-editor-color-gradient-control__panel', 26160 focusable: false 26161 }, tabPanels.gradient))), !canChooseAGradient && renderPanelType(TAB_IDS.color), !canChooseAColor && renderPanelType(TAB_IDS.gradient)))); 26162 } 26163 function ColorGradientControlSelect(props) { 26164 const [colors, gradients, customColors, customGradients] = use_settings_useSettings('color.palette', 'color.gradients', 'color.custom', 'color.customGradient'); 26165 return (0,external_React_.createElement)(ColorGradientControlInner, { 26166 colors: colors, 26167 gradients: gradients, 26168 disableCustomColors: !customColors, 26169 disableCustomGradients: !customGradients, 26170 ...props 26171 }); 26172 } 26173 function ColorGradientControl(props) { 26174 if (colorsAndGradientKeys.every(key => props.hasOwnProperty(key))) { 26175 return (0,external_React_.createElement)(ColorGradientControlInner, { 26176 ...props 26177 }); 26178 } 26179 return (0,external_React_.createElement)(ColorGradientControlSelect, { 26180 ...props 26181 }); 26182 } 26183 /* harmony default export */ const control = (ColorGradientControl); 26184 26185 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/global-styles/color-panel.js 26186 26187 /** 26188 * External dependencies 26189 */ 26190 26191 26192 /** 26193 * WordPress dependencies 26194 */ 26195 26196 26197 26198 26199 /** 26200 * Internal dependencies 26201 */ 26202 26203 26204 26205 26206 26207 function useHasColorPanel(settings) { 26208 const hasTextPanel = useHasTextPanel(settings); 26209 const hasBackgroundPanel = useHasBackgroundPanel(settings); 26210 const hasLinkPanel = useHasLinkPanel(settings); 26211 const hasHeadingPanel = useHasHeadingPanel(settings); 26212 const hasButtonPanel = useHasButtonPanel(settings); 26213 const hasCaptionPanel = useHasCaptionPanel(settings); 26214 return hasTextPanel || hasBackgroundPanel || hasLinkPanel || hasHeadingPanel || hasButtonPanel || hasCaptionPanel; 26215 } 26216 function useHasTextPanel(settings) { 26217 const colors = useColorsPerOrigin(settings); 26218 return settings?.color?.text && (colors?.length > 0 || settings?.color?.custom); 26219 } 26220 function useHasLinkPanel(settings) { 26221 const colors = useColorsPerOrigin(settings); 26222 return settings?.color?.link && (colors?.length > 0 || settings?.color?.custom); 26223 } 26224 function useHasCaptionPanel(settings) { 26225 const colors = useColorsPerOrigin(settings); 26226 return settings?.color?.caption && (colors?.length > 0 || settings?.color?.custom); 26227 } 26228 function useHasHeadingPanel(settings) { 26229 const colors = useColorsPerOrigin(settings); 26230 const gradients = useGradientsPerOrigin(settings); 26231 return settings?.color?.heading && (colors?.length > 0 || settings?.color?.custom || gradients?.length > 0 || settings?.color?.customGradient); 26232 } 26233 function useHasButtonPanel(settings) { 26234 const colors = useColorsPerOrigin(settings); 26235 const gradients = useGradientsPerOrigin(settings); 26236 return settings?.color?.button && (colors?.length > 0 || settings?.color?.custom || gradients?.length > 0 || settings?.color?.customGradient); 26237 } 26238 function useHasBackgroundPanel(settings) { 26239 const colors = useColorsPerOrigin(settings); 26240 const gradients = useGradientsPerOrigin(settings); 26241 return settings?.color?.background && (colors?.length > 0 || settings?.color?.custom || gradients?.length > 0 || settings?.color?.customGradient); 26242 } 26243 function ColorToolsPanel({ 26244 resetAllFilter, 26245 onChange, 26246 value, 26247 panelId, 26248 children 26249 }) { 26250 const resetAll = () => { 26251 const updatedValue = resetAllFilter(value); 26252 onChange(updatedValue); 26253 }; 26254 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanel, { 26255 label: (0,external_wp_i18n_namespaceObject.__)('Color'), 26256 resetAll: resetAll, 26257 panelId: panelId, 26258 hasInnerWrapper: true, 26259 className: "color-block-support-panel", 26260 __experimentalFirstVisibleItemClass: "first", 26261 __experimentalLastVisibleItemClass: "last", 26262 dropdownMenuProps: TOOLSPANEL_DROPDOWNMENU_PROPS 26263 }, (0,external_React_.createElement)("div", { 26264 className: "color-block-support-panel__inner-wrapper" 26265 }, children)); 26266 } 26267 const color_panel_DEFAULT_CONTROLS = { 26268 text: true, 26269 background: true, 26270 link: true, 26271 heading: true, 26272 button: true, 26273 caption: true 26274 }; 26275 const popoverProps = { 26276 placement: 'left-start', 26277 offset: 36, 26278 shift: true 26279 }; 26280 const LabeledColorIndicators = ({ 26281 indicators, 26282 label 26283 }) => (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, { 26284 justify: "flex-start" 26285 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalZStack, { 26286 isLayered: false, 26287 offset: -8 26288 }, indicators.map((indicator, index) => (0,external_React_.createElement)(external_wp_components_namespaceObject.Flex, { 26289 key: index, 26290 expanded: false 26291 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.ColorIndicator, { 26292 colorValue: indicator 26293 })))), (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexItem, { 26294 className: "block-editor-panel-color-gradient-settings__color-name", 26295 title: label 26296 }, label)); 26297 function ColorPanelTab({ 26298 isGradient, 26299 inheritedValue, 26300 userValue, 26301 setValue, 26302 colorGradientControlSettings 26303 }) { 26304 return (0,external_React_.createElement)(control, { 26305 ...colorGradientControlSettings, 26306 showTitle: false, 26307 enableAlpha: true, 26308 __experimentalIsRenderedInSidebar: true, 26309 colorValue: isGradient ? undefined : inheritedValue, 26310 gradientValue: isGradient ? inheritedValue : undefined, 26311 onColorChange: isGradient ? undefined : setValue, 26312 onGradientChange: isGradient ? setValue : undefined, 26313 clearable: inheritedValue === userValue, 26314 headingLevel: 3 26315 }); 26316 } 26317 function ColorPanelDropdown({ 26318 label, 26319 hasValue, 26320 resetValue, 26321 isShownByDefault, 26322 indicators, 26323 tabs, 26324 colorGradientControlSettings, 26325 panelId 26326 }) { 26327 const currentTab = tabs.find(tab => tab.userValue !== undefined); 26328 // Unlocking `Tabs` too early causes the `unlock` method to receive an empty 26329 // object, due to circular dependencies. 26330 // See https://github.com/WordPress/gutenberg/issues/52692 26331 const { 26332 Tabs 26333 } = unlock(external_wp_components_namespaceObject.privateApis); 26334 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 26335 className: "block-editor-tools-panel-color-gradient-settings__item", 26336 hasValue: hasValue, 26337 label: label, 26338 onDeselect: resetValue, 26339 isShownByDefault: isShownByDefault, 26340 panelId: panelId 26341 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Dropdown, { 26342 popoverProps: popoverProps, 26343 className: "block-editor-tools-panel-color-gradient-settings__dropdown", 26344 renderToggle: ({ 26345 onToggle, 26346 isOpen 26347 }) => { 26348 const toggleProps = { 26349 onClick: onToggle, 26350 className: classnames_default()('block-editor-panel-color-gradient-settings__dropdown', { 26351 'is-open': isOpen 26352 }), 26353 'aria-expanded': isOpen, 26354 'aria-label': (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s is the type of color property, e.g., "background" */ 26355 (0,external_wp_i18n_namespaceObject.__)('Color %s styles'), label) 26356 }; 26357 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 26358 ...toggleProps 26359 }, (0,external_React_.createElement)(LabeledColorIndicators, { 26360 indicators: indicators, 26361 label: label 26362 })); 26363 }, 26364 renderContent: () => (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalDropdownContentWrapper, { 26365 paddingSize: "none" 26366 }, (0,external_React_.createElement)("div", { 26367 className: "block-editor-panel-color-gradient-settings__dropdown-content" 26368 }, tabs.length === 1 && (0,external_React_.createElement)(ColorPanelTab, { 26369 ...tabs[0], 26370 colorGradientControlSettings: colorGradientControlSettings 26371 }), tabs.length > 1 && (0,external_React_.createElement)(Tabs, { 26372 initialTabId: currentTab?.key 26373 }, (0,external_React_.createElement)(Tabs.TabList, null, tabs.map(tab => (0,external_React_.createElement)(Tabs.Tab, { 26374 key: tab.key, 26375 tabId: tab.key 26376 }, tab.label))), tabs.map(tab => { 26377 return (0,external_React_.createElement)(Tabs.TabPanel, { 26378 key: tab.key, 26379 tabId: tab.key, 26380 focusable: false 26381 }, (0,external_React_.createElement)(ColorPanelTab, { 26382 ...tab, 26383 colorGradientControlSettings: colorGradientControlSettings 26384 })); 26385 })))) 26386 })); 26387 } 26388 function ColorPanel({ 26389 as: Wrapper = ColorToolsPanel, 26390 value, 26391 onChange, 26392 inheritedValue = value, 26393 settings, 26394 panelId, 26395 defaultControls = color_panel_DEFAULT_CONTROLS, 26396 children 26397 }) { 26398 const colors = useColorsPerOrigin(settings); 26399 const gradients = useGradientsPerOrigin(settings); 26400 const areCustomSolidsEnabled = settings?.color?.custom; 26401 const areCustomGradientsEnabled = settings?.color?.customGradient; 26402 const hasSolidColors = colors.length > 0 || areCustomSolidsEnabled; 26403 const hasGradientColors = gradients.length > 0 || areCustomGradientsEnabled; 26404 const decodeValue = rawValue => getValueFromVariable({ 26405 settings 26406 }, '', rawValue); 26407 const encodeColorValue = colorValue => { 26408 const allColors = colors.flatMap(({ 26409 colors: originColors 26410 }) => originColors); 26411 const colorObject = allColors.find(({ 26412 color 26413 }) => color === colorValue); 26414 return colorObject ? 'var:preset|color|' + colorObject.slug : colorValue; 26415 }; 26416 const encodeGradientValue = gradientValue => { 26417 const allGradients = gradients.flatMap(({ 26418 gradients: originGradients 26419 }) => originGradients); 26420 const gradientObject = allGradients.find(({ 26421 gradient 26422 }) => gradient === gradientValue); 26423 return gradientObject ? 'var:preset|gradient|' + gradientObject.slug : gradientValue; 26424 }; 26425 26426 // BackgroundColor 26427 const showBackgroundPanel = useHasBackgroundPanel(settings); 26428 const backgroundColor = decodeValue(inheritedValue?.color?.background); 26429 const userBackgroundColor = decodeValue(value?.color?.background); 26430 const gradient = decodeValue(inheritedValue?.color?.gradient); 26431 const userGradient = decodeValue(value?.color?.gradient); 26432 const hasBackground = () => !!userBackgroundColor || !!userGradient; 26433 const setBackgroundColor = newColor => { 26434 const newValue = setImmutably(value, ['color', 'background'], encodeColorValue(newColor)); 26435 newValue.color.gradient = undefined; 26436 onChange(newValue); 26437 }; 26438 const setGradient = newGradient => { 26439 const newValue = setImmutably(value, ['color', 'gradient'], encodeGradientValue(newGradient)); 26440 newValue.color.background = undefined; 26441 onChange(newValue); 26442 }; 26443 const resetBackground = () => { 26444 const newValue = setImmutably(value, ['color', 'background'], undefined); 26445 newValue.color.gradient = undefined; 26446 onChange(newValue); 26447 }; 26448 26449 // Links 26450 const showLinkPanel = useHasLinkPanel(settings); 26451 const linkColor = decodeValue(inheritedValue?.elements?.link?.color?.text); 26452 const userLinkColor = decodeValue(value?.elements?.link?.color?.text); 26453 const setLinkColor = newColor => { 26454 onChange(setImmutably(value, ['elements', 'link', 'color', 'text'], encodeColorValue(newColor))); 26455 }; 26456 const hoverLinkColor = decodeValue(inheritedValue?.elements?.link?.[':hover']?.color?.text); 26457 const userHoverLinkColor = decodeValue(value?.elements?.link?.[':hover']?.color?.text); 26458 const setHoverLinkColor = newColor => { 26459 onChange(setImmutably(value, ['elements', 'link', ':hover', 'color', 'text'], encodeColorValue(newColor))); 26460 }; 26461 const hasLink = () => !!userLinkColor || !!userHoverLinkColor; 26462 const resetLink = () => { 26463 let newValue = setImmutably(value, ['elements', 'link', ':hover', 'color', 'text'], undefined); 26464 newValue = setImmutably(newValue, ['elements', 'link', 'color', 'text'], undefined); 26465 onChange(newValue); 26466 }; 26467 26468 // Text Color 26469 const showTextPanel = useHasTextPanel(settings); 26470 const textColor = decodeValue(inheritedValue?.color?.text); 26471 const userTextColor = decodeValue(value?.color?.text); 26472 const hasTextColor = () => !!userTextColor; 26473 const setTextColor = newColor => { 26474 let changedObject = setImmutably(value, ['color', 'text'], encodeColorValue(newColor)); 26475 if (textColor === linkColor) { 26476 changedObject = setImmutably(changedObject, ['elements', 'link', 'color', 'text'], encodeColorValue(newColor)); 26477 } 26478 onChange(changedObject); 26479 }; 26480 const resetTextColor = () => setTextColor(undefined); 26481 26482 // Elements 26483 const elements = [{ 26484 name: 'caption', 26485 label: (0,external_wp_i18n_namespaceObject.__)('Captions'), 26486 showPanel: useHasCaptionPanel(settings) 26487 }, { 26488 name: 'button', 26489 label: (0,external_wp_i18n_namespaceObject.__)('Button'), 26490 showPanel: useHasButtonPanel(settings) 26491 }, { 26492 name: 'heading', 26493 label: (0,external_wp_i18n_namespaceObject.__)('Heading'), 26494 showPanel: useHasHeadingPanel(settings) 26495 }, { 26496 name: 'h1', 26497 label: (0,external_wp_i18n_namespaceObject.__)('H1'), 26498 showPanel: useHasHeadingPanel(settings) 26499 }, { 26500 name: 'h2', 26501 label: (0,external_wp_i18n_namespaceObject.__)('H2'), 26502 showPanel: useHasHeadingPanel(settings) 26503 }, { 26504 name: 'h3', 26505 label: (0,external_wp_i18n_namespaceObject.__)('H3'), 26506 showPanel: useHasHeadingPanel(settings) 26507 }, { 26508 name: 'h4', 26509 label: (0,external_wp_i18n_namespaceObject.__)('H4'), 26510 showPanel: useHasHeadingPanel(settings) 26511 }, { 26512 name: 'h5', 26513 label: (0,external_wp_i18n_namespaceObject.__)('H5'), 26514 showPanel: useHasHeadingPanel(settings) 26515 }, { 26516 name: 'h6', 26517 label: (0,external_wp_i18n_namespaceObject.__)('H6'), 26518 showPanel: useHasHeadingPanel(settings) 26519 }]; 26520 const resetAllFilter = (0,external_wp_element_namespaceObject.useCallback)(previousValue => { 26521 return { 26522 ...previousValue, 26523 color: undefined, 26524 elements: { 26525 ...previousValue?.elements, 26526 link: { 26527 ...previousValue?.elements?.link, 26528 color: undefined, 26529 ':hover': { 26530 color: undefined 26531 } 26532 }, 26533 ...elements.reduce((acc, element) => { 26534 return { 26535 ...acc, 26536 [element.name]: { 26537 ...previousValue?.elements?.[element.name], 26538 color: undefined 26539 } 26540 }; 26541 }, {}) 26542 } 26543 }; 26544 }, []); 26545 const items = [showTextPanel && { 26546 key: 'text', 26547 label: (0,external_wp_i18n_namespaceObject.__)('Text'), 26548 hasValue: hasTextColor, 26549 resetValue: resetTextColor, 26550 isShownByDefault: defaultControls.text, 26551 indicators: [textColor], 26552 tabs: [{ 26553 key: 'text', 26554 label: (0,external_wp_i18n_namespaceObject.__)('Text'), 26555 inheritedValue: textColor, 26556 setValue: setTextColor, 26557 userValue: userTextColor 26558 }] 26559 }, showBackgroundPanel && { 26560 key: 'background', 26561 label: (0,external_wp_i18n_namespaceObject.__)('Background'), 26562 hasValue: hasBackground, 26563 resetValue: resetBackground, 26564 isShownByDefault: defaultControls.background, 26565 indicators: [gradient !== null && gradient !== void 0 ? gradient : backgroundColor], 26566 tabs: [hasSolidColors && { 26567 key: 'background', 26568 label: (0,external_wp_i18n_namespaceObject.__)('Solid'), 26569 inheritedValue: backgroundColor, 26570 setValue: setBackgroundColor, 26571 userValue: userBackgroundColor 26572 }, hasGradientColors && { 26573 key: 'gradient', 26574 label: (0,external_wp_i18n_namespaceObject.__)('Gradient'), 26575 inheritedValue: gradient, 26576 setValue: setGradient, 26577 userValue: userGradient, 26578 isGradient: true 26579 }].filter(Boolean) 26580 }, showLinkPanel && { 26581 key: 'link', 26582 label: (0,external_wp_i18n_namespaceObject.__)('Link'), 26583 hasValue: hasLink, 26584 resetValue: resetLink, 26585 isShownByDefault: defaultControls.link, 26586 indicators: [linkColor, hoverLinkColor], 26587 tabs: [{ 26588 key: 'link', 26589 label: (0,external_wp_i18n_namespaceObject.__)('Default'), 26590 inheritedValue: linkColor, 26591 setValue: setLinkColor, 26592 userValue: userLinkColor 26593 }, { 26594 key: 'hover', 26595 label: (0,external_wp_i18n_namespaceObject.__)('Hover'), 26596 inheritedValue: hoverLinkColor, 26597 setValue: setHoverLinkColor, 26598 userValue: userHoverLinkColor 26599 }] 26600 }].filter(Boolean); 26601 elements.forEach(({ 26602 name, 26603 label, 26604 showPanel 26605 }) => { 26606 if (!showPanel) return; 26607 const elementBackgroundColor = decodeValue(inheritedValue?.elements?.[name]?.color?.background); 26608 const elementGradient = decodeValue(inheritedValue?.elements?.[name]?.color?.gradient); 26609 const elementTextColor = decodeValue(inheritedValue?.elements?.[name]?.color?.text); 26610 const elementBackgroundUserColor = decodeValue(value?.elements?.[name]?.color?.background); 26611 const elementGradientUserColor = decodeValue(value?.elements?.[name]?.color?.gradient); 26612 const elementTextUserColor = decodeValue(value?.elements?.[name]?.color?.text); 26613 const hasElement = () => !!(elementTextUserColor || elementBackgroundUserColor || elementGradientUserColor); 26614 const resetElement = () => { 26615 const newValue = setImmutably(value, ['elements', name, 'color', 'background'], undefined); 26616 newValue.elements[name].color.gradient = undefined; 26617 newValue.elements[name].color.text = undefined; 26618 onChange(newValue); 26619 }; 26620 const setElementTextColor = newTextColor => { 26621 onChange(setImmutably(value, ['elements', name, 'color', 'text'], encodeColorValue(newTextColor))); 26622 }; 26623 const setElementBackgroundColor = newBackgroundColor => { 26624 const newValue = setImmutably(value, ['elements', name, 'color', 'background'], encodeColorValue(newBackgroundColor)); 26625 newValue.elements[name].color.gradient = undefined; 26626 onChange(newValue); 26627 }; 26628 const setElementGradient = newGradient => { 26629 const newValue = setImmutably(value, ['elements', name, 'color', 'gradient'], encodeGradientValue(newGradient)); 26630 newValue.elements[name].color.background = undefined; 26631 onChange(newValue); 26632 }; 26633 const supportsTextColor = true; 26634 // Background color is not supported for `caption` 26635 // as there isn't yet a way to set padding for the element. 26636 const supportsBackground = name !== 'caption'; 26637 items.push({ 26638 key: name, 26639 label, 26640 hasValue: hasElement, 26641 resetValue: resetElement, 26642 isShownByDefault: defaultControls[name], 26643 indicators: supportsTextColor && supportsBackground ? [elementTextColor, elementGradient !== null && elementGradient !== void 0 ? elementGradient : elementBackgroundColor] : [supportsTextColor ? elementTextColor : elementGradient !== null && elementGradient !== void 0 ? elementGradient : elementBackgroundColor], 26644 tabs: [hasSolidColors && supportsTextColor && { 26645 key: 'text', 26646 label: (0,external_wp_i18n_namespaceObject.__)('Text'), 26647 inheritedValue: elementTextColor, 26648 setValue: setElementTextColor, 26649 userValue: elementTextUserColor 26650 }, hasSolidColors && supportsBackground && { 26651 key: 'background', 26652 label: (0,external_wp_i18n_namespaceObject.__)('Background'), 26653 inheritedValue: elementBackgroundColor, 26654 setValue: setElementBackgroundColor, 26655 userValue: elementBackgroundUserColor 26656 }, hasGradientColors && supportsBackground && { 26657 key: 'gradient', 26658 label: (0,external_wp_i18n_namespaceObject.__)('Gradient'), 26659 inheritedValue: elementGradient, 26660 setValue: setElementGradient, 26661 userValue: elementGradientUserColor, 26662 isGradient: true 26663 }].filter(Boolean) 26664 }); 26665 }); 26666 return (0,external_React_.createElement)(Wrapper, { 26667 resetAllFilter: resetAllFilter, 26668 value: value, 26669 onChange: onChange, 26670 panelId: panelId 26671 }, items.map(item => (0,external_React_.createElement)(ColorPanelDropdown, { 26672 key: item.key, 26673 ...item, 26674 colorGradientControlSettings: { 26675 colors, 26676 disableCustomColors: !areCustomSolidsEnabled, 26677 gradients, 26678 disableCustomGradients: !areCustomGradientsEnabled 26679 }, 26680 panelId: panelId 26681 })), children); 26682 } 26683 26684 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/contrast-checker/index.js 26685 26686 /** 26687 * External dependencies 26688 */ 26689 26690 26691 26692 26693 /** 26694 * WordPress dependencies 26695 */ 26696 26697 26698 26699 k([names, a11y]); 26700 function ContrastChecker({ 26701 backgroundColor, 26702 fallbackBackgroundColor, 26703 fallbackTextColor, 26704 fallbackLinkColor, 26705 fontSize, 26706 // Font size value in pixels. 26707 isLargeText, 26708 textColor, 26709 linkColor, 26710 enableAlphaChecker = false 26711 }) { 26712 const currentBackgroundColor = backgroundColor || fallbackBackgroundColor; 26713 26714 // Must have a background color. 26715 if (!currentBackgroundColor) { 26716 return null; 26717 } 26718 const currentTextColor = textColor || fallbackTextColor; 26719 const currentLinkColor = linkColor || fallbackLinkColor; 26720 26721 // Must have at least one text color. 26722 if (!currentTextColor && !currentLinkColor) { 26723 return null; 26724 } 26725 const textColors = [{ 26726 color: currentTextColor, 26727 description: (0,external_wp_i18n_namespaceObject.__)('text color') 26728 }, { 26729 color: currentLinkColor, 26730 description: (0,external_wp_i18n_namespaceObject.__)('link color') 26731 }]; 26732 const colordBackgroundColor = w(currentBackgroundColor); 26733 const backgroundColorHasTransparency = colordBackgroundColor.alpha() < 1; 26734 const backgroundColorBrightness = colordBackgroundColor.brightness(); 26735 const isReadableOptions = { 26736 level: 'AA', 26737 size: isLargeText || isLargeText !== false && fontSize >= 24 ? 'large' : 'small' 26738 }; 26739 let message = ''; 26740 let speakMessage = ''; 26741 for (const item of textColors) { 26742 // If there is no color, go no further. 26743 if (!item.color) { 26744 continue; 26745 } 26746 const colordTextColor = w(item.color); 26747 const isColordTextReadable = colordTextColor.isReadable(colordBackgroundColor, isReadableOptions); 26748 const textHasTransparency = colordTextColor.alpha() < 1; 26749 26750 // If the contrast is not readable. 26751 if (!isColordTextReadable) { 26752 // Don't show the message if the background or text is transparent. 26753 if (backgroundColorHasTransparency || textHasTransparency) { 26754 continue; 26755 } 26756 message = backgroundColorBrightness < colordTextColor.brightness() ? (0,external_wp_i18n_namespaceObject.sprintf)( 26757 // translators: %s is a type of text color, e.g., "text color" or "link color". 26758 (0,external_wp_i18n_namespaceObject.__)('This color combination may be hard for people to read. Try using a darker background color and/or a brighter %s.'), item.description) : (0,external_wp_i18n_namespaceObject.sprintf)( 26759 // translators: %s is a type of text color, e.g., "text color" or "link color". 26760 (0,external_wp_i18n_namespaceObject.__)('This color combination may be hard for people to read. Try using a brighter background color and/or a darker %s.'), item.description); 26761 speakMessage = (0,external_wp_i18n_namespaceObject.__)('This color combination may be hard for people to read.'); 26762 // Break from the loop when we have a contrast warning. 26763 // These messages take priority over the transparency warning. 26764 break; 26765 } 26766 26767 // If there is no contrast warning and the text is transparent, 26768 // show the transparent warning if alpha check is enabled. 26769 if (textHasTransparency && enableAlphaChecker) { 26770 message = (0,external_wp_i18n_namespaceObject.__)('Transparent text may be hard for people to read.'); 26771 speakMessage = (0,external_wp_i18n_namespaceObject.__)('Transparent text may be hard for people to read.'); 26772 } 26773 } 26774 if (!message) { 26775 return null; 26776 } 26777 26778 // Note: The `Notice` component can speak messages via its `spokenMessage` 26779 // prop, but the contrast checker requires granular control over when the 26780 // announcements are made. Notably, the message will be re-announced if a 26781 // new color combination is selected and the contrast is still insufficient. 26782 (0,external_wp_a11y_namespaceObject.speak)(speakMessage); 26783 return (0,external_React_.createElement)("div", { 26784 className: "block-editor-contrast-checker" 26785 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Notice, { 26786 spokenMessage: null, 26787 status: "warning", 26788 isDismissible: false 26789 }, message)); 26790 } 26791 26792 /** 26793 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/contrast-checker/README.md 26794 */ 26795 /* harmony default export */ const contrast_checker = (ContrastChecker); 26796 26797 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/provider/block-refs-provider.js 26798 26799 /** 26800 * WordPress dependencies 26801 */ 26802 26803 const BlockRefs = (0,external_wp_element_namespaceObject.createContext)({ 26804 refs: new Map(), 26805 callbacks: new Map() 26806 }); 26807 function BlockRefsProvider({ 26808 children 26809 }) { 26810 const value = (0,external_wp_element_namespaceObject.useMemo)(() => ({ 26811 refs: new Map(), 26812 callbacks: new Map() 26813 }), []); 26814 return (0,external_React_.createElement)(BlockRefs.Provider, { 26815 value: value 26816 }, children); 26817 } 26818 26819 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/use-block-refs.js 26820 /** 26821 * WordPress dependencies 26822 */ 26823 26824 26825 26826 /** 26827 * Internal dependencies 26828 */ 26829 26830 26831 /** @typedef {import('@wordpress/element').RefCallback} RefCallback */ 26832 /** @typedef {import('@wordpress/element').RefObject} RefObject */ 26833 26834 /** 26835 * Provides a ref to the BlockRefs context. 26836 * 26837 * @param {string} clientId The client ID of the element ref. 26838 * 26839 * @return {RefCallback} Ref callback. 26840 */ 26841 function useBlockRefProvider(clientId) { 26842 const { 26843 refs, 26844 callbacks 26845 } = (0,external_wp_element_namespaceObject.useContext)(BlockRefs); 26846 const ref = (0,external_wp_element_namespaceObject.useRef)(); 26847 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 26848 refs.set(ref, clientId); 26849 return () => { 26850 refs.delete(ref); 26851 }; 26852 }, [clientId]); 26853 return (0,external_wp_compose_namespaceObject.useRefEffect)(element => { 26854 // Update the ref in the provider. 26855 ref.current = element; 26856 // Call any update functions. 26857 callbacks.forEach((id, setElement) => { 26858 if (clientId === id) { 26859 setElement(element); 26860 } 26861 }); 26862 }, [clientId]); 26863 } 26864 26865 /** 26866 * Gets a ref pointing to the current block element. Continues to return a 26867 * stable ref even if the block client ID changes. 26868 * 26869 * @param {string} clientId The client ID to get a ref for. 26870 * 26871 * @return {RefObject} A ref containing the element. 26872 */ 26873 function useBlockRef(clientId) { 26874 const { 26875 refs 26876 } = (0,external_wp_element_namespaceObject.useContext)(BlockRefs); 26877 const freshClientId = (0,external_wp_element_namespaceObject.useRef)(); 26878 freshClientId.current = clientId; 26879 // Always return an object, even if no ref exists for a given client ID, so 26880 // that `current` works at a later point. 26881 return (0,external_wp_element_namespaceObject.useMemo)(() => ({ 26882 get current() { 26883 let element = null; 26884 26885 // Multiple refs may be created for a single block. Find the 26886 // first that has an element set. 26887 for (const [ref, id] of refs.entries()) { 26888 if (id === freshClientId.current && ref.current) { 26889 element = ref.current; 26890 } 26891 } 26892 return element; 26893 } 26894 }), []); 26895 } 26896 26897 /** 26898 * Return the element for a given client ID. Updates whenever the element 26899 * changes, becomes available, or disappears. 26900 * 26901 * @param {string} clientId The client ID to an element for. 26902 * 26903 * @return {Element|null} The block's wrapper element. 26904 */ 26905 function useBlockElement(clientId) { 26906 const { 26907 callbacks 26908 } = (0,external_wp_element_namespaceObject.useContext)(BlockRefs); 26909 const ref = useBlockRef(clientId); 26910 const [element, setElement] = (0,external_wp_element_namespaceObject.useState)(null); 26911 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 26912 if (!clientId) { 26913 return; 26914 } 26915 callbacks.set(setElement, clientId); 26916 return () => { 26917 callbacks.delete(setElement); 26918 }; 26919 }, [clientId]); 26920 return ref.current || element; 26921 } 26922 26923 26924 26925 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/contrast-checker.js 26926 26927 /** 26928 * WordPress dependencies 26929 */ 26930 26931 26932 /** 26933 * Internal dependencies 26934 */ 26935 26936 26937 function getComputedStyle(node) { 26938 return node.ownerDocument.defaultView.getComputedStyle(node); 26939 } 26940 function BlockColorContrastChecker({ 26941 clientId 26942 }) { 26943 const [detectedBackgroundColor, setDetectedBackgroundColor] = (0,external_wp_element_namespaceObject.useState)(); 26944 const [detectedColor, setDetectedColor] = (0,external_wp_element_namespaceObject.useState)(); 26945 const [detectedLinkColor, setDetectedLinkColor] = (0,external_wp_element_namespaceObject.useState)(); 26946 const ref = useBlockRef(clientId); 26947 26948 // There are so many things that can change the color of a block 26949 // So we perform this check on every render. 26950 // eslint-disable-next-line react-hooks/exhaustive-deps 26951 (0,external_wp_element_namespaceObject.useEffect)(() => { 26952 if (!ref.current) { 26953 return; 26954 } 26955 setDetectedColor(getComputedStyle(ref.current).color); 26956 const firstLinkElement = ref.current?.querySelector('a'); 26957 if (firstLinkElement && !!firstLinkElement.innerText) { 26958 setDetectedLinkColor(getComputedStyle(firstLinkElement).color); 26959 } 26960 let backgroundColorNode = ref.current; 26961 let backgroundColor = getComputedStyle(backgroundColorNode).backgroundColor; 26962 while (backgroundColor === 'rgba(0, 0, 0, 0)' && backgroundColorNode.parentNode && backgroundColorNode.parentNode.nodeType === backgroundColorNode.parentNode.ELEMENT_NODE) { 26963 backgroundColorNode = backgroundColorNode.parentNode; 26964 backgroundColor = getComputedStyle(backgroundColorNode).backgroundColor; 26965 } 26966 setDetectedBackgroundColor(backgroundColor); 26967 }); 26968 return (0,external_React_.createElement)(contrast_checker, { 26969 backgroundColor: detectedBackgroundColor, 26970 textColor: detectedColor, 26971 enableAlphaChecker: true, 26972 linkColor: detectedLinkColor 26973 }); 26974 } 26975 26976 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/color.js 26977 26978 /** 26979 * External dependencies 26980 */ 26981 26982 26983 /** 26984 * WordPress dependencies 26985 */ 26986 26987 26988 26989 26990 26991 /** 26992 * Internal dependencies 26993 */ 26994 26995 26996 26997 26998 26999 27000 27001 27002 27003 const COLOR_SUPPORT_KEY = 'color'; 27004 const hasColorSupport = blockNameOrType => { 27005 const colorSupport = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockNameOrType, COLOR_SUPPORT_KEY); 27006 return colorSupport && (colorSupport.link === true || colorSupport.gradient === true || colorSupport.background !== false || colorSupport.text !== false); 27007 }; 27008 const hasLinkColorSupport = blockType => { 27009 if (external_wp_element_namespaceObject.Platform.OS !== 'web') { 27010 return false; 27011 } 27012 const colorSupport = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockType, COLOR_SUPPORT_KEY); 27013 return colorSupport !== null && typeof colorSupport === 'object' && !!colorSupport.link; 27014 }; 27015 const hasGradientSupport = blockNameOrType => { 27016 const colorSupport = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockNameOrType, COLOR_SUPPORT_KEY); 27017 return colorSupport !== null && typeof colorSupport === 'object' && !!colorSupport.gradients; 27018 }; 27019 const hasBackgroundColorSupport = blockType => { 27020 const colorSupport = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockType, COLOR_SUPPORT_KEY); 27021 return colorSupport && colorSupport.background !== false; 27022 }; 27023 const hasTextColorSupport = blockType => { 27024 const colorSupport = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockType, COLOR_SUPPORT_KEY); 27025 return colorSupport && colorSupport.text !== false; 27026 }; 27027 27028 /** 27029 * Filters registered block settings, extending attributes to include 27030 * `backgroundColor` and `textColor` attribute. 27031 * 27032 * @param {Object} settings Original block settings. 27033 * 27034 * @return {Object} Filtered block settings. 27035 */ 27036 function color_addAttributes(settings) { 27037 if (!hasColorSupport(settings)) { 27038 return settings; 27039 } 27040 27041 // Allow blocks to specify their own attribute definition with default values if needed. 27042 if (!settings.attributes.backgroundColor) { 27043 Object.assign(settings.attributes, { 27044 backgroundColor: { 27045 type: 'string' 27046 } 27047 }); 27048 } 27049 if (!settings.attributes.textColor) { 27050 Object.assign(settings.attributes, { 27051 textColor: { 27052 type: 'string' 27053 } 27054 }); 27055 } 27056 if (hasGradientSupport(settings) && !settings.attributes.gradient) { 27057 Object.assign(settings.attributes, { 27058 gradient: { 27059 type: 'string' 27060 } 27061 }); 27062 } 27063 return settings; 27064 } 27065 27066 /** 27067 * Override props assigned to save component to inject colors classnames. 27068 * 27069 * @param {Object} props Additional props applied to save element. 27070 * @param {Object|string} blockNameOrType Block type. 27071 * @param {Object} attributes Block attributes. 27072 * 27073 * @return {Object} Filtered props applied to save element. 27074 */ 27075 function color_addSaveProps(props, blockNameOrType, attributes) { 27076 if (!hasColorSupport(blockNameOrType) || shouldSkipSerialization(blockNameOrType, COLOR_SUPPORT_KEY)) { 27077 return props; 27078 } 27079 const hasGradient = hasGradientSupport(blockNameOrType); 27080 27081 // I'd have preferred to avoid the "style" attribute usage here 27082 const { 27083 backgroundColor, 27084 textColor, 27085 gradient, 27086 style 27087 } = attributes; 27088 const shouldSerialize = feature => !shouldSkipSerialization(blockNameOrType, COLOR_SUPPORT_KEY, feature); 27089 27090 // Primary color classes must come before the `has-text-color`, 27091 // `has-background` and `has-link-color` classes to maintain backwards 27092 // compatibility and avoid block invalidations. 27093 const textClass = shouldSerialize('text') ? getColorClassName('color', textColor) : undefined; 27094 const gradientClass = shouldSerialize('gradients') ? __experimentalGetGradientClass(gradient) : undefined; 27095 const backgroundClass = shouldSerialize('background') ? getColorClassName('background-color', backgroundColor) : undefined; 27096 const serializeHasBackground = shouldSerialize('background') || shouldSerialize('gradients'); 27097 const hasBackground = backgroundColor || style?.color?.background || hasGradient && (gradient || style?.color?.gradient); 27098 const newClassName = classnames_default()(props.className, textClass, gradientClass, { 27099 // Don't apply the background class if there's a custom gradient. 27100 [backgroundClass]: (!hasGradient || !style?.color?.gradient) && !!backgroundClass, 27101 'has-text-color': shouldSerialize('text') && (textColor || style?.color?.text), 27102 'has-background': serializeHasBackground && hasBackground, 27103 'has-link-color': shouldSerialize('link') && style?.elements?.link?.color 27104 }); 27105 props.className = newClassName ? newClassName : undefined; 27106 return props; 27107 } 27108 function color_styleToAttributes(style) { 27109 const textColorValue = style?.color?.text; 27110 const textColorSlug = textColorValue?.startsWith('var:preset|color|') ? textColorValue.substring('var:preset|color|'.length) : undefined; 27111 const backgroundColorValue = style?.color?.background; 27112 const backgroundColorSlug = backgroundColorValue?.startsWith('var:preset|color|') ? backgroundColorValue.substring('var:preset|color|'.length) : undefined; 27113 const gradientValue = style?.color?.gradient; 27114 const gradientSlug = gradientValue?.startsWith('var:preset|gradient|') ? gradientValue.substring('var:preset|gradient|'.length) : undefined; 27115 const updatedStyle = { 27116 ...style 27117 }; 27118 updatedStyle.color = { 27119 ...updatedStyle.color, 27120 text: textColorSlug ? undefined : textColorValue, 27121 background: backgroundColorSlug ? undefined : backgroundColorValue, 27122 gradient: gradientSlug ? undefined : gradientValue 27123 }; 27124 return { 27125 style: utils_cleanEmptyObject(updatedStyle), 27126 textColor: textColorSlug, 27127 backgroundColor: backgroundColorSlug, 27128 gradient: gradientSlug 27129 }; 27130 } 27131 function color_attributesToStyle(attributes) { 27132 return { 27133 ...attributes.style, 27134 color: { 27135 ...attributes.style?.color, 27136 text: attributes.textColor ? 'var:preset|color|' + attributes.textColor : attributes.style?.color?.text, 27137 background: attributes.backgroundColor ? 'var:preset|color|' + attributes.backgroundColor : attributes.style?.color?.background, 27138 gradient: attributes.gradient ? 'var:preset|gradient|' + attributes.gradient : attributes.style?.color?.gradient 27139 } 27140 }; 27141 } 27142 function ColorInspectorControl({ 27143 children, 27144 resetAllFilter 27145 }) { 27146 const attributesResetAllFilter = (0,external_wp_element_namespaceObject.useCallback)(attributes => { 27147 const existingStyle = color_attributesToStyle(attributes); 27148 const updatedStyle = resetAllFilter(existingStyle); 27149 return { 27150 ...attributes, 27151 ...color_styleToAttributes(updatedStyle) 27152 }; 27153 }, [resetAllFilter]); 27154 return (0,external_React_.createElement)(inspector_controls, { 27155 group: "color", 27156 resetAllFilter: attributesResetAllFilter 27157 }, children); 27158 } 27159 function ColorEdit({ 27160 clientId, 27161 name, 27162 setAttributes, 27163 settings 27164 }) { 27165 const isEnabled = useHasColorPanel(settings); 27166 function selector(select) { 27167 const { 27168 style, 27169 textColor, 27170 backgroundColor, 27171 gradient 27172 } = select(store).getBlockAttributes(clientId) || {}; 27173 return { 27174 style, 27175 textColor, 27176 backgroundColor, 27177 gradient 27178 }; 27179 } 27180 const { 27181 style, 27182 textColor, 27183 backgroundColor, 27184 gradient 27185 } = (0,external_wp_data_namespaceObject.useSelect)(selector, [clientId]); 27186 const value = (0,external_wp_element_namespaceObject.useMemo)(() => { 27187 return color_attributesToStyle({ 27188 style, 27189 textColor, 27190 backgroundColor, 27191 gradient 27192 }); 27193 }, [style, textColor, backgroundColor, gradient]); 27194 const onChange = newStyle => { 27195 setAttributes(color_styleToAttributes(newStyle)); 27196 }; 27197 if (!isEnabled) { 27198 return null; 27199 } 27200 const defaultControls = (0,external_wp_blocks_namespaceObject.getBlockSupport)(name, [COLOR_SUPPORT_KEY, '__experimentalDefaultControls']); 27201 const enableContrastChecking = external_wp_element_namespaceObject.Platform.OS === 'web' && !value?.color?.gradient && (settings?.color?.text || settings?.color?.link) && 27202 // Contrast checking is enabled by default. 27203 // Deactivating it requires `enableContrastChecker` to have 27204 // an explicit value of `false`. 27205 false !== (0,external_wp_blocks_namespaceObject.getBlockSupport)(name, [COLOR_SUPPORT_KEY, 'enableContrastChecker']); 27206 return (0,external_React_.createElement)(ColorPanel, { 27207 as: ColorInspectorControl, 27208 panelId: clientId, 27209 settings: settings, 27210 value: value, 27211 onChange: onChange, 27212 defaultControls: defaultControls, 27213 enableContrastChecker: false !== (0,external_wp_blocks_namespaceObject.getBlockSupport)(name, [COLOR_SUPPORT_KEY, 'enableContrastChecker']) 27214 }, enableContrastChecking && (0,external_React_.createElement)(BlockColorContrastChecker, { 27215 clientId: clientId 27216 })); 27217 } 27218 function color_useBlockProps({ 27219 name, 27220 backgroundColor, 27221 textColor, 27222 gradient, 27223 style 27224 }) { 27225 const [userPalette, themePalette, defaultPalette] = use_settings_useSettings('color.palette.custom', 'color.palette.theme', 'color.palette.default'); 27226 const colors = (0,external_wp_element_namespaceObject.useMemo)(() => [...(userPalette || []), ...(themePalette || []), ...(defaultPalette || [])], [userPalette, themePalette, defaultPalette]); 27227 if (!hasColorSupport(name) || shouldSkipSerialization(name, COLOR_SUPPORT_KEY)) { 27228 return {}; 27229 } 27230 const extraStyles = {}; 27231 if (textColor && !shouldSkipSerialization(name, COLOR_SUPPORT_KEY, 'text')) { 27232 extraStyles.color = getColorObjectByAttributeValues(colors, textColor)?.color; 27233 } 27234 if (backgroundColor && !shouldSkipSerialization(name, COLOR_SUPPORT_KEY, 'background')) { 27235 extraStyles.backgroundColor = getColorObjectByAttributeValues(colors, backgroundColor)?.color; 27236 } 27237 const saveProps = color_addSaveProps({ 27238 style: extraStyles 27239 }, name, { 27240 textColor, 27241 backgroundColor, 27242 gradient, 27243 style 27244 }); 27245 const hasBackgroundValue = backgroundColor || style?.color?.background || gradient || style?.color?.gradient; 27246 return { 27247 ...saveProps, 27248 className: classnames_default()(saveProps.className, 27249 // Add background image classes in the editor, if not already handled by background color values. 27250 !hasBackgroundValue && getBackgroundImageClasses(style)) 27251 }; 27252 } 27253 /* harmony default export */ const color = ({ 27254 useBlockProps: color_useBlockProps, 27255 addSaveProps: color_addSaveProps, 27256 attributeKeys: ['backgroundColor', 'textColor', 'gradient', 'style'], 27257 hasSupport: hasColorSupport 27258 }); 27259 const MIGRATION_PATHS = { 27260 linkColor: [['style', 'elements', 'link', 'color', 'text']], 27261 textColor: [['textColor'], ['style', 'color', 'text']], 27262 backgroundColor: [['backgroundColor'], ['style', 'color', 'background']], 27263 gradient: [['gradient'], ['style', 'color', 'gradient']] 27264 }; 27265 function color_addTransforms(result, source, index, results) { 27266 const destinationBlockType = result.name; 27267 const activeSupports = { 27268 linkColor: hasLinkColorSupport(destinationBlockType), 27269 textColor: hasTextColorSupport(destinationBlockType), 27270 backgroundColor: hasBackgroundColorSupport(destinationBlockType), 27271 gradient: hasGradientSupport(destinationBlockType) 27272 }; 27273 return transformStyles(activeSupports, MIGRATION_PATHS, result, source, index, results); 27274 } 27275 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/color/addAttribute', color_addAttributes); 27276 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.switchToBlockType.transformedBlock', 'core/color/addTransforms', color_addTransforms); 27277 27278 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/font-family/index.js 27279 27280 /** 27281 * WordPress dependencies 27282 */ 27283 27284 27285 27286 /** 27287 * Internal dependencies 27288 */ 27289 27290 function FontFamilyControl({ 27291 value = '', 27292 onChange, 27293 fontFamilies, 27294 ...props 27295 }) { 27296 const [blockLevelFontFamilies] = use_settings_useSettings('typography.fontFamilies'); 27297 if (!fontFamilies) { 27298 fontFamilies = blockLevelFontFamilies; 27299 } 27300 if (!fontFamilies || fontFamilies.length === 0) { 27301 return null; 27302 } 27303 const options = [{ 27304 value: '', 27305 label: (0,external_wp_i18n_namespaceObject.__)('Default') 27306 }, ...fontFamilies.map(({ 27307 fontFamily, 27308 name 27309 }) => { 27310 return { 27311 value: fontFamily, 27312 label: name || fontFamily 27313 }; 27314 })]; 27315 return (0,external_React_.createElement)(external_wp_components_namespaceObject.SelectControl, { 27316 label: (0,external_wp_i18n_namespaceObject.__)('Font'), 27317 options: options, 27318 value: value, 27319 onChange: onChange, 27320 labelPosition: "top", 27321 ...props 27322 }); 27323 } 27324 27325 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/font-appearance-control/index.js 27326 27327 /** 27328 * WordPress dependencies 27329 */ 27330 27331 27332 27333 const FONT_STYLES = [{ 27334 name: (0,external_wp_i18n_namespaceObject._x)('Regular', 'font style'), 27335 value: 'normal' 27336 }, { 27337 name: (0,external_wp_i18n_namespaceObject._x)('Italic', 'font style'), 27338 value: 'italic' 27339 }]; 27340 const FONT_WEIGHTS = [{ 27341 name: (0,external_wp_i18n_namespaceObject._x)('Thin', 'font weight'), 27342 value: '100' 27343 }, { 27344 name: (0,external_wp_i18n_namespaceObject._x)('Extra Light', 'font weight'), 27345 value: '200' 27346 }, { 27347 name: (0,external_wp_i18n_namespaceObject._x)('Light', 'font weight'), 27348 value: '300' 27349 }, { 27350 name: (0,external_wp_i18n_namespaceObject._x)('Regular', 'font weight'), 27351 value: '400' 27352 }, { 27353 name: (0,external_wp_i18n_namespaceObject._x)('Medium', 'font weight'), 27354 value: '500' 27355 }, { 27356 name: (0,external_wp_i18n_namespaceObject._x)('Semi Bold', 'font weight'), 27357 value: '600' 27358 }, { 27359 name: (0,external_wp_i18n_namespaceObject._x)('Bold', 'font weight'), 27360 value: '700' 27361 }, { 27362 name: (0,external_wp_i18n_namespaceObject._x)('Extra Bold', 'font weight'), 27363 value: '800' 27364 }, { 27365 name: (0,external_wp_i18n_namespaceObject._x)('Black', 'font weight'), 27366 value: '900' 27367 }]; 27368 27369 /** 27370 * Adjusts font appearance field label in case either font styles or weights 27371 * are disabled. 27372 * 27373 * @param {boolean} hasFontStyles Whether font styles are enabled and present. 27374 * @param {boolean} hasFontWeights Whether font weights are enabled and present. 27375 * @return {string} A label representing what font appearance is being edited. 27376 */ 27377 const getFontAppearanceLabel = (hasFontStyles, hasFontWeights) => { 27378 if (!hasFontStyles) { 27379 return (0,external_wp_i18n_namespaceObject.__)('Font weight'); 27380 } 27381 if (!hasFontWeights) { 27382 return (0,external_wp_i18n_namespaceObject.__)('Font style'); 27383 } 27384 return (0,external_wp_i18n_namespaceObject.__)('Appearance'); 27385 }; 27386 27387 /** 27388 * Control to display unified font style and weight options. 27389 * 27390 * @param {Object} props Component props. 27391 * 27392 * @return {Element} Font appearance control. 27393 */ 27394 function FontAppearanceControl(props) { 27395 const { 27396 onChange, 27397 hasFontStyles = true, 27398 hasFontWeights = true, 27399 value: { 27400 fontStyle, 27401 fontWeight 27402 }, 27403 ...otherProps 27404 } = props; 27405 const hasStylesOrWeights = hasFontStyles || hasFontWeights; 27406 const label = getFontAppearanceLabel(hasFontStyles, hasFontWeights); 27407 const defaultOption = { 27408 key: 'default', 27409 name: (0,external_wp_i18n_namespaceObject.__)('Default'), 27410 style: { 27411 fontStyle: undefined, 27412 fontWeight: undefined 27413 } 27414 }; 27415 27416 // Combines both font style and weight options into a single dropdown. 27417 const combineOptions = () => { 27418 const combinedOptions = [defaultOption]; 27419 FONT_STYLES.forEach(({ 27420 name: styleName, 27421 value: styleValue 27422 }) => { 27423 FONT_WEIGHTS.forEach(({ 27424 name: weightName, 27425 value: weightValue 27426 }) => { 27427 const optionName = styleValue === 'normal' ? weightName : (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: 1: Font weight name. 2: Font style name. */ 27428 (0,external_wp_i18n_namespaceObject.__)('%1$s %2$s'), weightName, styleName); 27429 combinedOptions.push({ 27430 key: `$styleValue}-$weightValue}`, 27431 name: optionName, 27432 style: { 27433 fontStyle: styleValue, 27434 fontWeight: weightValue 27435 } 27436 }); 27437 }); 27438 }); 27439 return combinedOptions; 27440 }; 27441 27442 // Generates select options for font styles only. 27443 const styleOptions = () => { 27444 const combinedOptions = [defaultOption]; 27445 FONT_STYLES.forEach(({ 27446 name, 27447 value 27448 }) => { 27449 combinedOptions.push({ 27450 key: value, 27451 name, 27452 style: { 27453 fontStyle: value, 27454 fontWeight: undefined 27455 } 27456 }); 27457 }); 27458 return combinedOptions; 27459 }; 27460 27461 // Generates select options for font weights only. 27462 const weightOptions = () => { 27463 const combinedOptions = [defaultOption]; 27464 FONT_WEIGHTS.forEach(({ 27465 name, 27466 value 27467 }) => { 27468 combinedOptions.push({ 27469 key: value, 27470 name, 27471 style: { 27472 fontStyle: undefined, 27473 fontWeight: value 27474 } 27475 }); 27476 }); 27477 return combinedOptions; 27478 }; 27479 27480 // Map font styles and weights to select options. 27481 const selectOptions = (0,external_wp_element_namespaceObject.useMemo)(() => { 27482 if (hasFontStyles && hasFontWeights) { 27483 return combineOptions(); 27484 } 27485 return hasFontStyles ? styleOptions() : weightOptions(); 27486 }, [props.options]); 27487 27488 // Find current selection by comparing font style & weight against options, 27489 // and fall back to the Default option if there is no matching option. 27490 const currentSelection = selectOptions.find(option => option.style.fontStyle === fontStyle && option.style.fontWeight === fontWeight) || selectOptions[0]; 27491 27492 // Adjusts screen reader description based on styles or weights. 27493 const getDescribedBy = () => { 27494 if (!currentSelection) { 27495 return (0,external_wp_i18n_namespaceObject.__)('No selected font appearance'); 27496 } 27497 if (!hasFontStyles) { 27498 return (0,external_wp_i18n_namespaceObject.sprintf)( 27499 // translators: %s: Currently selected font weight. 27500 (0,external_wp_i18n_namespaceObject.__)('Currently selected font weight: %s'), currentSelection.name); 27501 } 27502 if (!hasFontWeights) { 27503 return (0,external_wp_i18n_namespaceObject.sprintf)( 27504 // translators: %s: Currently selected font style. 27505 (0,external_wp_i18n_namespaceObject.__)('Currently selected font style: %s'), currentSelection.name); 27506 } 27507 return (0,external_wp_i18n_namespaceObject.sprintf)( 27508 // translators: %s: Currently selected font appearance. 27509 (0,external_wp_i18n_namespaceObject.__)('Currently selected font appearance: %s'), currentSelection.name); 27510 }; 27511 return hasStylesOrWeights && (0,external_React_.createElement)(external_wp_components_namespaceObject.CustomSelectControl, { 27512 ...otherProps, 27513 className: "components-font-appearance-control", 27514 label: label, 27515 describedBy: getDescribedBy(), 27516 options: selectOptions, 27517 value: currentSelection, 27518 onChange: ({ 27519 selectedItem 27520 }) => onChange(selectedItem.style), 27521 __nextUnconstrainedWidth: true 27522 }); 27523 } 27524 27525 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/line-height-control/utils.js 27526 const BASE_DEFAULT_VALUE = 1.5; 27527 const STEP = 0.01; 27528 /** 27529 * A spin factor of 10 allows the spin controls to increment/decrement by 0.1. 27530 * e.g. A line-height value of 1.55 will increment to 1.65. 27531 */ 27532 const SPIN_FACTOR = 10; 27533 /** 27534 * There are varying value types within LineHeightControl: 27535 * 27536 * {undefined} Initial value. No changes from the user. 27537 * {string} Input value. Value consumed/outputted by the input. Empty would be ''. 27538 * {number} Block attribute type. Input value needs to be converted for attribute setting. 27539 * 27540 * Note: If the value is undefined, the input requires it to be an empty string ('') 27541 * in order to be considered "controlled" by props (rather than internal state). 27542 */ 27543 const RESET_VALUE = ''; 27544 27545 /** 27546 * Determines if the lineHeight attribute has been properly defined. 27547 * 27548 * @param {any} lineHeight The value to check. 27549 * 27550 * @return {boolean} Whether the lineHeight attribute is valid. 27551 */ 27552 function isLineHeightDefined(lineHeight) { 27553 return lineHeight !== undefined && lineHeight !== RESET_VALUE; 27554 } 27555 27556 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/line-height-control/index.js 27557 27558 /** 27559 * WordPress dependencies 27560 */ 27561 27562 27563 27564 27565 /** 27566 * Internal dependencies 27567 */ 27568 27569 const line_height_control_LineHeightControl = ({ 27570 value: lineHeight, 27571 onChange, 27572 /** Start opting into the new margin-free styles that will become the default in a future version. */ 27573 __nextHasNoMarginBottom = false, 27574 __unstableInputWidth = '60px', 27575 ...otherProps 27576 }) => { 27577 const isDefined = isLineHeightDefined(lineHeight); 27578 const adjustNextValue = (nextValue, wasTypedOrPasted) => { 27579 // Set the next value without modification if lineHeight has been defined. 27580 if (isDefined) return nextValue; 27581 27582 /** 27583 * The following logic handles the initial spin up/down action 27584 * (from an undefined value state) so that the next values are better suited for 27585 * line-height rendering. For example, the first spin up should immediately 27586 * go to 1.6, rather than the normally expected 0.1. 27587 * 27588 * Spin up/down actions can be triggered by keydowns of the up/down arrow keys, 27589 * dragging the input or by clicking the spin buttons. 27590 */ 27591 const spin = STEP * SPIN_FACTOR; 27592 switch (`$nextValue}`) { 27593 case `$spin}`: 27594 // Increment by spin value. 27595 return BASE_DEFAULT_VALUE + spin; 27596 case '0': 27597 { 27598 // This means the user explicitly input '0', rather than using the 27599 // spin down action from an undefined value state. 27600 if (wasTypedOrPasted) return nextValue; 27601 // Decrement by spin value. 27602 return BASE_DEFAULT_VALUE - spin; 27603 } 27604 case '': 27605 return BASE_DEFAULT_VALUE; 27606 default: 27607 return nextValue; 27608 } 27609 }; 27610 const stateReducer = (state, action) => { 27611 // Be careful when changing this — cross-browser behavior of the 27612 // `inputType` field in `input` events are inconsistent. 27613 // For example, Firefox emits an input event with inputType="insertReplacementText" 27614 // on spin button clicks, while other browsers do not even emit an input event. 27615 const wasTypedOrPasted = ['insertText', 'insertFromPaste'].includes(action.payload.event.nativeEvent?.inputType); 27616 const value = adjustNextValue(state.value, wasTypedOrPasted); 27617 return { 27618 ...state, 27619 value 27620 }; 27621 }; 27622 const value = isDefined ? lineHeight : RESET_VALUE; 27623 if (!__nextHasNoMarginBottom) { 27624 external_wp_deprecated_default()('Bottom margin styles for wp.blockEditor.LineHeightControl', { 27625 since: '6.0', 27626 version: '6.4', 27627 hint: 'Set the `__nextHasNoMarginBottom` prop to true to start opting into the new styles, which will become the default in a future version' 27628 }); 27629 } 27630 const deprecatedStyles = __nextHasNoMarginBottom ? undefined : { 27631 marginBottom: 24 27632 }; 27633 const handleOnChange = (nextValue, { 27634 event 27635 }) => { 27636 if (nextValue === '') { 27637 onChange(); 27638 return; 27639 } 27640 if (event.type === 'click') { 27641 onChange(adjustNextValue(`$nextValue}`, false)); 27642 return; 27643 } 27644 onChange(`$nextValue}`); 27645 }; 27646 return (0,external_React_.createElement)("div", { 27647 className: "block-editor-line-height-control", 27648 style: deprecatedStyles 27649 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalNumberControl, { 27650 ...otherProps, 27651 __unstableInputWidth: __unstableInputWidth, 27652 __unstableStateReducer: stateReducer, 27653 onChange: handleOnChange, 27654 label: (0,external_wp_i18n_namespaceObject.__)('Line height'), 27655 placeholder: BASE_DEFAULT_VALUE, 27656 step: STEP, 27657 spinFactor: SPIN_FACTOR, 27658 value: value, 27659 min: 0, 27660 spinControls: "custom" 27661 })); 27662 }; 27663 27664 /** 27665 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/line-height-control/README.md 27666 */ 27667 /* harmony default export */ const line_height_control = (line_height_control_LineHeightControl); 27668 27669 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/letter-spacing-control/index.js 27670 27671 /** 27672 * WordPress dependencies 27673 */ 27674 27675 27676 27677 /** 27678 * Internal dependencies 27679 */ 27680 27681 27682 /** 27683 * Control for letter-spacing. 27684 * 27685 * @param {Object} props Component props. 27686 * @param {string} props.value Currently selected letter-spacing. 27687 * @param {Function} props.onChange Handles change in letter-spacing selection. 27688 * @param {string|number|undefined} props.__unstableInputWidth Input width to pass through to inner UnitControl. Should be a valid CSS value. 27689 * 27690 * @return {Element} Letter-spacing control. 27691 */ 27692 function LetterSpacingControl({ 27693 value, 27694 onChange, 27695 __unstableInputWidth = '60px', 27696 ...otherProps 27697 }) { 27698 const [availableUnits] = use_settings_useSettings('spacing.units'); 27699 const units = (0,external_wp_components_namespaceObject.__experimentalUseCustomUnits)({ 27700 availableUnits: availableUnits || ['px', 'em', 'rem'], 27701 defaultValues: { 27702 px: 2, 27703 em: 0.2, 27704 rem: 0.2 27705 } 27706 }); 27707 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalUnitControl, { 27708 ...otherProps, 27709 label: (0,external_wp_i18n_namespaceObject.__)('Letter spacing'), 27710 value: value, 27711 __unstableInputWidth: __unstableInputWidth, 27712 units: units, 27713 onChange: onChange 27714 }); 27715 } 27716 27717 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/reset.js 27718 27719 /** 27720 * WordPress dependencies 27721 */ 27722 27723 const reset_reset = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 27724 xmlns: "http://www.w3.org/2000/svg", 27725 viewBox: "0 0 24 24" 27726 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 27727 d: "M7 11.5h10V13H7z" 27728 })); 27729 /* harmony default export */ const library_reset = (reset_reset); 27730 27731 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/format-uppercase.js 27732 27733 /** 27734 * WordPress dependencies 27735 */ 27736 27737 const formatUppercase = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 27738 xmlns: "http://www.w3.org/2000/svg", 27739 viewBox: "0 0 24 24" 27740 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 27741 d: "M6.1 6.8L2.1 18h1.6l1.1-3h4.3l1.1 3h1.6l-4-11.2H6.1zm-.8 6.8L7 8.9l1.7 4.7H5.3zm15.1-.7c-.4-.5-.9-.8-1.6-1 .4-.2.7-.5.8-.9.2-.4.3-.9.3-1.4 0-.9-.3-1.6-.8-2-.6-.5-1.3-.7-2.4-.7h-3.5V18h4.2c1.1 0 2-.3 2.6-.8.6-.6 1-1.4 1-2.4-.1-.8-.3-1.4-.6-1.9zm-5.7-4.7h1.8c.6 0 1.1.1 1.4.4.3.2.5.7.5 1.3 0 .6-.2 1.1-.5 1.3-.3.2-.8.4-1.4.4h-1.8V8.2zm4 8c-.4.3-.9.5-1.5.5h-2.6v-3.8h2.6c1.4 0 2 .6 2 1.9.1.6-.1 1-.5 1.4z" 27742 })); 27743 /* harmony default export */ const format_uppercase = (formatUppercase); 27744 27745 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/format-lowercase.js 27746 27747 /** 27748 * WordPress dependencies 27749 */ 27750 27751 const formatLowercase = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 27752 xmlns: "http://www.w3.org/2000/svg", 27753 viewBox: "0 0 24 24" 27754 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 27755 d: "M11 16.8c-.1-.1-.2-.3-.3-.5v-2.6c0-.9-.1-1.7-.3-2.2-.2-.5-.5-.9-.9-1.2-.4-.2-.9-.3-1.6-.3-.5 0-1 .1-1.5.2s-.9.3-1.2.6l.2 1.2c.4-.3.7-.4 1.1-.5.3-.1.7-.2 1-.2.6 0 1 .1 1.3.4.3.2.4.7.4 1.4-1.2 0-2.3.2-3.3.7s-1.4 1.1-1.4 2.1c0 .7.2 1.2.7 1.6.4.4 1 .6 1.8.6.9 0 1.7-.4 2.4-1.2.1.3.2.5.4.7.1.2.3.3.6.4.3.1.6.1 1.1.1h.1l.2-1.2h-.1c-.4.1-.6 0-.7-.1zM9.2 16c-.2.3-.5.6-.9.8-.3.1-.7.2-1.1.2-.4 0-.7-.1-.9-.3-.2-.2-.3-.5-.3-.9 0-.6.2-1 .7-1.3.5-.3 1.3-.4 2.5-.5v2zm10.6-3.9c-.3-.6-.7-1.1-1.2-1.5-.6-.4-1.2-.6-1.9-.6-.5 0-.9.1-1.4.3-.4.2-.8.5-1.1.8V6h-1.4v12h1.3l.2-1c.2.4.6.6 1 .8.4.2.9.3 1.4.3.7 0 1.2-.2 1.8-.5.5-.4 1-.9 1.3-1.5.3-.6.5-1.3.5-2.1-.1-.6-.2-1.3-.5-1.9zm-1.7 4c-.4.5-.9.8-1.6.8s-1.2-.2-1.7-.7c-.4-.5-.7-1.2-.7-2.1 0-.9.2-1.6.7-2.1.4-.5 1-.7 1.7-.7s1.2.3 1.6.8c.4.5.6 1.2.6 2s-.2 1.4-.6 2z" 27756 })); 27757 /* harmony default export */ const format_lowercase = (formatLowercase); 27758 27759 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/format-capitalize.js 27760 27761 /** 27762 * WordPress dependencies 27763 */ 27764 27765 const formatCapitalize = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 27766 xmlns: "http://www.w3.org/2000/svg", 27767 viewBox: "0 0 24 24" 27768 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 27769 d: "M7.1 6.8L3.1 18h1.6l1.1-3h4.3l1.1 3h1.6l-4-11.2H7.1zm-.8 6.8L8 8.9l1.7 4.7H6.3zm14.5-1.5c-.3-.6-.7-1.1-1.2-1.5-.6-.4-1.2-.6-1.9-.6-.5 0-.9.1-1.4.3-.4.2-.8.5-1.1.8V6h-1.4v12h1.3l.2-1c.2.4.6.6 1 .8.4.2.9.3 1.4.3.7 0 1.2-.2 1.8-.5.5-.4 1-.9 1.3-1.5.3-.6.5-1.3.5-2.1-.1-.6-.2-1.3-.5-1.9zm-1.7 4c-.4.5-.9.8-1.6.8s-1.2-.2-1.7-.7c-.4-.5-.7-1.2-.7-2.1 0-.9.2-1.6.7-2.1.4-.5 1-.7 1.7-.7s1.2.3 1.6.8c.4.5.6 1.2.6 2 .1.8-.2 1.4-.6 2z" 27770 })); 27771 /* harmony default export */ const format_capitalize = (formatCapitalize); 27772 27773 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/text-transform-control/index.js 27774 27775 /** 27776 * External dependencies 27777 */ 27778 27779 27780 /** 27781 * WordPress dependencies 27782 */ 27783 27784 27785 27786 const TEXT_TRANSFORMS = [{ 27787 name: (0,external_wp_i18n_namespaceObject.__)('None'), 27788 value: 'none', 27789 icon: library_reset 27790 }, { 27791 name: (0,external_wp_i18n_namespaceObject.__)('Uppercase'), 27792 value: 'uppercase', 27793 icon: format_uppercase 27794 }, { 27795 name: (0,external_wp_i18n_namespaceObject.__)('Lowercase'), 27796 value: 'lowercase', 27797 icon: format_lowercase 27798 }, { 27799 name: (0,external_wp_i18n_namespaceObject.__)('Capitalize'), 27800 value: 'capitalize', 27801 icon: format_capitalize 27802 }]; 27803 27804 /** 27805 * Control to facilitate text transform selections. 27806 * 27807 * @param {Object} props Component props. 27808 * @param {string} props.className Class name to add to the control. 27809 * @param {string} props.value Currently selected text transform. 27810 * @param {Function} props.onChange Handles change in text transform selection. 27811 * 27812 * @return {Element} Text transform control. 27813 */ 27814 function TextTransformControl({ 27815 className, 27816 value, 27817 onChange 27818 }) { 27819 return (0,external_React_.createElement)("fieldset", { 27820 className: classnames_default()('block-editor-text-transform-control', className) 27821 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.BaseControl.VisualLabel, { 27822 as: "legend" 27823 }, (0,external_wp_i18n_namespaceObject.__)('Letter case')), (0,external_React_.createElement)("div", { 27824 className: "block-editor-text-transform-control__buttons" 27825 }, TEXT_TRANSFORMS.map(textTransform => { 27826 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 27827 key: textTransform.value, 27828 icon: textTransform.icon, 27829 label: textTransform.name, 27830 isPressed: textTransform.value === value, 27831 onClick: () => { 27832 onChange(textTransform.value === value ? undefined : textTransform.value); 27833 } 27834 }); 27835 }))); 27836 } 27837 27838 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/format-underline.js 27839 27840 /** 27841 * WordPress dependencies 27842 */ 27843 27844 const formatUnderline = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 27845 xmlns: "http://www.w3.org/2000/svg", 27846 viewBox: "0 0 24 24" 27847 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 27848 d: "M7 18v1h10v-1H7zm5-2c1.5 0 2.6-.4 3.4-1.2.8-.8 1.1-2 1.1-3.5V5H15v5.8c0 1.2-.2 2.1-.6 2.8-.4.7-1.2 1-2.4 1s-2-.3-2.4-1c-.4-.7-.6-1.6-.6-2.8V5H7.5v6.2c0 1.5.4 2.7 1.1 3.5.8.9 1.9 1.3 3.4 1.3z" 27849 })); 27850 /* harmony default export */ const format_underline = (formatUnderline); 27851 27852 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/format-strikethrough.js 27853 27854 /** 27855 * WordPress dependencies 27856 */ 27857 27858 const formatStrikethrough = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 27859 xmlns: "http://www.w3.org/2000/svg", 27860 viewBox: "0 0 24 24" 27861 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 27862 d: "M9.1 9v-.5c0-.6.2-1.1.7-1.4.5-.3 1.2-.5 2-.5.7 0 1.4.1 2.1.3.7.2 1.4.5 2.1.9l.2-1.9c-.6-.3-1.2-.5-1.9-.7-.8-.1-1.6-.2-2.4-.2-1.5 0-2.7.3-3.6 1-.8.7-1.2 1.5-1.2 2.6V9h2zM20 12H4v1h8.3c.3.1.6.2.8.3.5.2.9.5 1.1.8.3.3.4.7.4 1.2 0 .7-.2 1.1-.8 1.5-.5.3-1.2.5-2.1.5-.8 0-1.6-.1-2.4-.3-.8-.2-1.5-.5-2.2-.8L7 18.1c.5.2 1.2.4 2 .6.8.2 1.6.3 2.4.3 1.7 0 3-.3 3.9-1 .9-.7 1.3-1.6 1.3-2.8 0-.9-.2-1.7-.7-2.2H20v-1z" 27863 })); 27864 /* harmony default export */ const format_strikethrough = (formatStrikethrough); 27865 27866 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/text-decoration-control/index.js 27867 27868 /** 27869 * External dependencies 27870 */ 27871 27872 27873 /** 27874 * WordPress dependencies 27875 */ 27876 27877 27878 27879 const TEXT_DECORATIONS = [{ 27880 name: (0,external_wp_i18n_namespaceObject.__)('None'), 27881 value: 'none', 27882 icon: library_reset 27883 }, { 27884 name: (0,external_wp_i18n_namespaceObject.__)('Underline'), 27885 value: 'underline', 27886 icon: format_underline 27887 }, { 27888 name: (0,external_wp_i18n_namespaceObject.__)('Strikethrough'), 27889 value: 'line-through', 27890 icon: format_strikethrough 27891 }]; 27892 27893 /** 27894 * Control to facilitate text decoration selections. 27895 * 27896 * @param {Object} props Component props. 27897 * @param {string} props.value Currently selected text decoration. 27898 * @param {Function} props.onChange Handles change in text decoration selection. 27899 * @param {string} [props.className] Additional class name to apply. 27900 * 27901 * @return {Element} Text decoration control. 27902 */ 27903 function TextDecorationControl({ 27904 value, 27905 onChange, 27906 className 27907 }) { 27908 return (0,external_React_.createElement)("fieldset", { 27909 className: classnames_default()('block-editor-text-decoration-control', className) 27910 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.BaseControl.VisualLabel, { 27911 as: "legend" 27912 }, (0,external_wp_i18n_namespaceObject.__)('Decoration')), (0,external_React_.createElement)("div", { 27913 className: "block-editor-text-decoration-control__buttons" 27914 }, TEXT_DECORATIONS.map(textDecoration => { 27915 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 27916 key: textDecoration.value, 27917 icon: textDecoration.icon, 27918 label: textDecoration.name, 27919 isPressed: textDecoration.value === value, 27920 onClick: () => { 27921 onChange(textDecoration.value === value ? undefined : textDecoration.value); 27922 } 27923 }); 27924 }))); 27925 } 27926 27927 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/text-horizontal.js 27928 27929 /** 27930 * WordPress dependencies 27931 */ 27932 27933 const textHorizontal = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 27934 xmlns: "http://www.w3.org/2000/svg", 27935 viewBox: "0 0 24 24" 27936 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 27937 d: "M8.2 14.4h3.9L13 17h1.7L11 6.5H9.3L5.6 17h1.7l.9-2.6zm2-5.5 1.4 4H8.8l1.4-4zm7.4 7.5-1.3.8.8 1.4H5.5V20h14.3l-2.2-3.6z" 27938 })); 27939 /* harmony default export */ const text_horizontal = (textHorizontal); 27940 27941 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/text-vertical.js 27942 27943 /** 27944 * WordPress dependencies 27945 */ 27946 27947 const textVertical = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 27948 xmlns: "http://www.w3.org/2000/svg", 27949 viewBox: "0 0 24 24" 27950 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 27951 d: "M7 5.6v1.7l2.6.9v3.9L7 13v1.7L17.5 11V9.3L7 5.6zm4.2 6V8.8l4 1.4-4 1.4zm-5.7 5.6V5.5H4v14.3l3.6-2.2-.8-1.3-1.3.9z" 27952 })); 27953 /* harmony default export */ const text_vertical = (textVertical); 27954 27955 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/writing-mode-control/index.js 27956 27957 /** 27958 * External dependencies 27959 */ 27960 27961 27962 /** 27963 * WordPress dependencies 27964 */ 27965 27966 27967 27968 const WRITING_MODES = [{ 27969 name: (0,external_wp_i18n_namespaceObject.__)('Horizontal'), 27970 value: 'horizontal-tb', 27971 icon: text_horizontal 27972 }, { 27973 name: (0,external_wp_i18n_namespaceObject.__)('Vertical'), 27974 value: (0,external_wp_i18n_namespaceObject.isRTL)() ? 'vertical-lr' : 'vertical-rl', 27975 icon: text_vertical 27976 }]; 27977 27978 /** 27979 * Control to facilitate writing mode selections. 27980 * 27981 * @param {Object} props Component props. 27982 * @param {string} props.className Class name to add to the control. 27983 * @param {string} props.value Currently selected writing mode. 27984 * @param {Function} props.onChange Handles change in the writing mode selection. 27985 * 27986 * @return {Element} Writing Mode control. 27987 */ 27988 function WritingModeControl({ 27989 className, 27990 value, 27991 onChange 27992 }) { 27993 return (0,external_React_.createElement)("fieldset", { 27994 className: classnames_default()('block-editor-writing-mode-control', className) 27995 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.BaseControl.VisualLabel, { 27996 as: "legend" 27997 }, (0,external_wp_i18n_namespaceObject.__)('Orientation')), (0,external_React_.createElement)("div", { 27998 className: "block-editor-writing-mode-control__buttons" 27999 }, WRITING_MODES.map(writingMode => { 28000 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 28001 key: writingMode.value, 28002 icon: writingMode.icon, 28003 label: writingMode.name, 28004 isPressed: writingMode.value === value, 28005 onClick: () => { 28006 onChange(writingMode.value === value ? undefined : writingMode.value); 28007 } 28008 }); 28009 }))); 28010 } 28011 28012 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/global-styles/typography-panel.js 28013 28014 /** 28015 * WordPress dependencies 28016 */ 28017 28018 28019 28020 28021 /** 28022 * Internal dependencies 28023 */ 28024 28025 28026 28027 28028 28029 28030 28031 28032 28033 28034 const MIN_TEXT_COLUMNS = 1; 28035 const MAX_TEXT_COLUMNS = 6; 28036 function useHasTypographyPanel(settings) { 28037 const hasFontFamily = useHasFontFamilyControl(settings); 28038 const hasLineHeight = useHasLineHeightControl(settings); 28039 const hasFontAppearance = useHasAppearanceControl(settings); 28040 const hasLetterSpacing = useHasLetterSpacingControl(settings); 28041 const hasTextTransform = useHasTextTransformControl(settings); 28042 const hasTextDecoration = useHasTextDecorationControl(settings); 28043 const hasWritingMode = useHasWritingModeControl(settings); 28044 const hasTextColumns = useHasTextColumnsControl(settings); 28045 const hasFontSize = useHasFontSizeControl(settings); 28046 return hasFontFamily || hasLineHeight || hasFontAppearance || hasLetterSpacing || hasTextTransform || hasFontSize || hasTextDecoration || hasWritingMode || hasTextColumns; 28047 } 28048 function useHasFontSizeControl(settings) { 28049 return hasOriginValue(settings?.typography?.fontSizes) || settings?.typography?.customFontSize; 28050 } 28051 function useHasFontFamilyControl(settings) { 28052 return hasOriginValue(settings?.typography?.fontFamilies); 28053 } 28054 function useHasLineHeightControl(settings) { 28055 return settings?.typography?.lineHeight; 28056 } 28057 function useHasAppearanceControl(settings) { 28058 return settings?.typography?.fontStyle || settings?.typography?.fontWeight; 28059 } 28060 function useAppearanceControlLabel(settings) { 28061 if (!settings?.typography?.fontStyle) { 28062 return (0,external_wp_i18n_namespaceObject.__)('Font weight'); 28063 } 28064 if (!settings?.typography?.fontWeight) { 28065 return (0,external_wp_i18n_namespaceObject.__)('Font style'); 28066 } 28067 return (0,external_wp_i18n_namespaceObject.__)('Appearance'); 28068 } 28069 function useHasLetterSpacingControl(settings) { 28070 return settings?.typography?.letterSpacing; 28071 } 28072 function useHasTextTransformControl(settings) { 28073 return settings?.typography?.textTransform; 28074 } 28075 function useHasTextDecorationControl(settings) { 28076 return settings?.typography?.textDecoration; 28077 } 28078 function useHasWritingModeControl(settings) { 28079 return settings?.typography?.writingMode; 28080 } 28081 function useHasTextColumnsControl(settings) { 28082 return settings?.typography?.textColumns; 28083 } 28084 function getUniqueFontSizesBySlug(settings) { 28085 var _settings$typography$, _overrideOrigins; 28086 const fontSizes = (_settings$typography$ = settings?.typography?.fontSizes) !== null && _settings$typography$ !== void 0 ? _settings$typography$ : {}; 28087 const overriddenFontSizes = (_overrideOrigins = overrideOrigins(fontSizes)) !== null && _overrideOrigins !== void 0 ? _overrideOrigins : []; 28088 const uniqueSizes = []; 28089 for (const currentSize of overriddenFontSizes) { 28090 if (!uniqueSizes.some(({ 28091 slug 28092 }) => slug === currentSize.slug)) { 28093 uniqueSizes.push(currentSize); 28094 } 28095 } 28096 return uniqueSizes; 28097 } 28098 function TypographyToolsPanel({ 28099 resetAllFilter, 28100 onChange, 28101 value, 28102 panelId, 28103 children 28104 }) { 28105 const resetAll = () => { 28106 const updatedValue = resetAllFilter(value); 28107 onChange(updatedValue); 28108 }; 28109 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanel, { 28110 label: (0,external_wp_i18n_namespaceObject.__)('Typography'), 28111 resetAll: resetAll, 28112 panelId: panelId, 28113 dropdownMenuProps: TOOLSPANEL_DROPDOWNMENU_PROPS 28114 }, children); 28115 } 28116 const typography_panel_DEFAULT_CONTROLS = { 28117 fontFamily: true, 28118 fontSize: true, 28119 fontAppearance: true, 28120 lineHeight: true, 28121 letterSpacing: true, 28122 textTransform: true, 28123 textDecoration: true, 28124 writingMode: true, 28125 textColumns: true 28126 }; 28127 function TypographyPanel({ 28128 as: Wrapper = TypographyToolsPanel, 28129 value, 28130 onChange, 28131 inheritedValue = value, 28132 settings, 28133 panelId, 28134 defaultControls = typography_panel_DEFAULT_CONTROLS 28135 }) { 28136 var _settings$typography$2; 28137 const decodeValue = rawValue => getValueFromVariable({ 28138 settings 28139 }, '', rawValue); 28140 28141 // Font Family 28142 const hasFontFamilyEnabled = useHasFontFamilyControl(settings); 28143 const fontFamilies = (_settings$typography$2 = settings?.typography?.fontFamilies) !== null && _settings$typography$2 !== void 0 ? _settings$typography$2 : {}; 28144 const mergedFontFamilies = fontFamilies ? mergeOrigins(fontFamilies) : []; 28145 const fontFamily = decodeValue(inheritedValue?.typography?.fontFamily); 28146 const setFontFamily = newValue => { 28147 const slug = mergedFontFamilies?.find(({ 28148 fontFamily: f 28149 }) => f === newValue)?.slug; 28150 onChange(setImmutably(value, ['typography', 'fontFamily'], slug ? `var:preset|font-family|$slug}` : newValue || undefined)); 28151 }; 28152 const hasFontFamily = () => !!value?.typography?.fontFamily; 28153 const resetFontFamily = () => setFontFamily(undefined); 28154 28155 // Font Size 28156 const hasFontSizeEnabled = useHasFontSizeControl(settings); 28157 const disableCustomFontSizes = !settings?.typography?.customFontSize; 28158 const mergedFontSizes = getUniqueFontSizesBySlug(settings); 28159 const fontSize = decodeValue(inheritedValue?.typography?.fontSize); 28160 const setFontSize = (newValue, metadata) => { 28161 const actualValue = !!metadata?.slug ? `var:preset|font-size|$metadata?.slug}` : newValue; 28162 onChange(setImmutably(value, ['typography', 'fontSize'], actualValue || undefined)); 28163 }; 28164 const hasFontSize = () => !!value?.typography?.fontSize; 28165 const resetFontSize = () => setFontSize(undefined); 28166 28167 // Appearance 28168 const hasAppearanceControl = useHasAppearanceControl(settings); 28169 const appearanceControlLabel = useAppearanceControlLabel(settings); 28170 const hasFontStyles = settings?.typography?.fontStyle; 28171 const hasFontWeights = settings?.typography?.fontWeight; 28172 const fontStyle = decodeValue(inheritedValue?.typography?.fontStyle); 28173 const fontWeight = decodeValue(inheritedValue?.typography?.fontWeight); 28174 const setFontAppearance = ({ 28175 fontStyle: newFontStyle, 28176 fontWeight: newFontWeight 28177 }) => { 28178 onChange({ 28179 ...value, 28180 typography: { 28181 ...value?.typography, 28182 fontStyle: newFontStyle || undefined, 28183 fontWeight: newFontWeight || undefined 28184 } 28185 }); 28186 }; 28187 const hasFontAppearance = () => !!value?.typography?.fontStyle || !!value?.typography?.fontWeight; 28188 const resetFontAppearance = () => { 28189 setFontAppearance({}); 28190 }; 28191 28192 // Line Height 28193 const hasLineHeightEnabled = useHasLineHeightControl(settings); 28194 const lineHeight = decodeValue(inheritedValue?.typography?.lineHeight); 28195 const setLineHeight = newValue => { 28196 onChange(setImmutably(value, ['typography', 'lineHeight'], newValue || undefined)); 28197 }; 28198 const hasLineHeight = () => value?.typography?.lineHeight !== undefined; 28199 const resetLineHeight = () => setLineHeight(undefined); 28200 28201 // Letter Spacing 28202 const hasLetterSpacingControl = useHasLetterSpacingControl(settings); 28203 const letterSpacing = decodeValue(inheritedValue?.typography?.letterSpacing); 28204 const setLetterSpacing = newValue => { 28205 onChange(setImmutably(value, ['typography', 'letterSpacing'], newValue || undefined)); 28206 }; 28207 const hasLetterSpacing = () => !!value?.typography?.letterSpacing; 28208 const resetLetterSpacing = () => setLetterSpacing(undefined); 28209 28210 // Text Columns 28211 const hasTextColumnsControl = useHasTextColumnsControl(settings); 28212 const textColumns = decodeValue(inheritedValue?.typography?.textColumns); 28213 const setTextColumns = newValue => { 28214 onChange(setImmutably(value, ['typography', 'textColumns'], newValue || undefined)); 28215 }; 28216 const hasTextColumns = () => !!value?.typography?.textColumns; 28217 const resetTextColumns = () => setTextColumns(undefined); 28218 28219 // Text Transform 28220 const hasTextTransformControl = useHasTextTransformControl(settings); 28221 const textTransform = decodeValue(inheritedValue?.typography?.textTransform); 28222 const setTextTransform = newValue => { 28223 onChange(setImmutably(value, ['typography', 'textTransform'], newValue || undefined)); 28224 }; 28225 const hasTextTransform = () => !!value?.typography?.textTransform; 28226 const resetTextTransform = () => setTextTransform(undefined); 28227 28228 // Text Decoration 28229 const hasTextDecorationControl = useHasTextDecorationControl(settings); 28230 const textDecoration = decodeValue(inheritedValue?.typography?.textDecoration); 28231 const setTextDecoration = newValue => { 28232 onChange(setImmutably(value, ['typography', 'textDecoration'], newValue || undefined)); 28233 }; 28234 const hasTextDecoration = () => !!value?.typography?.textDecoration; 28235 const resetTextDecoration = () => setTextDecoration(undefined); 28236 28237 // Text Orientation 28238 const hasWritingModeControl = useHasWritingModeControl(settings); 28239 const writingMode = decodeValue(inheritedValue?.typography?.writingMode); 28240 const setWritingMode = newValue => { 28241 onChange(setImmutably(value, ['typography', 'writingMode'], newValue || undefined)); 28242 }; 28243 const hasWritingMode = () => !!value?.typography?.writingMode; 28244 const resetWritingMode = () => setWritingMode(undefined); 28245 const resetAllFilter = (0,external_wp_element_namespaceObject.useCallback)(previousValue => { 28246 return { 28247 ...previousValue, 28248 typography: {} 28249 }; 28250 }, []); 28251 return (0,external_React_.createElement)(Wrapper, { 28252 resetAllFilter: resetAllFilter, 28253 value: value, 28254 onChange: onChange, 28255 panelId: panelId 28256 }, hasFontFamilyEnabled && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 28257 label: (0,external_wp_i18n_namespaceObject.__)('Font family'), 28258 hasValue: hasFontFamily, 28259 onDeselect: resetFontFamily, 28260 isShownByDefault: defaultControls.fontFamily, 28261 panelId: panelId 28262 }, (0,external_React_.createElement)(FontFamilyControl, { 28263 fontFamilies: mergedFontFamilies, 28264 value: fontFamily, 28265 onChange: setFontFamily, 28266 size: "__unstable-large", 28267 __nextHasNoMarginBottom: true 28268 })), hasFontSizeEnabled && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 28269 label: (0,external_wp_i18n_namespaceObject.__)('Font size'), 28270 hasValue: hasFontSize, 28271 onDeselect: resetFontSize, 28272 isShownByDefault: defaultControls.fontSize, 28273 panelId: panelId 28274 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.FontSizePicker, { 28275 value: fontSize, 28276 onChange: setFontSize, 28277 fontSizes: mergedFontSizes, 28278 disableCustomFontSizes: disableCustomFontSizes, 28279 withReset: false, 28280 withSlider: true, 28281 size: "__unstable-large" 28282 })), hasAppearanceControl && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 28283 className: "single-column", 28284 label: appearanceControlLabel, 28285 hasValue: hasFontAppearance, 28286 onDeselect: resetFontAppearance, 28287 isShownByDefault: defaultControls.fontAppearance, 28288 panelId: panelId 28289 }, (0,external_React_.createElement)(FontAppearanceControl, { 28290 value: { 28291 fontStyle, 28292 fontWeight 28293 }, 28294 onChange: setFontAppearance, 28295 hasFontStyles: hasFontStyles, 28296 hasFontWeights: hasFontWeights, 28297 size: "__unstable-large", 28298 __nextHasNoMarginBottom: true 28299 })), hasLineHeightEnabled && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 28300 className: "single-column", 28301 label: (0,external_wp_i18n_namespaceObject.__)('Line height'), 28302 hasValue: hasLineHeight, 28303 onDeselect: resetLineHeight, 28304 isShownByDefault: defaultControls.lineHeight, 28305 panelId: panelId 28306 }, (0,external_React_.createElement)(line_height_control, { 28307 __nextHasNoMarginBottom: true, 28308 __unstableInputWidth: "auto", 28309 value: lineHeight, 28310 onChange: setLineHeight, 28311 size: "__unstable-large" 28312 })), hasLetterSpacingControl && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 28313 className: "single-column", 28314 label: (0,external_wp_i18n_namespaceObject.__)('Letter spacing'), 28315 hasValue: hasLetterSpacing, 28316 onDeselect: resetLetterSpacing, 28317 isShownByDefault: defaultControls.letterSpacing, 28318 panelId: panelId 28319 }, (0,external_React_.createElement)(LetterSpacingControl, { 28320 value: letterSpacing, 28321 onChange: setLetterSpacing, 28322 size: "__unstable-large", 28323 __unstableInputWidth: "auto" 28324 })), hasTextColumnsControl && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 28325 className: "single-column", 28326 label: (0,external_wp_i18n_namespaceObject.__)('Text columns'), 28327 hasValue: hasTextColumns, 28328 onDeselect: resetTextColumns, 28329 isShownByDefault: defaultControls.textColumns, 28330 panelId: panelId 28331 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalNumberControl, { 28332 label: (0,external_wp_i18n_namespaceObject.__)('Text columns'), 28333 max: MAX_TEXT_COLUMNS, 28334 min: MIN_TEXT_COLUMNS, 28335 onChange: setTextColumns, 28336 size: "__unstable-large", 28337 spinControls: "custom", 28338 value: textColumns, 28339 initialPosition: 1 28340 })), hasTextDecorationControl && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 28341 className: "single-column", 28342 label: (0,external_wp_i18n_namespaceObject.__)('Text decoration'), 28343 hasValue: hasTextDecoration, 28344 onDeselect: resetTextDecoration, 28345 isShownByDefault: defaultControls.textDecoration, 28346 panelId: panelId 28347 }, (0,external_React_.createElement)(TextDecorationControl, { 28348 value: textDecoration, 28349 onChange: setTextDecoration, 28350 size: "__unstable-large", 28351 __unstableInputWidth: "auto" 28352 })), hasWritingModeControl && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 28353 className: "single-column", 28354 label: (0,external_wp_i18n_namespaceObject.__)('Text orientation'), 28355 hasValue: hasWritingMode, 28356 onDeselect: resetWritingMode, 28357 isShownByDefault: defaultControls.writingMode, 28358 panelId: panelId 28359 }, (0,external_React_.createElement)(WritingModeControl, { 28360 value: writingMode, 28361 onChange: setWritingMode, 28362 size: "__unstable-large", 28363 __nextHasNoMarginBottom: true 28364 })), hasTextTransformControl && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 28365 label: (0,external_wp_i18n_namespaceObject.__)('Letter case'), 28366 hasValue: hasTextTransform, 28367 onDeselect: resetTextTransform, 28368 isShownByDefault: defaultControls.textTransform, 28369 panelId: panelId 28370 }, (0,external_React_.createElement)(TextTransformControl, { 28371 value: textTransform, 28372 onChange: setTextTransform, 28373 showNone: true, 28374 isBlock: true, 28375 size: "__unstable-large", 28376 __nextHasNoMarginBottom: true 28377 }))); 28378 } 28379 28380 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/line-height.js 28381 28382 /** 28383 * WordPress dependencies 28384 */ 28385 28386 28387 /** 28388 * Internal dependencies 28389 */ 28390 28391 28392 28393 const LINE_HEIGHT_SUPPORT_KEY = 'typography.lineHeight'; 28394 28395 /** 28396 * Inspector control panel containing the line height related configuration 28397 * 28398 * @param {Object} props 28399 * 28400 * @return {Element} Line height edit element. 28401 */ 28402 function LineHeightEdit(props) { 28403 const { 28404 attributes: { 28405 style 28406 }, 28407 setAttributes 28408 } = props; 28409 const onChange = newLineHeightValue => { 28410 const newStyle = { 28411 ...style, 28412 typography: { 28413 ...style?.typography, 28414 lineHeight: newLineHeightValue 28415 } 28416 }; 28417 setAttributes({ 28418 style: cleanEmptyObject(newStyle) 28419 }); 28420 }; 28421 return createElement(LineHeightControl, { 28422 __unstableInputWidth: "100%", 28423 __nextHasNoMarginBottom: true, 28424 value: style?.typography?.lineHeight, 28425 onChange: onChange, 28426 size: "__unstable-large" 28427 }); 28428 } 28429 28430 /** 28431 * Custom hook that checks if line-height settings have been disabled. 28432 * 28433 * @param {string} name The name of the block. 28434 * @return {boolean} Whether setting is disabled. 28435 */ 28436 function useIsLineHeightDisabled({ 28437 name: blockName 28438 } = {}) { 28439 const [isEnabled] = useSettings('typography.lineHeight'); 28440 return !isEnabled || !hasBlockSupport(blockName, LINE_HEIGHT_SUPPORT_KEY); 28441 } 28442 28443 ;// CONCATENATED MODULE: external ["wp","tokenList"] 28444 const external_wp_tokenList_namespaceObject = window["wp"]["tokenList"]; 28445 var external_wp_tokenList_default = /*#__PURE__*/__webpack_require__.n(external_wp_tokenList_namespaceObject); 28446 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/font-family.js 28447 /** 28448 * WordPress dependencies 28449 */ 28450 28451 28452 28453 28454 28455 /** 28456 * Internal dependencies 28457 */ 28458 28459 28460 28461 const FONT_FAMILY_SUPPORT_KEY = 'typography.__experimentalFontFamily'; 28462 28463 /** 28464 * Filters registered block settings, extending attributes to include 28465 * the `fontFamily` attribute. 28466 * 28467 * @param {Object} settings Original block settings 28468 * @return {Object} Filtered block settings 28469 */ 28470 function font_family_addAttributes(settings) { 28471 if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(settings, FONT_FAMILY_SUPPORT_KEY)) { 28472 return settings; 28473 } 28474 28475 // Allow blocks to specify a default value if needed. 28476 if (!settings.attributes.fontFamily) { 28477 Object.assign(settings.attributes, { 28478 fontFamily: { 28479 type: 'string' 28480 } 28481 }); 28482 } 28483 return settings; 28484 } 28485 28486 /** 28487 * Override props assigned to save component to inject font family. 28488 * 28489 * @param {Object} props Additional props applied to save element 28490 * @param {Object} blockType Block type 28491 * @param {Object} attributes Block attributes 28492 * @return {Object} Filtered props applied to save element 28493 */ 28494 function font_family_addSaveProps(props, blockType, attributes) { 28495 if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, FONT_FAMILY_SUPPORT_KEY)) { 28496 return props; 28497 } 28498 if (shouldSkipSerialization(blockType, TYPOGRAPHY_SUPPORT_KEY, 'fontFamily')) { 28499 return props; 28500 } 28501 if (!attributes?.fontFamily) { 28502 return props; 28503 } 28504 28505 // Use TokenList to dedupe classes. 28506 const classes = new (external_wp_tokenList_default())(props.className); 28507 const { 28508 kebabCase 28509 } = unlock(external_wp_components_namespaceObject.privateApis); 28510 classes.add(`has-$kebabCase(attributes?.fontFamily)}-font-family`); 28511 const newClassName = classes.value; 28512 props.className = newClassName ? newClassName : undefined; 28513 return props; 28514 } 28515 function font_family_useBlockProps({ 28516 name, 28517 fontFamily 28518 }) { 28519 return font_family_addSaveProps({}, name, { 28520 fontFamily 28521 }); 28522 } 28523 /* harmony default export */ const font_family = ({ 28524 useBlockProps: font_family_useBlockProps, 28525 addSaveProps: font_family_addSaveProps, 28526 attributeKeys: ['fontFamily'], 28527 hasSupport(name) { 28528 return (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, FONT_FAMILY_SUPPORT_KEY); 28529 } 28530 }); 28531 28532 /** 28533 * Resets the font family block support attribute. This can be used when 28534 * disabling the font family support controls for a block via a progressive 28535 * discovery panel. 28536 * 28537 * @param {Object} props Block props. 28538 * @param {Object} props.setAttributes Function to set block's attributes. 28539 */ 28540 function resetFontFamily({ 28541 setAttributes 28542 }) { 28543 setAttributes({ 28544 fontFamily: undefined 28545 }); 28546 } 28547 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/fontFamily/addAttribute', font_family_addAttributes); 28548 28549 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/font-sizes/utils.js 28550 /** 28551 * WordPress dependencies 28552 */ 28553 28554 28555 /** 28556 * Internal dependencies 28557 */ 28558 28559 28560 /** 28561 * Returns the font size object based on an array of named font sizes and the namedFontSize and customFontSize values. 28562 * If namedFontSize is undefined or not found in fontSizes an object with just the size value based on customFontSize is returned. 28563 * 28564 * @param {Array} fontSizes Array of font size objects containing at least the "name" and "size" values as properties. 28565 * @param {?string} fontSizeAttribute Content of the font size attribute (slug). 28566 * @param {?number} customFontSizeAttribute Contents of the custom font size attribute (value). 28567 * 28568 * @return {?Object} If fontSizeAttribute is set and an equal slug is found in fontSizes it returns the font size object for that slug. 28569 * Otherwise, an object with just the size value based on customFontSize is returned. 28570 */ 28571 const utils_getFontSize = (fontSizes, fontSizeAttribute, customFontSizeAttribute) => { 28572 if (fontSizeAttribute) { 28573 const fontSizeObject = fontSizes?.find(({ 28574 slug 28575 }) => slug === fontSizeAttribute); 28576 if (fontSizeObject) { 28577 return fontSizeObject; 28578 } 28579 } 28580 return { 28581 size: customFontSizeAttribute 28582 }; 28583 }; 28584 28585 /** 28586 * Returns the corresponding font size object for a given value. 28587 * 28588 * @param {Array} fontSizes Array of font size objects. 28589 * @param {number} value Font size value. 28590 * 28591 * @return {Object} Font size object. 28592 */ 28593 function utils_getFontSizeObjectByValue(fontSizes, value) { 28594 const fontSizeObject = fontSizes?.find(({ 28595 size 28596 }) => size === value); 28597 if (fontSizeObject) { 28598 return fontSizeObject; 28599 } 28600 return { 28601 size: value 28602 }; 28603 } 28604 28605 /** 28606 * Returns a class based on fontSizeName. 28607 * 28608 * @param {string} fontSizeSlug Slug of the fontSize. 28609 * 28610 * @return {string | undefined} String with the class corresponding to the fontSize passed. 28611 * The class is generated by appending 'has-' followed by fontSizeSlug in kebabCase and ending with '-font-size'. 28612 */ 28613 function getFontSizeClass(fontSizeSlug) { 28614 if (!fontSizeSlug) { 28615 return; 28616 } 28617 const { 28618 kebabCase 28619 } = unlock(external_wp_components_namespaceObject.privateApis); 28620 return `has-$kebabCase(fontSizeSlug)}-font-size`; 28621 } 28622 28623 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/font-size.js 28624 28625 /** 28626 * WordPress dependencies 28627 */ 28628 28629 28630 28631 28632 /** 28633 * Internal dependencies 28634 */ 28635 28636 28637 28638 28639 28640 const FONT_SIZE_SUPPORT_KEY = 'typography.fontSize'; 28641 28642 /** 28643 * Filters registered block settings, extending attributes to include 28644 * `fontSize` and `fontWeight` attributes. 28645 * 28646 * @param {Object} settings Original block settings. 28647 * 28648 * @return {Object} Filtered block settings. 28649 */ 28650 function font_size_addAttributes(settings) { 28651 if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(settings, FONT_SIZE_SUPPORT_KEY)) { 28652 return settings; 28653 } 28654 28655 // Allow blocks to specify a default value if needed. 28656 if (!settings.attributes.fontSize) { 28657 Object.assign(settings.attributes, { 28658 fontSize: { 28659 type: 'string' 28660 } 28661 }); 28662 } 28663 return settings; 28664 } 28665 28666 /** 28667 * Override props assigned to save component to inject font size. 28668 * 28669 * @param {Object} props Additional props applied to save element. 28670 * @param {Object} blockNameOrType Block type. 28671 * @param {Object} attributes Block attributes. 28672 * 28673 * @return {Object} Filtered props applied to save element. 28674 */ 28675 function font_size_addSaveProps(props, blockNameOrType, attributes) { 28676 if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockNameOrType, FONT_SIZE_SUPPORT_KEY)) { 28677 return props; 28678 } 28679 if (shouldSkipSerialization(blockNameOrType, TYPOGRAPHY_SUPPORT_KEY, 'fontSize')) { 28680 return props; 28681 } 28682 28683 // Use TokenList to dedupe classes. 28684 const classes = new (external_wp_tokenList_default())(props.className); 28685 classes.add(getFontSizeClass(attributes.fontSize)); 28686 const newClassName = classes.value; 28687 props.className = newClassName ? newClassName : undefined; 28688 return props; 28689 } 28690 28691 /** 28692 * Inspector control panel containing the font size related configuration 28693 * 28694 * @param {Object} props 28695 * 28696 * @return {Element} Font size edit element. 28697 */ 28698 function FontSizeEdit(props) { 28699 const { 28700 attributes: { 28701 fontSize, 28702 style 28703 }, 28704 setAttributes 28705 } = props; 28706 const [fontSizes] = useSettings('typography.fontSizes'); 28707 const onChange = value => { 28708 const fontSizeSlug = getFontSizeObjectByValue(fontSizes, value).slug; 28709 setAttributes({ 28710 style: cleanEmptyObject({ 28711 ...style, 28712 typography: { 28713 ...style?.typography, 28714 fontSize: fontSizeSlug ? undefined : value 28715 } 28716 }), 28717 fontSize: fontSizeSlug 28718 }); 28719 }; 28720 const fontSizeObject = getFontSize(fontSizes, fontSize, style?.typography?.fontSize); 28721 const fontSizeValue = fontSizeObject?.size || style?.typography?.fontSize || fontSize; 28722 return createElement(FontSizePicker, { 28723 onChange: onChange, 28724 value: fontSizeValue, 28725 withReset: false, 28726 withSlider: true, 28727 size: "__unstable-large" 28728 }); 28729 } 28730 28731 /** 28732 * Custom hook that checks if font-size settings have been disabled. 28733 * 28734 * @param {string} name The name of the block. 28735 * @return {boolean} Whether setting is disabled. 28736 */ 28737 function useIsFontSizeDisabled({ 28738 name: blockName 28739 } = {}) { 28740 const [fontSizes] = useSettings('typography.fontSizes'); 28741 const hasFontSizes = !!fontSizes?.length; 28742 return !hasBlockSupport(blockName, FONT_SIZE_SUPPORT_KEY) || !hasFontSizes; 28743 } 28744 function font_size_useBlockProps({ 28745 name, 28746 fontSize, 28747 style 28748 }) { 28749 const [fontSizes, fluidTypographySettings, layoutSettings] = use_settings_useSettings('typography.fontSizes', 'typography.fluid', 'layout'); 28750 28751 /* 28752 * Only add inline styles if the block supports font sizes, 28753 * doesn't skip serialization of font sizes, 28754 * and has either a custom font size or a preset font size. 28755 */ 28756 if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, FONT_SIZE_SUPPORT_KEY) || shouldSkipSerialization(name, TYPOGRAPHY_SUPPORT_KEY, 'fontSize') || !fontSize && !style?.typography?.fontSize) { 28757 return; 28758 } 28759 let props; 28760 if (style?.typography?.fontSize) { 28761 const fluidSettings = getFluidTypographyOptionsFromSettings({ 28762 typography: { 28763 fluid: fluidTypographySettings 28764 }, 28765 layout: layoutSettings 28766 }); 28767 props = { 28768 style: { 28769 fontSize: getTypographyFontSizeValue({ 28770 size: style.typography.fontSize 28771 }, fluidSettings) 28772 } 28773 }; 28774 } 28775 if (fontSize) { 28776 props = { 28777 style: { 28778 fontSize: utils_getFontSize(fontSizes, fontSize, style?.typography?.fontSize).size 28779 } 28780 }; 28781 } 28782 if (!props) { 28783 return; 28784 } 28785 return font_size_addSaveProps(props, name, { 28786 fontSize 28787 }); 28788 } 28789 /* harmony default export */ const font_size = ({ 28790 useBlockProps: font_size_useBlockProps, 28791 addSaveProps: font_size_addSaveProps, 28792 attributeKeys: ['fontSize', 'style'], 28793 hasSupport(name) { 28794 return (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, FONT_SIZE_SUPPORT_KEY); 28795 } 28796 }); 28797 const font_size_MIGRATION_PATHS = { 28798 fontSize: [['fontSize'], ['style', 'typography', 'fontSize']] 28799 }; 28800 function font_size_addTransforms(result, source, index, results) { 28801 const destinationBlockType = result.name; 28802 const activeSupports = { 28803 fontSize: (0,external_wp_blocks_namespaceObject.hasBlockSupport)(destinationBlockType, FONT_SIZE_SUPPORT_KEY) 28804 }; 28805 return transformStyles(activeSupports, font_size_MIGRATION_PATHS, result, source, index, results); 28806 } 28807 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/font/addAttribute', font_size_addAttributes); 28808 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.switchToBlockType.transformedBlock', 'core/font-size/addTransforms', font_size_addTransforms); 28809 28810 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/typography.js 28811 28812 /** 28813 * WordPress dependencies 28814 */ 28815 28816 28817 28818 28819 /** 28820 * Internal dependencies 28821 */ 28822 28823 28824 28825 28826 28827 28828 28829 function omit(object, keys) { 28830 return Object.fromEntries(Object.entries(object).filter(([key]) => !keys.includes(key))); 28831 } 28832 const LETTER_SPACING_SUPPORT_KEY = 'typography.__experimentalLetterSpacing'; 28833 const TEXT_TRANSFORM_SUPPORT_KEY = 'typography.__experimentalTextTransform'; 28834 const TEXT_DECORATION_SUPPORT_KEY = 'typography.__experimentalTextDecoration'; 28835 const TEXT_COLUMNS_SUPPORT_KEY = 'typography.textColumns'; 28836 const FONT_STYLE_SUPPORT_KEY = 'typography.__experimentalFontStyle'; 28837 const FONT_WEIGHT_SUPPORT_KEY = 'typography.__experimentalFontWeight'; 28838 const WRITING_MODE_SUPPORT_KEY = 'typography.__experimentalWritingMode'; 28839 const TYPOGRAPHY_SUPPORT_KEY = 'typography'; 28840 const TYPOGRAPHY_SUPPORT_KEYS = [LINE_HEIGHT_SUPPORT_KEY, FONT_SIZE_SUPPORT_KEY, FONT_STYLE_SUPPORT_KEY, FONT_WEIGHT_SUPPORT_KEY, FONT_FAMILY_SUPPORT_KEY, TEXT_COLUMNS_SUPPORT_KEY, TEXT_DECORATION_SUPPORT_KEY, WRITING_MODE_SUPPORT_KEY, TEXT_TRANSFORM_SUPPORT_KEY, LETTER_SPACING_SUPPORT_KEY]; 28841 function typography_styleToAttributes(style) { 28842 const updatedStyle = { 28843 ...omit(style, ['fontFamily']) 28844 }; 28845 const fontSizeValue = style?.typography?.fontSize; 28846 const fontFamilyValue = style?.typography?.fontFamily; 28847 const fontSizeSlug = fontSizeValue?.startsWith('var:preset|font-size|') ? fontSizeValue.substring('var:preset|font-size|'.length) : undefined; 28848 const fontFamilySlug = fontFamilyValue?.startsWith('var:preset|font-family|') ? fontFamilyValue.substring('var:preset|font-family|'.length) : undefined; 28849 updatedStyle.typography = { 28850 ...omit(updatedStyle.typography, ['fontFamily']), 28851 fontSize: fontSizeSlug ? undefined : fontSizeValue 28852 }; 28853 return { 28854 style: utils_cleanEmptyObject(updatedStyle), 28855 fontFamily: fontFamilySlug, 28856 fontSize: fontSizeSlug 28857 }; 28858 } 28859 function typography_attributesToStyle(attributes) { 28860 return { 28861 ...attributes.style, 28862 typography: { 28863 ...attributes.style?.typography, 28864 fontFamily: attributes.fontFamily ? 'var:preset|font-family|' + attributes.fontFamily : undefined, 28865 fontSize: attributes.fontSize ? 'var:preset|font-size|' + attributes.fontSize : attributes.style?.typography?.fontSize 28866 } 28867 }; 28868 } 28869 function TypographyInspectorControl({ 28870 children, 28871 resetAllFilter 28872 }) { 28873 const attributesResetAllFilter = (0,external_wp_element_namespaceObject.useCallback)(attributes => { 28874 const existingStyle = typography_attributesToStyle(attributes); 28875 const updatedStyle = resetAllFilter(existingStyle); 28876 return { 28877 ...attributes, 28878 ...typography_styleToAttributes(updatedStyle) 28879 }; 28880 }, [resetAllFilter]); 28881 return (0,external_React_.createElement)(inspector_controls, { 28882 group: "typography", 28883 resetAllFilter: attributesResetAllFilter 28884 }, children); 28885 } 28886 function typography_TypographyPanel({ 28887 clientId, 28888 name, 28889 setAttributes, 28890 settings 28891 }) { 28892 function selector(select) { 28893 const { 28894 style, 28895 fontFamily, 28896 fontSize 28897 } = select(store).getBlockAttributes(clientId) || {}; 28898 return { 28899 style, 28900 fontFamily, 28901 fontSize 28902 }; 28903 } 28904 const { 28905 style, 28906 fontFamily, 28907 fontSize 28908 } = (0,external_wp_data_namespaceObject.useSelect)(selector, [clientId]); 28909 const isEnabled = useHasTypographyPanel(settings); 28910 const value = (0,external_wp_element_namespaceObject.useMemo)(() => typography_attributesToStyle({ 28911 style, 28912 fontFamily, 28913 fontSize 28914 }), [style, fontSize, fontFamily]); 28915 const onChange = newStyle => { 28916 setAttributes(typography_styleToAttributes(newStyle)); 28917 }; 28918 if (!isEnabled) { 28919 return null; 28920 } 28921 const defaultControls = (0,external_wp_blocks_namespaceObject.getBlockSupport)(name, [TYPOGRAPHY_SUPPORT_KEY, '__experimentalDefaultControls']); 28922 return (0,external_React_.createElement)(TypographyPanel, { 28923 as: TypographyInspectorControl, 28924 panelId: clientId, 28925 settings: settings, 28926 value: value, 28927 onChange: onChange, 28928 defaultControls: defaultControls 28929 }); 28930 } 28931 const hasTypographySupport = blockName => { 28932 return TYPOGRAPHY_SUPPORT_KEYS.some(key => hasBlockSupport(blockName, key)); 28933 }; 28934 28935 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/settings.js 28936 28937 /** 28938 * WordPress dependencies 28939 */ 28940 28941 const settings_settings = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 28942 xmlns: "http://www.w3.org/2000/svg", 28943 viewBox: "0 0 24 24" 28944 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 28945 d: "m19 7.5h-7.628c-.3089-.87389-1.1423-1.5-2.122-1.5-.97966 0-1.81309.62611-2.12197 1.5h-2.12803v1.5h2.12803c.30888.87389 1.14231 1.5 2.12197 1.5.9797 0 1.8131-.62611 2.122-1.5h7.628z" 28946 }), (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 28947 d: "m19 15h-2.128c-.3089-.8739-1.1423-1.5-2.122-1.5s-1.8131.6261-2.122 1.5h-7.628v1.5h7.628c.3089.8739 1.1423 1.5 2.122 1.5s1.8131-.6261 2.122-1.5h2.128z" 28948 })); 28949 /* harmony default export */ const library_settings = (settings_settings); 28950 28951 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/spacing-sizes-control/input-controls/spacing-input-control.js 28952 28953 /** 28954 * WordPress dependencies 28955 */ 28956 28957 28958 28959 28960 28961 28962 28963 /** 28964 * Internal dependencies 28965 */ 28966 28967 28968 28969 const CUSTOM_VALUE_SETTINGS = { 28970 px: { 28971 max: 300, 28972 steps: 1 28973 }, 28974 '%': { 28975 max: 100, 28976 steps: 1 28977 }, 28978 vw: { 28979 max: 100, 28980 steps: 1 28981 }, 28982 vh: { 28983 max: 100, 28984 steps: 1 28985 }, 28986 em: { 28987 max: 10, 28988 steps: 0.1 28989 }, 28990 rm: { 28991 max: 10, 28992 steps: 0.1 28993 }, 28994 svw: { 28995 max: 100, 28996 steps: 1 28997 }, 28998 lvw: { 28999 max: 100, 29000 steps: 1 29001 }, 29002 dvw: { 29003 max: 100, 29004 steps: 1 29005 }, 29006 svh: { 29007 max: 100, 29008 steps: 1 29009 }, 29010 lvh: { 29011 max: 100, 29012 steps: 1 29013 }, 29014 dvh: { 29015 max: 100, 29016 steps: 1 29017 }, 29018 vi: { 29019 max: 100, 29020 steps: 1 29021 }, 29022 svi: { 29023 max: 100, 29024 steps: 1 29025 }, 29026 lvi: { 29027 max: 100, 29028 steps: 1 29029 }, 29030 dvi: { 29031 max: 100, 29032 steps: 1 29033 }, 29034 vb: { 29035 max: 100, 29036 steps: 1 29037 }, 29038 svb: { 29039 max: 100, 29040 steps: 1 29041 }, 29042 lvb: { 29043 max: 100, 29044 steps: 1 29045 }, 29046 dvb: { 29047 max: 100, 29048 steps: 1 29049 }, 29050 vmin: { 29051 max: 100, 29052 steps: 1 29053 }, 29054 svmin: { 29055 max: 100, 29056 steps: 1 29057 }, 29058 lvmin: { 29059 max: 100, 29060 steps: 1 29061 }, 29062 dvmin: { 29063 max: 100, 29064 steps: 1 29065 }, 29066 vmax: { 29067 max: 100, 29068 steps: 1 29069 }, 29070 svmax: { 29071 max: 100, 29072 steps: 1 29073 }, 29074 lvmax: { 29075 max: 100, 29076 steps: 1 29077 }, 29078 dvmax: { 29079 max: 100, 29080 steps: 1 29081 } 29082 }; 29083 function SpacingInputControl({ 29084 icon, 29085 isMixed = false, 29086 minimumCustomValue, 29087 onChange, 29088 onMouseOut, 29089 onMouseOver, 29090 showSideInLabel = true, 29091 side, 29092 spacingSizes, 29093 type, 29094 value 29095 }) { 29096 var _CUSTOM_VALUE_SETTING, _CUSTOM_VALUE_SETTING2; 29097 // Treat value as a preset value if the passed in value matches the value of one of the spacingSizes. 29098 value = getPresetValueFromCustomValue(value, spacingSizes); 29099 let selectListSizes = spacingSizes; 29100 const showRangeControl = spacingSizes.length <= 8; 29101 const disableCustomSpacingSizes = (0,external_wp_data_namespaceObject.useSelect)(select => { 29102 const editorSettings = select(store).getSettings(); 29103 return editorSettings?.disableCustomSpacingSizes; 29104 }); 29105 const [showCustomValueControl, setShowCustomValueControl] = (0,external_wp_element_namespaceObject.useState)(!disableCustomSpacingSizes && value !== undefined && !isValueSpacingPreset(value)); 29106 const previousValue = (0,external_wp_compose_namespaceObject.usePrevious)(value); 29107 if (!!value && previousValue !== value && !isValueSpacingPreset(value) && showCustomValueControl !== true) { 29108 setShowCustomValueControl(true); 29109 } 29110 const [availableUnits] = use_settings_useSettings('spacing.units'); 29111 const units = (0,external_wp_components_namespaceObject.__experimentalUseCustomUnits)({ 29112 availableUnits: availableUnits || ['px', 'em', 'rem'] 29113 }); 29114 let currentValue = null; 29115 const showCustomValueInSelectList = !showRangeControl && !showCustomValueControl && value !== undefined && (!isValueSpacingPreset(value) || isValueSpacingPreset(value) && isMixed); 29116 if (showCustomValueInSelectList) { 29117 selectListSizes = [...spacingSizes, { 29118 name: !isMixed ? 29119 // translators: A custom measurement, eg. a number followed by a unit like 12px. 29120 (0,external_wp_i18n_namespaceObject.sprintf)((0,external_wp_i18n_namespaceObject.__)('Custom (%s)'), value) : (0,external_wp_i18n_namespaceObject.__)('Mixed'), 29121 slug: 'custom', 29122 size: value 29123 }]; 29124 currentValue = selectListSizes.length - 1; 29125 } else if (!isMixed) { 29126 currentValue = !showCustomValueControl ? getSliderValueFromPreset(value, spacingSizes) : getCustomValueFromPreset(value, spacingSizes); 29127 } 29128 const selectedUnit = (0,external_wp_element_namespaceObject.useMemo)(() => (0,external_wp_components_namespaceObject.__experimentalParseQuantityAndUnitFromRawValue)(currentValue), [currentValue])[1] || units[0]?.value; 29129 const setInitialValue = () => { 29130 if (value === undefined) { 29131 onChange('0'); 29132 } 29133 }; 29134 const customTooltipContent = newValue => value === undefined ? undefined : spacingSizes[newValue]?.name; 29135 const customRangeValue = parseFloat(currentValue, 10); 29136 const getNewCustomValue = newSize => { 29137 const isNumeric = !isNaN(parseFloat(newSize)); 29138 const nextValue = isNumeric ? newSize : undefined; 29139 return nextValue; 29140 }; 29141 const getNewPresetValue = (newSize, controlType) => { 29142 const size = parseInt(newSize, 10); 29143 if (controlType === 'selectList') { 29144 if (size === 0) { 29145 return undefined; 29146 } 29147 if (size === 1) { 29148 return '0'; 29149 } 29150 } else if (size === 0) { 29151 return '0'; 29152 } 29153 return `var:preset|spacing|$spacingSizes[newSize]?.slug}`; 29154 }; 29155 const handleCustomValueSliderChange = next => { 29156 onChange([next, selectedUnit].join('')); 29157 }; 29158 const allPlaceholder = isMixed ? (0,external_wp_i18n_namespaceObject.__)('Mixed') : null; 29159 const options = selectListSizes.map((size, index) => ({ 29160 key: index, 29161 name: size.name 29162 })); 29163 const marks = spacingSizes.map((_newValue, index) => ({ 29164 value: index, 29165 label: undefined 29166 })); 29167 const sideLabel = ALL_SIDES.includes(side) && showSideInLabel ? LABELS[side] : ''; 29168 const typeLabel = showSideInLabel ? type?.toLowerCase() : type; 29169 const ariaLabel = (0,external_wp_i18n_namespaceObject.sprintf)( 29170 // translators: 1: The side of the block being modified (top, bottom, left, All sides etc.). 2. Type of spacing being modified (Padding, margin, etc) 29171 (0,external_wp_i18n_namespaceObject.__)('%1$s %2$s'), sideLabel, typeLabel).trim(); 29172 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, { 29173 className: "spacing-sizes-control__wrapper" 29174 }, icon && (0,external_React_.createElement)(external_wp_components_namespaceObject.Icon, { 29175 className: "spacing-sizes-control__icon", 29176 icon: icon, 29177 size: 24 29178 }), showCustomValueControl && (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalUnitControl, { 29179 onMouseOver: onMouseOver, 29180 onMouseOut: onMouseOut, 29181 onFocus: onMouseOver, 29182 onBlur: onMouseOut, 29183 onChange: newSize => onChange(getNewCustomValue(newSize)), 29184 value: currentValue, 29185 units: units, 29186 min: minimumCustomValue, 29187 placeholder: allPlaceholder, 29188 disableUnits: isMixed, 29189 label: ariaLabel, 29190 hideLabelFromVision: true, 29191 className: "spacing-sizes-control__custom-value-input", 29192 size: '__unstable-large' 29193 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.RangeControl, { 29194 onMouseOver: onMouseOver, 29195 onMouseOut: onMouseOut, 29196 onFocus: onMouseOver, 29197 onBlur: onMouseOut, 29198 value: customRangeValue, 29199 min: 0, 29200 max: (_CUSTOM_VALUE_SETTING = CUSTOM_VALUE_SETTINGS[selectedUnit]?.max) !== null && _CUSTOM_VALUE_SETTING !== void 0 ? _CUSTOM_VALUE_SETTING : 10, 29201 step: (_CUSTOM_VALUE_SETTING2 = CUSTOM_VALUE_SETTINGS[selectedUnit]?.steps) !== null && _CUSTOM_VALUE_SETTING2 !== void 0 ? _CUSTOM_VALUE_SETTING2 : 0.1, 29202 withInputField: false, 29203 onChange: handleCustomValueSliderChange, 29204 className: "spacing-sizes-control__custom-value-range", 29205 __nextHasNoMarginBottom: true 29206 })), showRangeControl && !showCustomValueControl && (0,external_React_.createElement)(external_wp_components_namespaceObject.RangeControl, { 29207 onMouseOver: onMouseOver, 29208 onMouseOut: onMouseOut, 29209 className: "spacing-sizes-control__range-control", 29210 value: currentValue, 29211 onChange: newSize => onChange(getNewPresetValue(newSize)), 29212 onMouseDown: event => { 29213 // If mouse down is near start of range set initial value to 0, which 29214 // prevents the user have to drag right then left to get 0 setting. 29215 if (event?.nativeEvent?.offsetX < 35) { 29216 setInitialValue(); 29217 } 29218 }, 29219 withInputField: false, 29220 "aria-valuenow": currentValue, 29221 "aria-valuetext": spacingSizes[currentValue]?.name, 29222 renderTooltipContent: customTooltipContent, 29223 min: 0, 29224 max: spacingSizes.length - 1, 29225 marks: marks, 29226 label: ariaLabel, 29227 hideLabelFromVision: true, 29228 __nextHasNoMarginBottom: true, 29229 onFocus: onMouseOver, 29230 onBlur: onMouseOut 29231 }), !showRangeControl && !showCustomValueControl && (0,external_React_.createElement)(external_wp_components_namespaceObject.CustomSelectControl, { 29232 className: "spacing-sizes-control__custom-select-control", 29233 value: options.find(option => option.key === currentValue) || '' // passing undefined here causes a downshift controlled/uncontrolled warning 29234 , 29235 onChange: selection => { 29236 onChange(getNewPresetValue(selection.selectedItem.key, 'selectList')); 29237 }, 29238 options: options, 29239 label: ariaLabel, 29240 hideLabelFromVision: true, 29241 __nextUnconstrainedWidth: true, 29242 size: '__unstable-large', 29243 onMouseOver: onMouseOver, 29244 onMouseOut: onMouseOut, 29245 onFocus: onMouseOver, 29246 onBlur: onMouseOut 29247 }), !disableCustomSpacingSizes && (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 29248 label: showCustomValueControl ? (0,external_wp_i18n_namespaceObject.__)('Use size preset') : (0,external_wp_i18n_namespaceObject.__)('Set custom size'), 29249 icon: library_settings, 29250 onClick: () => { 29251 setShowCustomValueControl(!showCustomValueControl); 29252 }, 29253 isPressed: showCustomValueControl, 29254 size: "small", 29255 className: "spacing-sizes-control__custom-toggle", 29256 iconSize: 24 29257 })); 29258 } 29259 29260 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/spacing-sizes-control/input-controls/axial.js 29261 29262 /** 29263 * Internal dependencies 29264 */ 29265 29266 29267 const groupedSides = ['vertical', 'horizontal']; 29268 function AxialInputControls({ 29269 minimumCustomValue, 29270 onChange, 29271 onMouseOut, 29272 onMouseOver, 29273 sides, 29274 spacingSizes, 29275 type, 29276 values 29277 }) { 29278 const createHandleOnChange = side => next => { 29279 if (!onChange) { 29280 return; 29281 } 29282 29283 // Encode the existing value into the preset value if the passed in value matches the value of one of the spacingSizes. 29284 const nextValues = { 29285 ...Object.keys(values).reduce((acc, key) => { 29286 acc[key] = getPresetValueFromCustomValue(values[key], spacingSizes); 29287 return acc; 29288 }, {}) 29289 }; 29290 if (side === 'vertical') { 29291 nextValues.top = next; 29292 nextValues.bottom = next; 29293 } 29294 if (side === 'horizontal') { 29295 nextValues.left = next; 29296 nextValues.right = next; 29297 } 29298 onChange(nextValues); 29299 }; 29300 29301 // Filter sides if custom configuration provided, maintaining default order. 29302 const filteredSides = sides?.length ? groupedSides.filter(side => hasAxisSupport(sides, side)) : groupedSides; 29303 return (0,external_React_.createElement)(external_React_.Fragment, null, filteredSides.map(side => { 29304 const axisValue = side === 'vertical' ? values.top : values.left; 29305 return (0,external_React_.createElement)(SpacingInputControl, { 29306 key: `spacing-sizes-control-$side}`, 29307 icon: ICONS[side], 29308 label: LABELS[side], 29309 minimumCustomValue: minimumCustomValue, 29310 onChange: createHandleOnChange(side), 29311 onMouseOut: onMouseOut, 29312 onMouseOver: onMouseOver, 29313 side: side, 29314 spacingSizes: spacingSizes, 29315 type: type, 29316 value: axisValue, 29317 withInputField: false 29318 }); 29319 })); 29320 } 29321 29322 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/spacing-sizes-control/input-controls/separated.js 29323 29324 /** 29325 * Internal dependencies 29326 */ 29327 29328 29329 function SeparatedInputControls({ 29330 minimumCustomValue, 29331 onChange, 29332 onMouseOut, 29333 onMouseOver, 29334 sides, 29335 spacingSizes, 29336 type, 29337 values 29338 }) { 29339 // Filter sides if custom configuration provided, maintaining default order. 29340 const filteredSides = sides?.length ? ALL_SIDES.filter(side => sides.includes(side)) : ALL_SIDES; 29341 const createHandleOnChange = side => next => { 29342 // Encode the existing value into the preset value if the passed in value matches the value of one of the spacingSizes. 29343 const nextValues = { 29344 ...Object.keys(values).reduce((acc, key) => { 29345 acc[key] = getPresetValueFromCustomValue(values[key], spacingSizes); 29346 return acc; 29347 }, {}) 29348 }; 29349 nextValues[side] = next; 29350 onChange(nextValues); 29351 }; 29352 return (0,external_React_.createElement)(external_React_.Fragment, null, filteredSides.map(side => { 29353 return (0,external_React_.createElement)(SpacingInputControl, { 29354 key: `spacing-sizes-control-$side}`, 29355 icon: ICONS[side], 29356 label: LABELS[side], 29357 minimumCustomValue: minimumCustomValue, 29358 onChange: createHandleOnChange(side), 29359 onMouseOut: onMouseOut, 29360 onMouseOver: onMouseOver, 29361 side: side, 29362 spacingSizes: spacingSizes, 29363 type: type, 29364 value: values[side], 29365 withInputField: false 29366 }); 29367 })); 29368 } 29369 29370 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/spacing-sizes-control/input-controls/single.js 29371 29372 /** 29373 * Internal dependencies 29374 */ 29375 29376 29377 function SingleInputControl({ 29378 minimumCustomValue, 29379 onChange, 29380 onMouseOut, 29381 onMouseOver, 29382 showSideInLabel, 29383 side, 29384 spacingSizes, 29385 type, 29386 values 29387 }) { 29388 const createHandleOnChange = currentSide => next => { 29389 // Encode the existing value into the preset value if the passed in value matches the value of one of the spacingSizes. 29390 const nextValues = { 29391 ...Object.keys(values).reduce((acc, key) => { 29392 acc[key] = getPresetValueFromCustomValue(values[key], spacingSizes); 29393 return acc; 29394 }, {}) 29395 }; 29396 nextValues[currentSide] = next; 29397 onChange(nextValues); 29398 }; 29399 return (0,external_React_.createElement)(SpacingInputControl, { 29400 label: LABELS[side], 29401 minimumCustomValue: minimumCustomValue, 29402 onChange: createHandleOnChange(side), 29403 onMouseOut: onMouseOut, 29404 onMouseOver: onMouseOver, 29405 showSideInLabel: showSideInLabel, 29406 side: side, 29407 spacingSizes: spacingSizes, 29408 type: type, 29409 value: values[side], 29410 withInputField: false 29411 }); 29412 } 29413 29414 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/spacing-sizes-control/sides-dropdown/index.js 29415 29416 /** 29417 * WordPress dependencies 29418 */ 29419 29420 29421 29422 /** 29423 * Internal dependencies 29424 */ 29425 29426 const checkIcon = (0,external_React_.createElement)(external_wp_components_namespaceObject.Icon, { 29427 icon: library_check, 29428 size: 24 29429 }); 29430 function SidesDropdown({ 29431 label: labelProp, 29432 onChange, 29433 sides, 29434 value 29435 }) { 29436 if (!sides || !sides.length) { 29437 return; 29438 } 29439 const supportedItems = getSupportedMenuItems(sides); 29440 const sideIcon = supportedItems[value].icon; 29441 const { 29442 custom: customItem, 29443 ...menuItems 29444 } = supportedItems; 29445 return (0,external_React_.createElement)(external_wp_components_namespaceObject.DropdownMenu, { 29446 icon: sideIcon, 29447 label: labelProp, 29448 className: "spacing-sizes-control__dropdown", 29449 toggleProps: { 29450 isSmall: true 29451 } 29452 }, ({ 29453 onClose 29454 }) => { 29455 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuGroup, null, Object.entries(menuItems).map(([slug, { 29456 label, 29457 icon 29458 }]) => { 29459 const isSelected = value === slug; 29460 return (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 29461 key: slug, 29462 icon: icon, 29463 iconPosition: "left", 29464 isSelected: isSelected, 29465 role: "menuitemradio", 29466 onClick: () => { 29467 onChange(slug); 29468 onClose(); 29469 }, 29470 suffix: isSelected ? checkIcon : undefined 29471 }, label); 29472 })), !!customItem && (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuGroup, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 29473 icon: customItem.icon, 29474 iconPosition: "left", 29475 isSelected: value === VIEWS.custom, 29476 role: "menuitemradio", 29477 onClick: () => { 29478 onChange(VIEWS.custom); 29479 onClose(); 29480 }, 29481 suffix: value === VIEWS.custom ? checkIcon : undefined 29482 }, customItem.label))); 29483 }); 29484 } 29485 29486 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/spacing-sizes-control/hooks/use-spacing-sizes.js 29487 /** 29488 * WordPress dependencies 29489 */ 29490 29491 29492 /** 29493 * Internal dependencies 29494 */ 29495 29496 function useSpacingSizes() { 29497 const spacingSizes = [{ 29498 name: 0, 29499 slug: '0', 29500 size: 0 29501 }]; 29502 const [settingsSizes] = use_settings_useSettings('spacing.spacingSizes'); 29503 if (settingsSizes) { 29504 spacingSizes.push(...settingsSizes); 29505 } 29506 if (spacingSizes.length > 8) { 29507 spacingSizes.unshift({ 29508 name: (0,external_wp_i18n_namespaceObject.__)('Default'), 29509 slug: 'default', 29510 size: undefined 29511 }); 29512 } 29513 return spacingSizes; 29514 } 29515 29516 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/spacing-sizes-control/index.js 29517 29518 /** 29519 * WordPress dependencies 29520 */ 29521 29522 29523 29524 29525 /** 29526 * Internal dependencies 29527 */ 29528 29529 29530 29531 29532 29533 29534 function SpacingSizesControl({ 29535 inputProps, 29536 label: labelProp, 29537 minimumCustomValue = 0, 29538 onChange, 29539 onMouseOut, 29540 onMouseOver, 29541 showSideInLabel = true, 29542 sides = ALL_SIDES, 29543 useSelect, 29544 values 29545 }) { 29546 const spacingSizes = useSpacingSizes(); 29547 const inputValues = values || DEFAULT_VALUES; 29548 const hasOneSide = sides?.length === 1; 29549 const hasOnlyAxialSides = sides?.includes('horizontal') && sides?.includes('vertical') && sides?.length === 2; 29550 const [view, setView] = (0,external_wp_element_namespaceObject.useState)(getInitialView(inputValues, sides)); 29551 const handleOnChange = nextValue => { 29552 const newValues = { 29553 ...values, 29554 ...nextValue 29555 }; 29556 onChange(newValues); 29557 }; 29558 const inputControlProps = { 29559 ...inputProps, 29560 minimumCustomValue, 29561 onChange: handleOnChange, 29562 onMouseOut, 29563 onMouseOver, 29564 sides, 29565 spacingSizes, 29566 type: labelProp, 29567 useSelect, 29568 values: inputValues 29569 }; 29570 const renderControls = () => { 29571 if (view === VIEWS.axial) { 29572 return (0,external_React_.createElement)(AxialInputControls, { 29573 ...inputControlProps 29574 }); 29575 } 29576 if (view === VIEWS.custom) { 29577 return (0,external_React_.createElement)(SeparatedInputControls, { 29578 ...inputControlProps 29579 }); 29580 } 29581 return (0,external_React_.createElement)(SingleInputControl, { 29582 side: view, 29583 ...inputControlProps, 29584 showSideInLabel: showSideInLabel 29585 }); 29586 }; 29587 const sideLabel = ALL_SIDES.includes(view) && showSideInLabel ? LABELS[view] : ''; 29588 const label = (0,external_wp_i18n_namespaceObject.sprintf)( 29589 // translators: 2. Type of spacing being modified (Padding, margin, etc). 1: The side of the block being modified (top, bottom, left etc.). 29590 (0,external_wp_i18n_namespaceObject.__)('%1$s %2$s'), labelProp, sideLabel).trim(); 29591 const dropdownLabelText = (0,external_wp_i18n_namespaceObject.sprintf)( 29592 // translators: %s: The current spacing property e.g. "Padding", "Margin". 29593 (0,external_wp_i18n_namespaceObject._x)('%s options', 'Button label to reveal side configuration options'), labelProp); 29594 return (0,external_React_.createElement)("fieldset", { 29595 className: "spacing-sizes-control" 29596 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, { 29597 className: "spacing-sizes-control__header" 29598 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.BaseControl.VisualLabel, { 29599 as: "legend", 29600 className: "spacing-sizes-control__label" 29601 }, label), !hasOneSide && !hasOnlyAxialSides && (0,external_React_.createElement)(SidesDropdown, { 29602 label: dropdownLabelText, 29603 onChange: setView, 29604 sides: sides, 29605 value: view 29606 })), (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalVStack, { 29607 spacing: 0.5 29608 }, renderControls())); 29609 } 29610 29611 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/height-control/index.js 29612 29613 /** 29614 * WordPress dependencies 29615 */ 29616 29617 29618 29619 29620 /** 29621 * Internal dependencies 29622 */ 29623 29624 const RANGE_CONTROL_CUSTOM_SETTINGS = { 29625 px: { 29626 max: 1000, 29627 step: 1 29628 }, 29629 '%': { 29630 max: 100, 29631 step: 1 29632 }, 29633 vw: { 29634 max: 100, 29635 step: 1 29636 }, 29637 vh: { 29638 max: 100, 29639 step: 1 29640 }, 29641 em: { 29642 max: 50, 29643 step: 0.1 29644 }, 29645 rem: { 29646 max: 50, 29647 step: 0.1 29648 }, 29649 svw: { 29650 max: 100, 29651 step: 1 29652 }, 29653 lvw: { 29654 max: 100, 29655 step: 1 29656 }, 29657 dvw: { 29658 max: 100, 29659 step: 1 29660 }, 29661 svh: { 29662 max: 100, 29663 step: 1 29664 }, 29665 lvh: { 29666 max: 100, 29667 step: 1 29668 }, 29669 dvh: { 29670 max: 100, 29671 step: 1 29672 }, 29673 vi: { 29674 max: 100, 29675 step: 1 29676 }, 29677 svi: { 29678 max: 100, 29679 step: 1 29680 }, 29681 lvi: { 29682 max: 100, 29683 step: 1 29684 }, 29685 dvi: { 29686 max: 100, 29687 step: 1 29688 }, 29689 vb: { 29690 max: 100, 29691 step: 1 29692 }, 29693 svb: { 29694 max: 100, 29695 step: 1 29696 }, 29697 lvb: { 29698 max: 100, 29699 step: 1 29700 }, 29701 dvb: { 29702 max: 100, 29703 step: 1 29704 }, 29705 vmin: { 29706 max: 100, 29707 step: 1 29708 }, 29709 svmin: { 29710 max: 100, 29711 step: 1 29712 }, 29713 lvmin: { 29714 max: 100, 29715 step: 1 29716 }, 29717 dvmin: { 29718 max: 100, 29719 step: 1 29720 }, 29721 vmax: { 29722 max: 100, 29723 step: 1 29724 }, 29725 svmax: { 29726 max: 100, 29727 step: 1 29728 }, 29729 lvmax: { 29730 max: 100, 29731 step: 1 29732 }, 29733 dvmax: { 29734 max: 100, 29735 step: 1 29736 } 29737 }; 29738 29739 /** 29740 * HeightControl renders a linked unit control and range control for adjusting the height of a block. 29741 * 29742 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/height-control/README.md 29743 * 29744 * @param {Object} props 29745 * @param {?string} props.label A label for the control. 29746 * @param {( value: string ) => void } props.onChange Called when the height changes. 29747 * @param {string} props.value The current height value. 29748 * 29749 * @return {Component} The component to be rendered. 29750 */ 29751 function HeightControl({ 29752 label = (0,external_wp_i18n_namespaceObject.__)('Height'), 29753 onChange, 29754 value 29755 }) { 29756 var _RANGE_CONTROL_CUSTOM, _RANGE_CONTROL_CUSTOM2; 29757 const customRangeValue = parseFloat(value); 29758 const [availableUnits] = use_settings_useSettings('spacing.units'); 29759 const units = (0,external_wp_components_namespaceObject.__experimentalUseCustomUnits)({ 29760 availableUnits: availableUnits || ['%', 'px', 'em', 'rem', 'vh', 'vw'] 29761 }); 29762 const selectedUnit = (0,external_wp_element_namespaceObject.useMemo)(() => (0,external_wp_components_namespaceObject.__experimentalParseQuantityAndUnitFromRawValue)(value), [value])[1] || units[0]?.value || 'px'; 29763 const handleSliderChange = next => { 29764 onChange([next, selectedUnit].join('')); 29765 }; 29766 const handleUnitChange = newUnit => { 29767 // Attempt to smooth over differences between currentUnit and newUnit. 29768 // This should slightly improve the experience of switching between unit types. 29769 const [currentValue, currentUnit] = (0,external_wp_components_namespaceObject.__experimentalParseQuantityAndUnitFromRawValue)(value); 29770 if (['em', 'rem'].includes(newUnit) && currentUnit === 'px') { 29771 // Convert pixel value to an approximate of the new unit, assuming a root size of 16px. 29772 onChange((currentValue / 16).toFixed(2) + newUnit); 29773 } else if (['em', 'rem'].includes(currentUnit) && newUnit === 'px') { 29774 // Convert to pixel value assuming a root size of 16px. 29775 onChange(Math.round(currentValue * 16) + newUnit); 29776 } else if (['%', 'vw', 'svw', 'lvw', 'dvw', 'vh', 'svh', 'lvh', 'dvh', 'vi', 'svi', 'lvi', 'dvi', 'vb', 'svb', 'lvb', 'dvb', 'vmin', 'svmin', 'lvmin', 'dvmin', 'vmax', 'svmax', 'lvmax', 'dvmax'].includes(newUnit) && currentValue > 100) { 29777 // When converting to `%` or viewport-relative units, cap the new value at 100. 29778 onChange(100 + newUnit); 29779 } 29780 }; 29781 return (0,external_React_.createElement)("fieldset", { 29782 className: "block-editor-height-control" 29783 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.BaseControl.VisualLabel, { 29784 as: "legend" 29785 }, label), (0,external_React_.createElement)(external_wp_components_namespaceObject.Flex, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexItem, { 29786 isBlock: true 29787 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalUnitControl, { 29788 value: value, 29789 units: units, 29790 onChange: onChange, 29791 onUnitChange: handleUnitChange, 29792 min: 0, 29793 size: '__unstable-large', 29794 label: label, 29795 hideLabelFromVision: true 29796 })), (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexItem, { 29797 isBlock: true 29798 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalSpacer, { 29799 marginX: 2, 29800 marginBottom: 0 29801 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.RangeControl, { 29802 value: customRangeValue, 29803 min: 0, 29804 max: (_RANGE_CONTROL_CUSTOM = RANGE_CONTROL_CUSTOM_SETTINGS[selectedUnit]?.max) !== null && _RANGE_CONTROL_CUSTOM !== void 0 ? _RANGE_CONTROL_CUSTOM : 100, 29805 step: (_RANGE_CONTROL_CUSTOM2 = RANGE_CONTROL_CUSTOM_SETTINGS[selectedUnit]?.step) !== null && _RANGE_CONTROL_CUSTOM2 !== void 0 ? _RANGE_CONTROL_CUSTOM2 : 0.1, 29806 withInputField: false, 29807 onChange: handleSliderChange, 29808 __nextHasNoMarginBottom: true, 29809 label: label, 29810 hideLabelFromVision: true 29811 }))))); 29812 } 29813 29814 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/child-layout-control/index.js 29815 29816 /** 29817 * WordPress dependencies 29818 */ 29819 29820 29821 29822 function helpText(selfStretch, parentLayout) { 29823 const { 29824 orientation = 'horizontal' 29825 } = parentLayout; 29826 if (selfStretch === 'fill') { 29827 return (0,external_wp_i18n_namespaceObject.__)('Stretch to fill available space.'); 29828 } 29829 if (selfStretch === 'fixed' && orientation === 'horizontal') { 29830 return (0,external_wp_i18n_namespaceObject.__)('Specify a fixed width.'); 29831 } else if (selfStretch === 'fixed') { 29832 return (0,external_wp_i18n_namespaceObject.__)('Specify a fixed height.'); 29833 } 29834 return (0,external_wp_i18n_namespaceObject.__)('Fit contents.'); 29835 } 29836 29837 /** 29838 * Form to edit the child layout value. 29839 * 29840 * @param {Object} props Props. 29841 * @param {Object} props.value The child layout value. 29842 * @param {Function} props.onChange Function to update the child layout value. 29843 * @param {Object} props.parentLayout The parent layout value. 29844 * 29845 * @return {Element} child layout edit element. 29846 */ 29847 function ChildLayoutControl({ 29848 value: childLayout = {}, 29849 onChange, 29850 parentLayout 29851 }) { 29852 const { 29853 selfStretch, 29854 flexSize 29855 } = childLayout; 29856 (0,external_wp_element_namespaceObject.useEffect)(() => { 29857 if (selfStretch === 'fixed' && !flexSize) { 29858 onChange({ 29859 ...childLayout, 29860 selfStretch: 'fit' 29861 }); 29862 } 29863 }, []); 29864 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToggleGroupControl, { 29865 __nextHasNoMarginBottom: true, 29866 size: '__unstable-large', 29867 label: childLayoutOrientation(parentLayout), 29868 value: selfStretch || 'fit', 29869 help: helpText(selfStretch, parentLayout), 29870 onChange: value => { 29871 const newFlexSize = value !== 'fixed' ? null : flexSize; 29872 onChange({ 29873 ...childLayout, 29874 selfStretch: value, 29875 flexSize: newFlexSize 29876 }); 29877 }, 29878 isBlock: true 29879 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOption, { 29880 key: 'fit', 29881 value: 'fit', 29882 label: (0,external_wp_i18n_namespaceObject.__)('Fit') 29883 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOption, { 29884 key: 'fill', 29885 value: 'fill', 29886 label: (0,external_wp_i18n_namespaceObject.__)('Fill') 29887 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOption, { 29888 key: 'fixed', 29889 value: 'fixed', 29890 label: (0,external_wp_i18n_namespaceObject.__)('Fixed') 29891 })), selfStretch === 'fixed' && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalUnitControl, { 29892 size: '__unstable-large', 29893 onChange: value => { 29894 onChange({ 29895 ...childLayout, 29896 flexSize: value 29897 }); 29898 }, 29899 value: flexSize 29900 })); 29901 } 29902 function childLayoutOrientation(parentLayout) { 29903 const { 29904 orientation = 'horizontal' 29905 } = parentLayout; 29906 return orientation === 'horizontal' ? (0,external_wp_i18n_namespaceObject.__)('Width') : (0,external_wp_i18n_namespaceObject.__)('Height'); 29907 } 29908 29909 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/dimensions-tool/aspect-ratio-tool.js 29910 29911 /** 29912 * WordPress dependencies 29913 */ 29914 29915 29916 29917 /** 29918 * @typedef {import('@wordpress/components/build-types/select-control/types').SelectControlProps} SelectControlProps 29919 */ 29920 29921 /** 29922 * @type {SelectControlProps[]} 29923 */ 29924 const DEFAULT_ASPECT_RATIO_OPTIONS = [{ 29925 label: (0,external_wp_i18n_namespaceObject._x)('Original', 'Aspect ratio option for dimensions control'), 29926 value: 'auto' 29927 }, { 29928 label: (0,external_wp_i18n_namespaceObject._x)('Square - 1:1', 'Aspect ratio option for dimensions control'), 29929 value: '1' 29930 }, { 29931 label: (0,external_wp_i18n_namespaceObject._x)('Standard - 4:3', 'Aspect ratio option for dimensions control'), 29932 value: '4/3' 29933 }, { 29934 label: (0,external_wp_i18n_namespaceObject._x)('Portrait - 3:4', 'Aspect ratio option for dimensions control'), 29935 value: '3/4' 29936 }, { 29937 label: (0,external_wp_i18n_namespaceObject._x)('Classic - 3:2', 'Aspect ratio option for dimensions control'), 29938 value: '3/2' 29939 }, { 29940 label: (0,external_wp_i18n_namespaceObject._x)('Classic Portrait - 2:3', 'Aspect ratio option for dimensions control'), 29941 value: '2/3' 29942 }, { 29943 label: (0,external_wp_i18n_namespaceObject._x)('Wide - 16:9', 'Aspect ratio option for dimensions control'), 29944 value: '16/9' 29945 }, { 29946 label: (0,external_wp_i18n_namespaceObject._x)('Tall - 9:16', 'Aspect ratio option for dimensions control'), 29947 value: '9/16' 29948 }, { 29949 label: (0,external_wp_i18n_namespaceObject._x)('Custom', 'Aspect ratio option for dimensions control'), 29950 value: 'custom', 29951 disabled: true, 29952 hidden: true 29953 }]; 29954 29955 /** 29956 * @callback AspectRatioToolPropsOnChange 29957 * @param {string} [value] New aspect ratio value. 29958 * @return {void} No return. 29959 */ 29960 29961 /** 29962 * @typedef {Object} AspectRatioToolProps 29963 * @property {string} [panelId] ID of the panel this tool is associated with. 29964 * @property {string} [value] Current aspect ratio value. 29965 * @property {AspectRatioToolPropsOnChange} [onChange] Callback to update the aspect ratio value. 29966 * @property {SelectControlProps[]} [options] Aspect ratio options. 29967 * @property {string} [defaultValue] Default aspect ratio value. 29968 * @property {boolean} [isShownByDefault] Whether the tool is shown by default. 29969 */ 29970 29971 function AspectRatioTool({ 29972 panelId, 29973 value, 29974 onChange = () => {}, 29975 options = DEFAULT_ASPECT_RATIO_OPTIONS, 29976 defaultValue = DEFAULT_ASPECT_RATIO_OPTIONS[0].value, 29977 hasValue, 29978 isShownByDefault = true 29979 }) { 29980 // Match the CSS default so if the value is used directly in CSS it will look correct in the control. 29981 const displayValue = value !== null && value !== void 0 ? value : 'auto'; 29982 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 29983 hasValue: hasValue ? hasValue : () => displayValue !== defaultValue, 29984 label: (0,external_wp_i18n_namespaceObject.__)('Aspect ratio'), 29985 onDeselect: () => onChange(undefined), 29986 isShownByDefault: isShownByDefault, 29987 panelId: panelId 29988 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.SelectControl, { 29989 label: (0,external_wp_i18n_namespaceObject.__)('Aspect ratio'), 29990 value: displayValue, 29991 options: options, 29992 onChange: onChange, 29993 size: '__unstable-large', 29994 __nextHasNoMarginBottom: true 29995 })); 29996 } 29997 29998 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/global-styles/dimensions-panel.js 29999 30000 /** 30001 * External dependencies 30002 */ 30003 30004 30005 /** 30006 * WordPress dependencies 30007 */ 30008 30009 30010 30011 30012 30013 /** 30014 * Internal dependencies 30015 */ 30016 30017 30018 30019 30020 30021 30022 30023 const AXIAL_SIDES = ['horizontal', 'vertical']; 30024 function useHasDimensionsPanel(settings) { 30025 const hasContentSize = useHasContentSize(settings); 30026 const hasWideSize = useHasWideSize(settings); 30027 const hasPadding = useHasPadding(settings); 30028 const hasMargin = useHasMargin(settings); 30029 const hasGap = useHasGap(settings); 30030 const hasMinHeight = useHasMinHeight(settings); 30031 const hasAspectRatio = useHasAspectRatio(settings); 30032 const hasChildLayout = useHasChildLayout(settings); 30033 return external_wp_element_namespaceObject.Platform.OS === 'web' && (hasContentSize || hasWideSize || hasPadding || hasMargin || hasGap || hasMinHeight || hasAspectRatio || hasChildLayout); 30034 } 30035 function useHasContentSize(settings) { 30036 return settings?.layout?.contentSize; 30037 } 30038 function useHasWideSize(settings) { 30039 return settings?.layout?.wideSize; 30040 } 30041 function useHasPadding(settings) { 30042 return settings?.spacing?.padding; 30043 } 30044 function useHasMargin(settings) { 30045 return settings?.spacing?.margin; 30046 } 30047 function useHasGap(settings) { 30048 return settings?.spacing?.blockGap; 30049 } 30050 function useHasMinHeight(settings) { 30051 return settings?.dimensions?.minHeight; 30052 } 30053 function useHasAspectRatio(settings) { 30054 return settings?.dimensions?.aspectRatio; 30055 } 30056 function useHasChildLayout(settings) { 30057 var _settings$parentLayou; 30058 const { 30059 type: parentLayoutType = 'default', 30060 default: { 30061 type: defaultParentLayoutType = 'default' 30062 } = {}, 30063 allowSizingOnChildren = false 30064 } = (_settings$parentLayou = settings?.parentLayout) !== null && _settings$parentLayou !== void 0 ? _settings$parentLayou : {}; 30065 const support = (defaultParentLayoutType === 'flex' || parentLayoutType === 'flex') && allowSizingOnChildren; 30066 return !!settings?.layout && support; 30067 } 30068 function useHasSpacingPresets(settings) { 30069 var _ref, _ref2; 30070 const { 30071 custom, 30072 theme, 30073 default: defaultPresets 30074 } = settings?.spacing?.spacingSizes || {}; 30075 const presets = (_ref = (_ref2 = custom !== null && custom !== void 0 ? custom : theme) !== null && _ref2 !== void 0 ? _ref2 : defaultPresets) !== null && _ref !== void 0 ? _ref : []; 30076 return presets.length > 0; 30077 } 30078 function filterValuesBySides(values, sides) { 30079 // If no custom side configuration, all sides are opted into by default. 30080 // Without any values, we have nothing to filter either. 30081 if (!sides || !values) { 30082 return values; 30083 } 30084 30085 // Only include sides opted into within filtered values. 30086 const filteredValues = {}; 30087 sides.forEach(side => { 30088 if (side === 'vertical') { 30089 filteredValues.top = values.top; 30090 filteredValues.bottom = values.bottom; 30091 } 30092 if (side === 'horizontal') { 30093 filteredValues.left = values.left; 30094 filteredValues.right = values.right; 30095 } 30096 filteredValues[side] = values?.[side]; 30097 }); 30098 return filteredValues; 30099 } 30100 function splitStyleValue(value) { 30101 // Check for shorthand value (a string value). 30102 if (value && typeof value === 'string') { 30103 // Convert to value for individual sides for BoxControl. 30104 return { 30105 top: value, 30106 right: value, 30107 bottom: value, 30108 left: value 30109 }; 30110 } 30111 return value; 30112 } 30113 function splitGapValue(value) { 30114 // Check for shorthand value (a string value). 30115 if (value && typeof value === 'string') { 30116 // If the value is a string, treat it as a single side (top) for the spacing controls. 30117 return { 30118 top: value 30119 }; 30120 } 30121 if (value) { 30122 return { 30123 ...value, 30124 right: value?.left, 30125 bottom: value?.top 30126 }; 30127 } 30128 return value; 30129 } 30130 function DimensionsToolsPanel({ 30131 resetAllFilter, 30132 onChange, 30133 value, 30134 panelId, 30135 children 30136 }) { 30137 const resetAll = () => { 30138 const updatedValue = resetAllFilter(value); 30139 onChange(updatedValue); 30140 }; 30141 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanel, { 30142 label: (0,external_wp_i18n_namespaceObject.__)('Dimensions'), 30143 resetAll: resetAll, 30144 panelId: panelId, 30145 dropdownMenuProps: TOOLSPANEL_DROPDOWNMENU_PROPS 30146 }, children); 30147 } 30148 const dimensions_panel_DEFAULT_CONTROLS = { 30149 contentSize: true, 30150 wideSize: true, 30151 padding: true, 30152 margin: true, 30153 blockGap: true, 30154 minHeight: true, 30155 aspectRatio: true, 30156 childLayout: true 30157 }; 30158 function DimensionsPanel({ 30159 as: Wrapper = DimensionsToolsPanel, 30160 value, 30161 onChange, 30162 inheritedValue = value, 30163 settings, 30164 panelId, 30165 defaultControls = dimensions_panel_DEFAULT_CONTROLS, 30166 onVisualize = () => {}, 30167 // Special case because the layout controls are not part of the dimensions panel 30168 // in global styles but not in block inspector. 30169 includeLayoutControls = false 30170 }) { 30171 var _settings$parentLayou2, _defaultControls$cont, _defaultControls$wide, _defaultControls$padd, _defaultControls$marg, _defaultControls$bloc, _defaultControls$minH, _defaultControls$aspe, _defaultControls$chil; 30172 const { 30173 dimensions, 30174 spacing 30175 } = settings; 30176 const decodeValue = rawValue => { 30177 if (rawValue && typeof rawValue === 'object') { 30178 return Object.keys(rawValue).reduce((acc, key) => { 30179 acc[key] = getValueFromVariable({ 30180 settings: { 30181 dimensions, 30182 spacing 30183 } 30184 }, '', rawValue[key]); 30185 return acc; 30186 }, {}); 30187 } 30188 return getValueFromVariable({ 30189 settings: { 30190 dimensions, 30191 spacing 30192 } 30193 }, '', rawValue); 30194 }; 30195 const showSpacingPresetsControl = useHasSpacingPresets(settings); 30196 const units = (0,external_wp_components_namespaceObject.__experimentalUseCustomUnits)({ 30197 availableUnits: settings?.spacing?.units || ['%', 'px', 'em', 'rem', 'vw'] 30198 }); 30199 30200 // Content Size 30201 const showContentSizeControl = useHasContentSize(settings) && includeLayoutControls; 30202 const contentSizeValue = decodeValue(inheritedValue?.layout?.contentSize); 30203 const setContentSizeValue = newValue => { 30204 onChange(setImmutably(value, ['layout', 'contentSize'], newValue || undefined)); 30205 }; 30206 const hasUserSetContentSizeValue = () => !!value?.layout?.contentSize; 30207 const resetContentSizeValue = () => setContentSizeValue(undefined); 30208 30209 // Wide Size 30210 const showWideSizeControl = useHasWideSize(settings) && includeLayoutControls; 30211 const wideSizeValue = decodeValue(inheritedValue?.layout?.wideSize); 30212 const setWideSizeValue = newValue => { 30213 onChange(setImmutably(value, ['layout', 'wideSize'], newValue || undefined)); 30214 }; 30215 const hasUserSetWideSizeValue = () => !!value?.layout?.wideSize; 30216 const resetWideSizeValue = () => setWideSizeValue(undefined); 30217 30218 // Padding 30219 const showPaddingControl = useHasPadding(settings); 30220 const rawPadding = decodeValue(inheritedValue?.spacing?.padding); 30221 const paddingValues = splitStyleValue(rawPadding); 30222 const paddingSides = Array.isArray(settings?.spacing?.padding) ? settings?.spacing?.padding : settings?.spacing?.padding?.sides; 30223 const isAxialPadding = paddingSides && paddingSides.some(side => AXIAL_SIDES.includes(side)); 30224 const setPaddingValues = newPaddingValues => { 30225 const padding = filterValuesBySides(newPaddingValues, paddingSides); 30226 onChange(setImmutably(value, ['spacing', 'padding'], padding)); 30227 }; 30228 const hasPaddingValue = () => !!value?.spacing?.padding && Object.keys(value?.spacing?.padding).length; 30229 const resetPaddingValue = () => setPaddingValues(undefined); 30230 const onMouseOverPadding = () => onVisualize('padding'); 30231 30232 // Margin 30233 const showMarginControl = useHasMargin(settings); 30234 const rawMargin = decodeValue(inheritedValue?.spacing?.margin); 30235 const marginValues = splitStyleValue(rawMargin); 30236 const marginSides = Array.isArray(settings?.spacing?.margin) ? settings?.spacing?.margin : settings?.spacing?.margin?.sides; 30237 const isAxialMargin = marginSides && marginSides.some(side => AXIAL_SIDES.includes(side)); 30238 const setMarginValues = newMarginValues => { 30239 const margin = filterValuesBySides(newMarginValues, marginSides); 30240 onChange(setImmutably(value, ['spacing', 'margin'], margin)); 30241 }; 30242 const hasMarginValue = () => !!value?.spacing?.margin && Object.keys(value?.spacing?.margin).length; 30243 const resetMarginValue = () => setMarginValues(undefined); 30244 const onMouseOverMargin = () => onVisualize('margin'); 30245 30246 // Block Gap 30247 const showGapControl = useHasGap(settings); 30248 const gapValue = decodeValue(inheritedValue?.spacing?.blockGap); 30249 const gapValues = splitGapValue(gapValue); 30250 const gapSides = Array.isArray(settings?.spacing?.blockGap) ? settings?.spacing?.blockGap : settings?.spacing?.blockGap?.sides; 30251 const isAxialGap = gapSides && gapSides.some(side => AXIAL_SIDES.includes(side)); 30252 const setGapValue = newGapValue => { 30253 onChange(setImmutably(value, ['spacing', 'blockGap'], newGapValue)); 30254 }; 30255 const setGapValues = nextBoxGapValue => { 30256 if (!nextBoxGapValue) { 30257 setGapValue(null); 30258 } 30259 // If axial gap is not enabled, treat the 'top' value as the shorthand gap value. 30260 if (!isAxialGap && nextBoxGapValue?.hasOwnProperty('top')) { 30261 setGapValue(nextBoxGapValue.top); 30262 } else { 30263 setGapValue({ 30264 top: nextBoxGapValue?.top, 30265 left: nextBoxGapValue?.left 30266 }); 30267 } 30268 }; 30269 const resetGapValue = () => setGapValue(undefined); 30270 const hasGapValue = () => !!value?.spacing?.blockGap; 30271 30272 // Min Height 30273 const showMinHeightControl = useHasMinHeight(settings); 30274 const minHeightValue = decodeValue(inheritedValue?.dimensions?.minHeight); 30275 const setMinHeightValue = newValue => { 30276 const tempValue = setImmutably(value, ['dimensions', 'minHeight'], newValue); 30277 // Apply min-height, while removing any applied aspect ratio. 30278 onChange(setImmutably(tempValue, ['dimensions', 'aspectRatio'], undefined)); 30279 }; 30280 const resetMinHeightValue = () => { 30281 setMinHeightValue(undefined); 30282 }; 30283 const hasMinHeightValue = () => !!value?.dimensions?.minHeight; 30284 30285 // Aspect Ratio 30286 const showAspectRatioControl = useHasAspectRatio(settings); 30287 const aspectRatioValue = decodeValue(inheritedValue?.dimensions?.aspectRatio); 30288 const setAspectRatioValue = newValue => { 30289 const tempValue = setImmutably(value, ['dimensions', 'aspectRatio'], newValue); 30290 // Apply aspect-ratio, while removing any applied min-height. 30291 onChange(setImmutably(tempValue, ['dimensions', 'minHeight'], undefined)); 30292 }; 30293 const hasAspectRatioValue = () => !!value?.dimensions?.aspectRatio; 30294 30295 // Child Layout 30296 const showChildLayoutControl = useHasChildLayout(settings); 30297 const childLayout = inheritedValue?.layout; 30298 const { 30299 orientation = 'horizontal' 30300 } = (_settings$parentLayou2 = settings?.parentLayout) !== null && _settings$parentLayou2 !== void 0 ? _settings$parentLayou2 : {}; 30301 const childLayoutOrientationLabel = orientation === 'horizontal' ? (0,external_wp_i18n_namespaceObject.__)('Width') : (0,external_wp_i18n_namespaceObject.__)('Height'); 30302 const setChildLayout = newChildLayout => { 30303 onChange({ 30304 ...value, 30305 layout: { 30306 ...value?.layout, 30307 ...newChildLayout 30308 } 30309 }); 30310 }; 30311 const resetChildLayoutValue = () => { 30312 setChildLayout({ 30313 selfStretch: undefined, 30314 flexSize: undefined 30315 }); 30316 }; 30317 const hasChildLayoutValue = () => !!value?.layout; 30318 const resetAllFilter = (0,external_wp_element_namespaceObject.useCallback)(previousValue => { 30319 return { 30320 ...previousValue, 30321 layout: utils_cleanEmptyObject({ 30322 ...previousValue?.layout, 30323 contentSize: undefined, 30324 wideSize: undefined, 30325 selfStretch: undefined, 30326 flexSize: undefined 30327 }), 30328 spacing: { 30329 ...previousValue?.spacing, 30330 padding: undefined, 30331 margin: undefined, 30332 blockGap: undefined 30333 }, 30334 dimensions: { 30335 ...previousValue?.dimensions, 30336 minHeight: undefined, 30337 aspectRatio: undefined 30338 } 30339 }; 30340 }, []); 30341 const onMouseLeaveControls = () => onVisualize(false); 30342 return (0,external_React_.createElement)(Wrapper, { 30343 resetAllFilter: resetAllFilter, 30344 value: value, 30345 onChange: onChange, 30346 panelId: panelId 30347 }, (showContentSizeControl || showWideSizeControl) && (0,external_React_.createElement)("span", { 30348 className: "span-columns" 30349 }, (0,external_wp_i18n_namespaceObject.__)('Set the width of the main content area.')), showContentSizeControl && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 30350 className: "single-column", 30351 label: (0,external_wp_i18n_namespaceObject.__)('Content size'), 30352 hasValue: hasUserSetContentSizeValue, 30353 onDeselect: resetContentSizeValue, 30354 isShownByDefault: (_defaultControls$cont = defaultControls.contentSize) !== null && _defaultControls$cont !== void 0 ? _defaultControls$cont : dimensions_panel_DEFAULT_CONTROLS.contentSize, 30355 panelId: panelId 30356 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, { 30357 alignment: "flex-end", 30358 justify: "flex-start" 30359 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalUnitControl, { 30360 label: (0,external_wp_i18n_namespaceObject.__)('Content'), 30361 labelPosition: "top", 30362 __unstableInputWidth: "80px", 30363 value: contentSizeValue || '', 30364 onChange: nextContentSize => { 30365 setContentSizeValue(nextContentSize); 30366 }, 30367 units: units 30368 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalView, null, (0,external_React_.createElement)(build_module_icon, { 30369 icon: position_center 30370 })))), showWideSizeControl && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 30371 className: "single-column", 30372 label: (0,external_wp_i18n_namespaceObject.__)('Wide size'), 30373 hasValue: hasUserSetWideSizeValue, 30374 onDeselect: resetWideSizeValue, 30375 isShownByDefault: (_defaultControls$wide = defaultControls.wideSize) !== null && _defaultControls$wide !== void 0 ? _defaultControls$wide : dimensions_panel_DEFAULT_CONTROLS.wideSize, 30376 panelId: panelId 30377 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, { 30378 alignment: "flex-end", 30379 justify: "flex-start" 30380 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalUnitControl, { 30381 label: (0,external_wp_i18n_namespaceObject.__)('Wide'), 30382 labelPosition: "top", 30383 __unstableInputWidth: "80px", 30384 value: wideSizeValue || '', 30385 onChange: nextWideSize => { 30386 setWideSizeValue(nextWideSize); 30387 }, 30388 units: units 30389 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalView, null, (0,external_React_.createElement)(build_module_icon, { 30390 icon: stretch_wide 30391 })))), showPaddingControl && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 30392 hasValue: hasPaddingValue, 30393 label: (0,external_wp_i18n_namespaceObject.__)('Padding'), 30394 onDeselect: resetPaddingValue, 30395 isShownByDefault: (_defaultControls$padd = defaultControls.padding) !== null && _defaultControls$padd !== void 0 ? _defaultControls$padd : dimensions_panel_DEFAULT_CONTROLS.padding, 30396 className: classnames_default()({ 30397 'tools-panel-item-spacing': showSpacingPresetsControl 30398 }), 30399 panelId: panelId 30400 }, !showSpacingPresetsControl && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalBoxControl, { 30401 values: paddingValues, 30402 onChange: setPaddingValues, 30403 label: (0,external_wp_i18n_namespaceObject.__)('Padding'), 30404 sides: paddingSides, 30405 units: units, 30406 allowReset: false, 30407 splitOnAxis: isAxialPadding, 30408 onMouseOver: onMouseOverPadding, 30409 onMouseOut: onMouseLeaveControls 30410 }), showSpacingPresetsControl && (0,external_React_.createElement)(SpacingSizesControl, { 30411 values: paddingValues, 30412 onChange: setPaddingValues, 30413 label: (0,external_wp_i18n_namespaceObject.__)('Padding'), 30414 sides: paddingSides, 30415 units: units, 30416 allowReset: false, 30417 onMouseOver: onMouseOverPadding, 30418 onMouseOut: onMouseLeaveControls 30419 })), showMarginControl && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 30420 hasValue: hasMarginValue, 30421 label: (0,external_wp_i18n_namespaceObject.__)('Margin'), 30422 onDeselect: resetMarginValue, 30423 isShownByDefault: (_defaultControls$marg = defaultControls.margin) !== null && _defaultControls$marg !== void 0 ? _defaultControls$marg : dimensions_panel_DEFAULT_CONTROLS.margin, 30424 className: classnames_default()({ 30425 'tools-panel-item-spacing': showSpacingPresetsControl 30426 }), 30427 panelId: panelId 30428 }, !showSpacingPresetsControl && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalBoxControl, { 30429 values: marginValues, 30430 onChange: setMarginValues, 30431 label: (0,external_wp_i18n_namespaceObject.__)('Margin'), 30432 sides: marginSides, 30433 units: units, 30434 allowReset: false, 30435 splitOnAxis: isAxialMargin, 30436 onMouseOver: onMouseOverMargin, 30437 onMouseOut: onMouseLeaveControls 30438 }), showSpacingPresetsControl && (0,external_React_.createElement)(SpacingSizesControl, { 30439 values: marginValues, 30440 onChange: setMarginValues, 30441 label: (0,external_wp_i18n_namespaceObject.__)('Margin'), 30442 sides: marginSides, 30443 units: units, 30444 allowReset: false, 30445 onMouseOver: onMouseOverMargin, 30446 onMouseOut: onMouseLeaveControls 30447 })), showGapControl && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 30448 hasValue: hasGapValue, 30449 label: (0,external_wp_i18n_namespaceObject.__)('Block spacing'), 30450 onDeselect: resetGapValue, 30451 isShownByDefault: (_defaultControls$bloc = defaultControls.blockGap) !== null && _defaultControls$bloc !== void 0 ? _defaultControls$bloc : dimensions_panel_DEFAULT_CONTROLS.blockGap, 30452 className: classnames_default()({ 30453 'tools-panel-item-spacing': showSpacingPresetsControl 30454 }), 30455 panelId: panelId 30456 }, !showSpacingPresetsControl && (isAxialGap ? (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalBoxControl, { 30457 label: (0,external_wp_i18n_namespaceObject.__)('Block spacing'), 30458 min: 0, 30459 onChange: setGapValues, 30460 units: units, 30461 sides: gapSides, 30462 values: gapValues, 30463 allowReset: false, 30464 splitOnAxis: isAxialGap 30465 }) : (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalUnitControl, { 30466 label: (0,external_wp_i18n_namespaceObject.__)('Block spacing'), 30467 __unstableInputWidth: "80px", 30468 min: 0, 30469 onChange: setGapValue, 30470 units: units, 30471 value: gapValue 30472 })), showSpacingPresetsControl && (0,external_React_.createElement)(SpacingSizesControl, { 30473 label: (0,external_wp_i18n_namespaceObject.__)('Block spacing'), 30474 min: 0, 30475 onChange: setGapValues, 30476 showSideInLabel: false, 30477 sides: isAxialGap ? gapSides : ['top'] // Use 'top' as the shorthand property in non-axial configurations. 30478 , 30479 values: gapValues, 30480 allowReset: false 30481 })), showMinHeightControl && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 30482 hasValue: hasMinHeightValue, 30483 label: (0,external_wp_i18n_namespaceObject.__)('Minimum height'), 30484 onDeselect: resetMinHeightValue, 30485 isShownByDefault: (_defaultControls$minH = defaultControls.minHeight) !== null && _defaultControls$minH !== void 0 ? _defaultControls$minH : dimensions_panel_DEFAULT_CONTROLS.minHeight, 30486 panelId: panelId 30487 }, (0,external_React_.createElement)(HeightControl, { 30488 label: (0,external_wp_i18n_namespaceObject.__)('Minimum height'), 30489 value: minHeightValue, 30490 onChange: setMinHeightValue 30491 })), showAspectRatioControl && (0,external_React_.createElement)(AspectRatioTool, { 30492 hasValue: hasAspectRatioValue, 30493 value: aspectRatioValue, 30494 onChange: setAspectRatioValue, 30495 panelId: panelId, 30496 isShownByDefault: (_defaultControls$aspe = defaultControls.aspectRatio) !== null && _defaultControls$aspe !== void 0 ? _defaultControls$aspe : dimensions_panel_DEFAULT_CONTROLS.aspectRatio 30497 }), showChildLayoutControl && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalVStack, { 30498 as: external_wp_components_namespaceObject.__experimentalToolsPanelItem, 30499 spacing: 2, 30500 hasValue: hasChildLayoutValue, 30501 label: childLayoutOrientationLabel, 30502 onDeselect: resetChildLayoutValue, 30503 isShownByDefault: (_defaultControls$chil = defaultControls.childLayout) !== null && _defaultControls$chil !== void 0 ? _defaultControls$chil : dimensions_panel_DEFAULT_CONTROLS.childLayout, 30504 panelId: panelId 30505 }, (0,external_React_.createElement)(ChildLayoutControl, { 30506 value: childLayout, 30507 onChange: setChildLayout, 30508 parentLayout: settings?.parentLayout 30509 }))); 30510 } 30511 30512 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-popover/use-popover-scroll.js 30513 /** 30514 * WordPress dependencies 30515 */ 30516 30517 30518 /** 30519 * Allow scrolling "through" popovers over the canvas. This is only called for 30520 * as long as the pointer is over a popover. Do not use React events because it 30521 * will bubble through portals. 30522 * 30523 * @param {Object} scrollableRef 30524 */ 30525 function usePopoverScroll(scrollableRef) { 30526 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 30527 if (!scrollableRef) { 30528 return; 30529 } 30530 function onWheel(event) { 30531 const { 30532 deltaX, 30533 deltaY 30534 } = event; 30535 scrollableRef.current.scrollBy(deltaX, deltaY); 30536 } 30537 // Tell the browser that we do not call event.preventDefault 30538 // See https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#improving_scrolling_performance_with_passive_listeners 30539 const options = { 30540 passive: true 30541 }; 30542 node.addEventListener('wheel', onWheel, options); 30543 return () => { 30544 node.removeEventListener('wheel', onWheel, options); 30545 }; 30546 }, [scrollableRef]); 30547 } 30548 /* harmony default export */ const use_popover_scroll = (usePopoverScroll); 30549 30550 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-popover/index.js 30551 30552 /** 30553 * External dependencies 30554 */ 30555 30556 30557 /** 30558 * WordPress dependencies 30559 */ 30560 30561 30562 30563 30564 /** 30565 * Internal dependencies 30566 */ 30567 30568 30569 const MAX_POPOVER_RECOMPUTE_COUNTER = Number.MAX_SAFE_INTEGER; 30570 function BlockPopover({ 30571 clientId, 30572 bottomClientId, 30573 children, 30574 __unstableRefreshSize, 30575 __unstableCoverTarget = false, 30576 __unstablePopoverSlot, 30577 __unstableContentRef, 30578 shift = true, 30579 ...props 30580 }, ref) { 30581 const selectedElement = useBlockElement(clientId); 30582 const lastSelectedElement = useBlockElement(bottomClientId !== null && bottomClientId !== void 0 ? bottomClientId : clientId); 30583 const mergedRefs = (0,external_wp_compose_namespaceObject.useMergeRefs)([ref, use_popover_scroll(__unstableContentRef)]); 30584 const [popoverDimensionsRecomputeCounter, forceRecomputePopoverDimensions] = (0,external_wp_element_namespaceObject.useReducer)( 30585 // Module is there to make sure that the counter doesn't overflow. 30586 s => (s + 1) % MAX_POPOVER_RECOMPUTE_COUNTER, 0); 30587 30588 // When blocks are moved up/down, they are animated to their new position by 30589 // updating the `transform` property manually (i.e. without using CSS 30590 // transitions or animations). The animation, which can also scroll the block 30591 // editor, can sometimes cause the position of the Popover to get out of sync. 30592 // A MutationObserver is therefore used to make sure that changes to the 30593 // selectedElement's attribute (i.e. `transform`) can be tracked and used to 30594 // trigger the Popover to rerender. 30595 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 30596 if (!selectedElement) { 30597 return; 30598 } 30599 const observer = new window.MutationObserver(forceRecomputePopoverDimensions); 30600 observer.observe(selectedElement, { 30601 attributes: true 30602 }); 30603 return () => { 30604 observer.disconnect(); 30605 }; 30606 }, [selectedElement]); 30607 const style = (0,external_wp_element_namespaceObject.useMemo)(() => { 30608 if ( 30609 // popoverDimensionsRecomputeCounter is by definition always equal or greater 30610 // than 0. This check is only there to satisfy the correctness of the 30611 // exhaustive-deps rule for the `useMemo` hook. 30612 popoverDimensionsRecomputeCounter < 0 || !selectedElement || lastSelectedElement !== selectedElement) { 30613 return {}; 30614 } 30615 return { 30616 position: 'absolute', 30617 width: selectedElement.offsetWidth, 30618 height: selectedElement.offsetHeight 30619 }; 30620 }, [selectedElement, lastSelectedElement, __unstableRefreshSize, popoverDimensionsRecomputeCounter]); 30621 const popoverAnchor = (0,external_wp_element_namespaceObject.useMemo)(() => { 30622 if ( 30623 // popoverDimensionsRecomputeCounter is by definition always equal or greater 30624 // than 0. This check is only there to satisfy the correctness of the 30625 // exhaustive-deps rule for the `useMemo` hook. 30626 popoverDimensionsRecomputeCounter < 0 || !selectedElement || bottomClientId && !lastSelectedElement) { 30627 return undefined; 30628 } 30629 return { 30630 getBoundingClientRect() { 30631 var _lastSelectedBCR$left, _lastSelectedBCR$top, _lastSelectedBCR$righ, _lastSelectedBCR$bott; 30632 const selectedBCR = selectedElement.getBoundingClientRect(); 30633 const lastSelectedBCR = lastSelectedElement?.getBoundingClientRect(); 30634 30635 // Get the biggest rectangle that encompasses completely the currently 30636 // selected element and the last selected element: 30637 // - for top/left coordinates, use the smaller numbers 30638 // - for the bottom/right coordinates, use the largest numbers 30639 const left = Math.min(selectedBCR.left, (_lastSelectedBCR$left = lastSelectedBCR?.left) !== null && _lastSelectedBCR$left !== void 0 ? _lastSelectedBCR$left : Infinity); 30640 const top = Math.min(selectedBCR.top, (_lastSelectedBCR$top = lastSelectedBCR?.top) !== null && _lastSelectedBCR$top !== void 0 ? _lastSelectedBCR$top : Infinity); 30641 const right = Math.max(selectedBCR.right, (_lastSelectedBCR$righ = lastSelectedBCR.right) !== null && _lastSelectedBCR$righ !== void 0 ? _lastSelectedBCR$righ : -Infinity); 30642 const bottom = Math.max(selectedBCR.bottom, (_lastSelectedBCR$bott = lastSelectedBCR.bottom) !== null && _lastSelectedBCR$bott !== void 0 ? _lastSelectedBCR$bott : -Infinity); 30643 const width = right - left; 30644 const height = bottom - top; 30645 return new window.DOMRect(left, top, width, height); 30646 }, 30647 contextElement: selectedElement 30648 }; 30649 }, [bottomClientId, lastSelectedElement, selectedElement, popoverDimensionsRecomputeCounter]); 30650 if (!selectedElement || bottomClientId && !lastSelectedElement) { 30651 return null; 30652 } 30653 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Popover, { 30654 ref: mergedRefs, 30655 animate: false, 30656 focusOnMount: false, 30657 anchor: popoverAnchor 30658 // Render in the old slot if needed for backward compatibility, 30659 // otherwise render in place (not in the default popover slot). 30660 , 30661 __unstableSlotName: __unstablePopoverSlot, 30662 inline: !__unstablePopoverSlot, 30663 placement: "top-start", 30664 resize: false, 30665 flip: false, 30666 shift: shift, 30667 ...props, 30668 className: classnames_default()('block-editor-block-popover', props.className), 30669 variant: "unstyled" 30670 }, __unstableCoverTarget && (0,external_React_.createElement)("div", { 30671 style: style 30672 }, children), !__unstableCoverTarget && children); 30673 } 30674 /* harmony default export */ const block_popover = ((0,external_wp_element_namespaceObject.forwardRef)(BlockPopover)); 30675 30676 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/margin.js 30677 30678 /** 30679 * WordPress dependencies 30680 */ 30681 30682 30683 30684 /** 30685 * Internal dependencies 30686 */ 30687 30688 30689 function getComputedCSS(element, property) { 30690 return element.ownerDocument.defaultView.getComputedStyle(element).getPropertyValue(property); 30691 } 30692 function MarginVisualizer({ 30693 clientId, 30694 attributes, 30695 forceShow 30696 }) { 30697 const blockElement = useBlockElement(clientId); 30698 const [style, setStyle] = (0,external_wp_element_namespaceObject.useState)(); 30699 const margin = attributes?.style?.spacing?.margin; 30700 (0,external_wp_element_namespaceObject.useEffect)(() => { 30701 if (!blockElement || null === blockElement.ownerDocument.defaultView) { 30702 return; 30703 } 30704 const top = getComputedCSS(blockElement, 'margin-top'); 30705 const right = getComputedCSS(blockElement, 'margin-right'); 30706 const bottom = getComputedCSS(blockElement, 'margin-bottom'); 30707 const left = getComputedCSS(blockElement, 'margin-left'); 30708 setStyle({ 30709 borderTopWidth: top, 30710 borderRightWidth: right, 30711 borderBottomWidth: bottom, 30712 borderLeftWidth: left, 30713 top: top ? `-$top}` : 0, 30714 right: right ? `-$right}` : 0, 30715 bottom: bottom ? `-$bottom}` : 0, 30716 left: left ? `-$left}` : 0 30717 }); 30718 }, [blockElement, margin]); 30719 const [isActive, setIsActive] = (0,external_wp_element_namespaceObject.useState)(false); 30720 const valueRef = (0,external_wp_element_namespaceObject.useRef)(margin); 30721 const timeoutRef = (0,external_wp_element_namespaceObject.useRef)(); 30722 const clearTimer = () => { 30723 if (timeoutRef.current) { 30724 window.clearTimeout(timeoutRef.current); 30725 } 30726 }; 30727 (0,external_wp_element_namespaceObject.useEffect)(() => { 30728 if (!external_wp_isShallowEqual_default()(margin, valueRef.current) && !forceShow) { 30729 setIsActive(true); 30730 valueRef.current = margin; 30731 timeoutRef.current = setTimeout(() => { 30732 setIsActive(false); 30733 }, 400); 30734 } 30735 return () => { 30736 setIsActive(false); 30737 clearTimer(); 30738 }; 30739 }, [margin, forceShow]); 30740 if (!isActive && !forceShow) { 30741 return null; 30742 } 30743 return (0,external_React_.createElement)(block_popover, { 30744 clientId: clientId, 30745 __unstableCoverTarget: true, 30746 __unstableRefreshSize: margin, 30747 __unstablePopoverSlot: "block-toolbar", 30748 shift: false 30749 }, (0,external_React_.createElement)("div", { 30750 className: "block-editor__padding-visualizer", 30751 style: style 30752 })); 30753 } 30754 30755 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/padding.js 30756 30757 /** 30758 * WordPress dependencies 30759 */ 30760 30761 30762 30763 /** 30764 * Internal dependencies 30765 */ 30766 30767 30768 function padding_getComputedCSS(element, property) { 30769 return element.ownerDocument.defaultView.getComputedStyle(element).getPropertyValue(property); 30770 } 30771 function PaddingVisualizer({ 30772 clientId, 30773 value, 30774 forceShow 30775 }) { 30776 const blockElement = useBlockElement(clientId); 30777 const [style, setStyle] = (0,external_wp_element_namespaceObject.useState)(); 30778 const padding = value?.spacing?.padding; 30779 (0,external_wp_element_namespaceObject.useEffect)(() => { 30780 if (!blockElement || null === blockElement.ownerDocument.defaultView) { 30781 return; 30782 } 30783 setStyle({ 30784 borderTopWidth: padding_getComputedCSS(blockElement, 'padding-top'), 30785 borderRightWidth: padding_getComputedCSS(blockElement, 'padding-right'), 30786 borderBottomWidth: padding_getComputedCSS(blockElement, 'padding-bottom'), 30787 borderLeftWidth: padding_getComputedCSS(blockElement, 'padding-left') 30788 }); 30789 }, [blockElement, padding]); 30790 const [isActive, setIsActive] = (0,external_wp_element_namespaceObject.useState)(false); 30791 const valueRef = (0,external_wp_element_namespaceObject.useRef)(padding); 30792 const timeoutRef = (0,external_wp_element_namespaceObject.useRef)(); 30793 const clearTimer = () => { 30794 if (timeoutRef.current) { 30795 window.clearTimeout(timeoutRef.current); 30796 } 30797 }; 30798 (0,external_wp_element_namespaceObject.useEffect)(() => { 30799 if (!external_wp_isShallowEqual_default()(padding, valueRef.current) && !forceShow) { 30800 setIsActive(true); 30801 valueRef.current = padding; 30802 timeoutRef.current = setTimeout(() => { 30803 setIsActive(false); 30804 }, 400); 30805 } 30806 return () => { 30807 setIsActive(false); 30808 clearTimer(); 30809 }; 30810 }, [padding, forceShow]); 30811 if (!isActive && !forceShow) { 30812 return null; 30813 } 30814 return (0,external_React_.createElement)(block_popover, { 30815 clientId: clientId, 30816 __unstableCoverTarget: true, 30817 __unstableRefreshSize: padding, 30818 __unstablePopoverSlot: "block-toolbar", 30819 shift: false 30820 }, (0,external_React_.createElement)("div", { 30821 className: "block-editor__padding-visualizer", 30822 style: style 30823 })); 30824 } 30825 30826 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/dimensions.js 30827 30828 /** 30829 * External dependencies 30830 */ 30831 30832 30833 /** 30834 * WordPress dependencies 30835 */ 30836 30837 30838 30839 30840 30841 /** 30842 * Internal dependencies 30843 */ 30844 30845 30846 30847 30848 30849 30850 30851 const DIMENSIONS_SUPPORT_KEY = 'dimensions'; 30852 const SPACING_SUPPORT_KEY = 'spacing'; 30853 const dimensions_ALL_SIDES = (/* unused pure expression or super */ null && (['top', 'right', 'bottom', 'left'])); 30854 const dimensions_AXIAL_SIDES = (/* unused pure expression or super */ null && (['vertical', 'horizontal'])); 30855 function useVisualizer() { 30856 const [property, setProperty] = (0,external_wp_element_namespaceObject.useState)(false); 30857 const { 30858 hideBlockInterface, 30859 showBlockInterface 30860 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store)); 30861 (0,external_wp_element_namespaceObject.useEffect)(() => { 30862 if (!property) { 30863 showBlockInterface(); 30864 } else { 30865 hideBlockInterface(); 30866 } 30867 }, [property, showBlockInterface, hideBlockInterface]); 30868 return [property, setProperty]; 30869 } 30870 function DimensionsInspectorControl({ 30871 children, 30872 resetAllFilter 30873 }) { 30874 const attributesResetAllFilter = (0,external_wp_element_namespaceObject.useCallback)(attributes => { 30875 const existingStyle = attributes.style; 30876 const updatedStyle = resetAllFilter(existingStyle); 30877 return { 30878 ...attributes, 30879 style: updatedStyle 30880 }; 30881 }, [resetAllFilter]); 30882 return (0,external_React_.createElement)(inspector_controls, { 30883 group: "dimensions", 30884 resetAllFilter: attributesResetAllFilter 30885 }, children); 30886 } 30887 function dimensions_DimensionsPanel({ 30888 clientId, 30889 name, 30890 setAttributes, 30891 settings 30892 }) { 30893 const isEnabled = useHasDimensionsPanel(settings); 30894 const value = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getBlockAttributes(clientId)?.style, [clientId]); 30895 const [visualizedProperty, setVisualizedProperty] = useVisualizer(); 30896 const onChange = newStyle => { 30897 setAttributes({ 30898 style: utils_cleanEmptyObject(newStyle) 30899 }); 30900 }; 30901 if (!isEnabled) { 30902 return null; 30903 } 30904 const defaultDimensionsControls = (0,external_wp_blocks_namespaceObject.getBlockSupport)(name, [DIMENSIONS_SUPPORT_KEY, '__experimentalDefaultControls']); 30905 const defaultSpacingControls = (0,external_wp_blocks_namespaceObject.getBlockSupport)(name, [SPACING_SUPPORT_KEY, '__experimentalDefaultControls']); 30906 const defaultControls = { 30907 ...defaultDimensionsControls, 30908 ...defaultSpacingControls 30909 }; 30910 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(DimensionsPanel, { 30911 as: DimensionsInspectorControl, 30912 panelId: clientId, 30913 settings: settings, 30914 value: value, 30915 onChange: onChange, 30916 defaultControls: defaultControls, 30917 onVisualize: setVisualizedProperty 30918 }), !!settings?.spacing?.padding && (0,external_React_.createElement)(PaddingVisualizer, { 30919 forceShow: visualizedProperty === 'padding', 30920 clientId: clientId, 30921 value: value 30922 }), !!settings?.spacing?.margin && (0,external_React_.createElement)(MarginVisualizer, { 30923 forceShow: visualizedProperty === 'margin', 30924 clientId: clientId, 30925 value: value 30926 })); 30927 } 30928 30929 /** 30930 * Determine whether there is block support for dimensions. 30931 * 30932 * @param {string} blockName Block name. 30933 * @param {string} feature Background image feature to check for. 30934 * 30935 * @return {boolean} Whether there is support. 30936 */ 30937 function hasDimensionsSupport(blockName, feature = 'any') { 30938 if (external_wp_element_namespaceObject.Platform.OS !== 'web') { 30939 return false; 30940 } 30941 const support = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockName, DIMENSIONS_SUPPORT_KEY); 30942 if (support === true) { 30943 return true; 30944 } 30945 if (feature === 'any') { 30946 return !!(support?.aspectRatio || !!support?.minHeight); 30947 } 30948 return !!support?.[feature]; 30949 } 30950 /* harmony default export */ const dimensions = ({ 30951 useBlockProps: dimensions_useBlockProps, 30952 attributeKeys: ['minHeight', 'style'], 30953 hasSupport(name) { 30954 return hasDimensionsSupport(name, 'aspectRatio'); 30955 } 30956 }); 30957 function dimensions_useBlockProps({ 30958 name, 30959 minHeight, 30960 style 30961 }) { 30962 if (!hasDimensionsSupport(name, 'aspectRatio') || shouldSkipSerialization(name, DIMENSIONS_SUPPORT_KEY, 'aspectRatio')) { 30963 return {}; 30964 } 30965 const className = classnames_default()({ 30966 'has-aspect-ratio': !!style?.dimensions?.aspectRatio 30967 }); 30968 30969 // Allow dimensions-based inline style overrides to override any global styles rules that 30970 // might be set for the block, and therefore affect the display of the aspect ratio. 30971 const inlineStyleOverrides = {}; 30972 30973 // Apply rules to unset incompatible styles. 30974 // Note that a set `aspectRatio` will win out if both an aspect ratio and a minHeight are set. 30975 // This is because the aspect ratio is a newer block support, so (in theory) any aspect ratio 30976 // that is set should be intentional and should override any existing minHeight. The Cover block 30977 // and dimensions controls have logic that will manually clear the aspect ratio if a minHeight 30978 // is set. 30979 if (style?.dimensions?.aspectRatio) { 30980 // To ensure the aspect ratio does not get overridden by `minHeight` unset any existing rule. 30981 inlineStyleOverrides.minHeight = 'unset'; 30982 } else if (minHeight || style?.dimensions?.minHeight) { 30983 // To ensure the minHeight does not get overridden by `aspectRatio` unset any existing rule. 30984 inlineStyleOverrides.aspectRatio = 'unset'; 30985 } 30986 return { 30987 className, 30988 style: inlineStyleOverrides 30989 }; 30990 } 30991 30992 /** 30993 * @deprecated 30994 */ 30995 function useCustomSides() { 30996 external_wp_deprecated_default()('wp.blockEditor.__experimentalUseCustomSides', { 30997 since: '6.3', 30998 version: '6.4' 30999 }); 31000 } 31001 31002 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/style.js 31003 31004 /** 31005 * WordPress dependencies 31006 */ 31007 31008 31009 31010 31011 31012 31013 /** 31014 * Internal dependencies 31015 */ 31016 31017 31018 31019 31020 31021 31022 31023 31024 const styleSupportKeys = [...TYPOGRAPHY_SUPPORT_KEYS, BORDER_SUPPORT_KEY, COLOR_SUPPORT_KEY, DIMENSIONS_SUPPORT_KEY, BACKGROUND_SUPPORT_KEY, SPACING_SUPPORT_KEY, SHADOW_SUPPORT_KEY]; 31025 const hasStyleSupport = nameOrType => styleSupportKeys.some(key => (0,external_wp_blocks_namespaceObject.hasBlockSupport)(nameOrType, key)); 31026 31027 /** 31028 * Returns the inline styles to add depending on the style object 31029 * 31030 * @param {Object} styles Styles configuration. 31031 * 31032 * @return {Object} Flattened CSS variables declaration. 31033 */ 31034 function getInlineStyles(styles = {}) { 31035 const output = {}; 31036 // The goal is to move everything to server side generated engine styles 31037 // This is temporary as we absorb more and more styles into the engine. 31038 (0,external_wp_styleEngine_namespaceObject.getCSSRules)(styles).forEach(rule => { 31039 output[rule.key] = rule.value; 31040 }); 31041 return output; 31042 } 31043 31044 /** 31045 * Filters registered block settings, extending attributes to include `style` attribute. 31046 * 31047 * @param {Object} settings Original block settings. 31048 * 31049 * @return {Object} Filtered block settings. 31050 */ 31051 function style_addAttribute(settings) { 31052 if (!hasStyleSupport(settings)) { 31053 return settings; 31054 } 31055 31056 // Allow blocks to specify their own attribute definition with default values if needed. 31057 if (!settings.attributes.style) { 31058 Object.assign(settings.attributes, { 31059 style: { 31060 type: 'object' 31061 } 31062 }); 31063 } 31064 return settings; 31065 } 31066 31067 /** 31068 * A dictionary of paths to flag skipping block support serialization as the key, 31069 * with values providing the style paths to be omitted from serialization. 31070 * 31071 * @constant 31072 * @type {Record<string, string[]>} 31073 */ 31074 const skipSerializationPathsEdit = { 31075 [`$BORDER_SUPPORT_KEY}.__experimentalSkipSerialization`]: ['border'], 31076 [`$COLOR_SUPPORT_KEY}.__experimentalSkipSerialization`]: [COLOR_SUPPORT_KEY], 31077 [`$TYPOGRAPHY_SUPPORT_KEY}.__experimentalSkipSerialization`]: [TYPOGRAPHY_SUPPORT_KEY], 31078 [`$DIMENSIONS_SUPPORT_KEY}.__experimentalSkipSerialization`]: [DIMENSIONS_SUPPORT_KEY], 31079 [`$SPACING_SUPPORT_KEY}.__experimentalSkipSerialization`]: [SPACING_SUPPORT_KEY], 31080 [`$SHADOW_SUPPORT_KEY}.__experimentalSkipSerialization`]: [SHADOW_SUPPORT_KEY] 31081 }; 31082 31083 /** 31084 * A dictionary of paths to flag skipping block support serialization as the key, 31085 * with values providing the style paths to be omitted from serialization. 31086 * 31087 * Extends the Edit skip paths to enable skipping additional paths in just 31088 * the Save component. This allows a block support to be serialized within the 31089 * editor, while using an alternate approach, such as server-side rendering, when 31090 * the support is saved. 31091 * 31092 * @constant 31093 * @type {Record<string, string[]>} 31094 */ 31095 const skipSerializationPathsSave = { 31096 ...skipSerializationPathsEdit, 31097 [`$DIMENSIONS_SUPPORT_KEY}.aspectRatio`]: [`$DIMENSIONS_SUPPORT_KEY}.aspectRatio`], 31098 // Skip serialization of aspect ratio in save mode. 31099 [`$BACKGROUND_SUPPORT_KEY}`]: [BACKGROUND_SUPPORT_KEY] // Skip serialization of background support in save mode. 31100 }; 31101 const skipSerializationPathsSaveChecks = { 31102 [`$DIMENSIONS_SUPPORT_KEY}.aspectRatio`]: true, 31103 [`$BACKGROUND_SUPPORT_KEY}`]: true 31104 }; 31105 31106 /** 31107 * A dictionary used to normalize feature names between support flags, style 31108 * object properties and __experimentSkipSerialization configuration arrays. 31109 * 31110 * This allows not having to provide a migration for a support flag and possible 31111 * backwards compatibility bridges, while still achieving consistency between 31112 * the support flag and the skip serialization array. 31113 * 31114 * @constant 31115 * @type {Record<string, string>} 31116 */ 31117 const renamedFeatures = { 31118 gradients: 'gradient' 31119 }; 31120 31121 /** 31122 * A utility function used to remove one or more paths from a style object. 31123 * Works in a way similar to Lodash's `omit()`. See unit tests and examples below. 31124 * 31125 * It supports a single string path: 31126 * 31127 * ``` 31128 * omitStyle( { color: 'red' }, 'color' ); // {} 31129 * ``` 31130 * 31131 * or an array of paths: 31132 * 31133 * ``` 31134 * omitStyle( { color: 'red', background: '#fff' }, [ 'color', 'background' ] ); // {} 31135 * ``` 31136 * 31137 * It also allows you to specify paths at multiple levels in a string. 31138 * 31139 * ``` 31140 * omitStyle( { typography: { textDecoration: 'underline' } }, 'typography.textDecoration' ); // {} 31141 * ``` 31142 * 31143 * You can remove multiple paths at the same time: 31144 * 31145 * ``` 31146 * omitStyle( 31147 * { 31148 * typography: { 31149 * textDecoration: 'underline', 31150 * textTransform: 'uppercase', 31151 * } 31152 * }, 31153 * [ 31154 * 'typography.textDecoration', 31155 * 'typography.textTransform', 31156 * ] 31157 * ); 31158 * // {} 31159 * ``` 31160 * 31161 * You can also specify nested paths as arrays: 31162 * 31163 * ``` 31164 * omitStyle( 31165 * { 31166 * typography: { 31167 * textDecoration: 'underline', 31168 * textTransform: 'uppercase', 31169 * } 31170 * }, 31171 * [ 31172 * [ 'typography', 'textDecoration' ], 31173 * [ 'typography', 'textTransform' ], 31174 * ] 31175 * ); 31176 * // {} 31177 * ``` 31178 * 31179 * With regards to nesting of styles, infinite depth is supported: 31180 * 31181 * ``` 31182 * omitStyle( 31183 * { 31184 * border: { 31185 * radius: { 31186 * topLeft: '10px', 31187 * topRight: '0.5rem', 31188 * } 31189 * } 31190 * }, 31191 * [ 31192 * [ 'border', 'radius', 'topRight' ], 31193 * ] 31194 * ); 31195 * // { border: { radius: { topLeft: '10px' } } } 31196 * ``` 31197 * 31198 * The third argument, `preserveReference`, defines how to treat the input style object. 31199 * It is mostly necessary to properly handle mutation when recursively handling the style object. 31200 * Defaulting to `false`, this will always create a new object, avoiding to mutate `style`. 31201 * However, when recursing, we change that value to `true` in order to work with a single copy 31202 * of the original style object. 31203 * 31204 * @see https://lodash.com/docs/4.17.15#omit 31205 * 31206 * @param {Object} style Styles object. 31207 * @param {Array|string} paths Paths to remove. 31208 * @param {boolean} preserveReference True to mutate the `style` object, false otherwise. 31209 * @return {Object} Styles object with the specified paths removed. 31210 */ 31211 function omitStyle(style, paths, preserveReference = false) { 31212 if (!style) { 31213 return style; 31214 } 31215 let newStyle = style; 31216 if (!preserveReference) { 31217 newStyle = JSON.parse(JSON.stringify(style)); 31218 } 31219 if (!Array.isArray(paths)) { 31220 paths = [paths]; 31221 } 31222 paths.forEach(path => { 31223 if (!Array.isArray(path)) { 31224 path = path.split('.'); 31225 } 31226 if (path.length > 1) { 31227 const [firstSubpath, ...restPath] = path; 31228 omitStyle(newStyle[firstSubpath], [restPath], true); 31229 } else if (path.length === 1) { 31230 delete newStyle[path[0]]; 31231 } 31232 }); 31233 return newStyle; 31234 } 31235 31236 /** 31237 * Override props assigned to save component to inject the CSS variables definition. 31238 * 31239 * @param {Object} props Additional props applied to save element. 31240 * @param {Object|string} blockNameOrType Block type. 31241 * @param {Object} attributes Block attributes. 31242 * @param {?Record<string, string[]>} skipPaths An object of keys and paths to skip serialization. 31243 * 31244 * @return {Object} Filtered props applied to save element. 31245 */ 31246 function style_addSaveProps(props, blockNameOrType, attributes, skipPaths = skipSerializationPathsSave) { 31247 if (!hasStyleSupport(blockNameOrType)) { 31248 return props; 31249 } 31250 let { 31251 style 31252 } = attributes; 31253 Object.entries(skipPaths).forEach(([indicator, path]) => { 31254 const skipSerialization = skipSerializationPathsSaveChecks[indicator] || (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockNameOrType, indicator); 31255 if (skipSerialization === true) { 31256 style = omitStyle(style, path); 31257 } 31258 if (Array.isArray(skipSerialization)) { 31259 skipSerialization.forEach(featureName => { 31260 const feature = renamedFeatures[featureName] || featureName; 31261 style = omitStyle(style, [[...path, feature]]); 31262 }); 31263 } 31264 }); 31265 props.style = { 31266 ...getInlineStyles(style), 31267 ...props.style 31268 }; 31269 return props; 31270 } 31271 function BlockStyleControls({ 31272 clientId, 31273 name, 31274 setAttributes, 31275 __unstableParentLayout 31276 }) { 31277 const settings = useBlockSettings(name, __unstableParentLayout); 31278 const blockEditingMode = useBlockEditingMode(); 31279 const passedProps = { 31280 clientId, 31281 name, 31282 setAttributes, 31283 settings 31284 }; 31285 if (blockEditingMode !== 'default') { 31286 return null; 31287 } 31288 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(ColorEdit, { 31289 ...passedProps 31290 }), (0,external_React_.createElement)(BackgroundImagePanel, { 31291 ...passedProps 31292 }), (0,external_React_.createElement)(typography_TypographyPanel, { 31293 ...passedProps 31294 }), (0,external_React_.createElement)(border_BorderPanel, { 31295 ...passedProps 31296 }), (0,external_React_.createElement)(dimensions_DimensionsPanel, { 31297 ...passedProps 31298 })); 31299 } 31300 /* harmony default export */ const style = ({ 31301 edit: BlockStyleControls, 31302 hasSupport: hasStyleSupport, 31303 addSaveProps: style_addSaveProps, 31304 attributeKeys: ['style'], 31305 useBlockProps: style_useBlockProps 31306 }); 31307 31308 // Defines which element types are supported, including their hover styles or 31309 // any other elements that have been included under a single element type 31310 // e.g. heading and h1-h6. 31311 const elementTypes = [{ 31312 elementType: 'button' 31313 }, { 31314 elementType: 'link', 31315 pseudo: [':hover'] 31316 }, { 31317 elementType: 'heading', 31318 elements: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] 31319 }]; 31320 function style_useBlockProps({ 31321 name, 31322 style 31323 }) { 31324 const blockElementsContainerIdentifier = `wp-elements-${(0,external_wp_compose_namespaceObject.useInstanceId)(style_useBlockProps)}`; 31325 31326 // The .editor-styles-wrapper selector is required on elements styles. As it is 31327 // added to all other editor styles, not providing it causes reset and global 31328 // styles to override element styles because of higher specificity. 31329 const baseElementSelector = `.editor-styles-wrapper .$blockElementsContainerIdentifier}`; 31330 const blockElementStyles = style?.elements; 31331 const styles = (0,external_wp_element_namespaceObject.useMemo)(() => { 31332 if (!blockElementStyles) { 31333 return; 31334 } 31335 const elementCSSRules = []; 31336 elementTypes.forEach(({ 31337 elementType, 31338 pseudo, 31339 elements 31340 }) => { 31341 const skipSerialization = shouldSkipSerialization(name, COLOR_SUPPORT_KEY, elementType); 31342 if (skipSerialization) { 31343 return; 31344 } 31345 const elementStyles = blockElementStyles?.[elementType]; 31346 31347 // Process primary element type styles. 31348 if (elementStyles) { 31349 const selector = scopeSelector(baseElementSelector, external_wp_blocks_namespaceObject.__EXPERIMENTAL_ELEMENTS[elementType]); 31350 elementCSSRules.push((0,external_wp_styleEngine_namespaceObject.compileCSS)(elementStyles, { 31351 selector 31352 })); 31353 31354 // Process any interactive states for the element type. 31355 if (pseudo) { 31356 pseudo.forEach(pseudoSelector => { 31357 if (elementStyles[pseudoSelector]) { 31358 elementCSSRules.push((0,external_wp_styleEngine_namespaceObject.compileCSS)(elementStyles[pseudoSelector], { 31359 selector: scopeSelector(baseElementSelector, `$external_wp_blocks_namespaceObject.__EXPERIMENTAL_ELEMENTS[elementType]}$pseudoSelector}`) 31360 })); 31361 } 31362 }); 31363 } 31364 } 31365 31366 // Process related elements e.g. h1-h6 for headings 31367 if (elements) { 31368 elements.forEach(element => { 31369 if (blockElementStyles[element]) { 31370 elementCSSRules.push((0,external_wp_styleEngine_namespaceObject.compileCSS)(blockElementStyles[element], { 31371 selector: scopeSelector(baseElementSelector, external_wp_blocks_namespaceObject.__EXPERIMENTAL_ELEMENTS[element]) 31372 })); 31373 } 31374 }); 31375 } 31376 }); 31377 return elementCSSRules.length > 0 ? elementCSSRules.join('') : undefined; 31378 }, [baseElementSelector, blockElementStyles, name]); 31379 useStyleOverride({ 31380 css: styles 31381 }); 31382 return style_addSaveProps({ 31383 className: blockElementsContainerIdentifier 31384 }, name, { 31385 style 31386 }, skipSerializationPathsEdit); 31387 } 31388 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/style/addAttribute', style_addAttribute); 31389 31390 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/settings.js 31391 /** 31392 * WordPress dependencies 31393 */ 31394 31395 31396 const hasSettingsSupport = blockType => (0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, '__experimentalSettings', false); 31397 function settings_addAttribute(settings) { 31398 if (!hasSettingsSupport(settings)) { 31399 return settings; 31400 } 31401 31402 // Allow blocks to specify their own attribute definition with default values if needed. 31403 if (!settings?.attributes?.settings) { 31404 settings.attributes = { 31405 ...settings.attributes, 31406 settings: { 31407 type: 'object' 31408 } 31409 }; 31410 } 31411 return settings; 31412 } 31413 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/settings/addAttribute', settings_addAttribute); 31414 31415 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/filter.js 31416 31417 /** 31418 * WordPress dependencies 31419 */ 31420 31421 const filter = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 31422 xmlns: "http://www.w3.org/2000/svg", 31423 viewBox: "0 0 24 24" 31424 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 31425 d: "M12 4 4 19h16L12 4zm0 3.2 5.5 10.3H12V7.2z" 31426 })); 31427 /* harmony default export */ const library_filter = (filter); 31428 31429 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/duotone-control/index.js 31430 31431 /** 31432 * WordPress dependencies 31433 */ 31434 31435 31436 31437 31438 31439 function DuotoneControl({ 31440 id: idProp, 31441 colorPalette, 31442 duotonePalette, 31443 disableCustomColors, 31444 disableCustomDuotone, 31445 value, 31446 onChange 31447 }) { 31448 let toolbarIcon; 31449 if (value === 'unset') { 31450 toolbarIcon = (0,external_React_.createElement)(external_wp_components_namespaceObject.ColorIndicator, { 31451 className: "block-editor-duotone-control__unset-indicator" 31452 }); 31453 } else if (value) { 31454 toolbarIcon = (0,external_React_.createElement)(external_wp_components_namespaceObject.DuotoneSwatch, { 31455 values: value 31456 }); 31457 } else { 31458 toolbarIcon = (0,external_React_.createElement)(build_module_icon, { 31459 icon: library_filter 31460 }); 31461 } 31462 const actionLabel = (0,external_wp_i18n_namespaceObject.__)('Apply duotone filter'); 31463 const id = (0,external_wp_compose_namespaceObject.useInstanceId)(DuotoneControl, 'duotone-control', idProp); 31464 const descriptionId = `$id}__description`; 31465 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Dropdown, { 31466 popoverProps: { 31467 className: 'block-editor-duotone-control__popover', 31468 headerTitle: (0,external_wp_i18n_namespaceObject.__)('Duotone') 31469 }, 31470 renderToggle: ({ 31471 isOpen, 31472 onToggle 31473 }) => { 31474 const openOnArrowDown = event => { 31475 if (!isOpen && event.keyCode === external_wp_keycodes_namespaceObject.DOWN) { 31476 event.preventDefault(); 31477 onToggle(); 31478 } 31479 }; 31480 return (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarButton, { 31481 showTooltip: true, 31482 onClick: onToggle, 31483 "aria-haspopup": "true", 31484 "aria-expanded": isOpen, 31485 onKeyDown: openOnArrowDown, 31486 label: actionLabel, 31487 icon: toolbarIcon 31488 }); 31489 }, 31490 renderContent: () => (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuGroup, { 31491 label: (0,external_wp_i18n_namespaceObject.__)('Duotone') 31492 }, (0,external_React_.createElement)("p", null, (0,external_wp_i18n_namespaceObject.__)('Create a two-tone color effect without losing your original image.')), (0,external_React_.createElement)(external_wp_components_namespaceObject.DuotonePicker, { 31493 "aria-label": actionLabel, 31494 "aria-describedby": descriptionId, 31495 colorPalette: colorPalette, 31496 duotonePalette: duotonePalette, 31497 disableCustomColors: disableCustomColors, 31498 disableCustomDuotone: disableCustomDuotone, 31499 value: value, 31500 onChange: onChange 31501 })) 31502 }); 31503 } 31504 /* harmony default export */ const duotone_control = (DuotoneControl); 31505 31506 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/duotone/utils.js 31507 /** 31508 * External dependencies 31509 */ 31510 31511 31512 /** 31513 * Convert a list of colors to an object of R, G, and B values. 31514 * 31515 * @param {string[]} colors Array of RBG color strings. 31516 * 31517 * @return {Object} R, G, and B values. 31518 */ 31519 function getValuesFromColors(colors = []) { 31520 const values = { 31521 r: [], 31522 g: [], 31523 b: [], 31524 a: [] 31525 }; 31526 colors.forEach(color => { 31527 const rgbColor = w(color).toRgb(); 31528 values.r.push(rgbColor.r / 255); 31529 values.g.push(rgbColor.g / 255); 31530 values.b.push(rgbColor.b / 255); 31531 values.a.push(rgbColor.a); 31532 }); 31533 return values; 31534 } 31535 31536 /** 31537 * Stylesheet for disabling a global styles duotone filter. 31538 * 31539 * @param {string} selector Selector to disable the filter for. 31540 * 31541 * @return {string} Filter none style. 31542 */ 31543 function getDuotoneUnsetStylesheet(selector) { 31544 return `$selector}{filter:none}`; 31545 } 31546 31547 /** 31548 * SVG and stylesheet needed for rendering the duotone filter. 31549 * 31550 * @param {string} selector Selector to apply the filter to. 31551 * @param {string} id Unique id for this duotone filter. 31552 * 31553 * @return {string} Duotone filter style. 31554 */ 31555 function getDuotoneStylesheet(selector, id) { 31556 return `$selector}{filter:url(#$id})}`; 31557 } 31558 31559 /** 31560 * The SVG part of the duotone filter. 31561 * 31562 * @param {string} id Unique id for this duotone filter. 31563 * @param {string[]} colors Color strings from dark to light. 31564 * 31565 * @return {string} Duotone SVG. 31566 */ 31567 function getDuotoneFilter(id, colors) { 31568 const values = getValuesFromColors(colors); 31569 return ` 31570 <svg 31571 xmlns:xlink="http://www.w3.org/1999/xlink" 31572 viewBox="0 0 0 0" 31573 width="0" 31574 height="0" 31575 focusable="false" 31576 role="none" 31577 aria-hidden="true" 31578 style="visibility: hidden; position: absolute; left: -9999px; overflow: hidden;" 31579 > 31580 <defs> 31581 <filter id="$id}"> 31582 <!-- 31583 Use sRGB instead of linearRGB so transparency looks correct. 31584 Use perceptual brightness to convert to grayscale. 31585 --> 31586 <feColorMatrix color-interpolation-filters="sRGB" type="matrix" values=" .299 .587 .114 0 0 .299 .587 .114 0 0 .299 .587 .114 0 0 .299 .587 .114 0 0 "></feColorMatrix> 31587 <!-- Use sRGB instead of linearRGB to be consistent with how CSS gradients work. --> 31588 <feComponentTransfer color-interpolation-filters="sRGB"> 31589 <feFuncR type="table" tableValues="$values.r.join(' ')}"></feFuncR> 31590 <feFuncG type="table" tableValues="$values.g.join(' ')}"></feFuncG> 31591 <feFuncB type="table" tableValues="$values.b.join(' ')}"></feFuncB> 31592 <feFuncA type="table" tableValues="$values.a.join(' ')}"></feFuncA> 31593 </feComponentTransfer> 31594 <!-- Re-mask the image with the original transparency since the feColorMatrix above loses that information. --> 31595 <feComposite in2="SourceGraphic" operator="in"></feComposite> 31596 </filter> 31597 </defs> 31598 </svg>`; 31599 } 31600 31601 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/global-styles/get-block-css-selector.js 31602 /** 31603 * Internal dependencies 31604 */ 31605 31606 31607 31608 /** 31609 * Determine the CSS selector for the block type and target provided, returning 31610 * it if available. 31611 * 31612 * @param {import('@wordpress/blocks').Block} blockType The block's type. 31613 * @param {string|string[]} target The desired selector's target e.g. `root`, delimited string, or array path. 31614 * @param {Object} options Options object. 31615 * @param {boolean} options.fallback Whether or not to fallback to broader selector. 31616 * 31617 * @return {?string} The CSS selector or `null` if no selector available. 31618 */ 31619 function getBlockCSSSelector(blockType, target = 'root', options = {}) { 31620 if (!target) { 31621 return null; 31622 } 31623 const { 31624 fallback = false 31625 } = options; 31626 const { 31627 name, 31628 selectors, 31629 supports 31630 } = blockType; 31631 const hasSelectors = selectors && Object.keys(selectors).length > 0; 31632 const path = Array.isArray(target) ? target.join('.') : target; 31633 31634 // Root selector. 31635 31636 // Calculated before returning as it can be used as a fallback for feature 31637 // selectors later on. 31638 let rootSelector = null; 31639 if (hasSelectors && selectors.root) { 31640 // Use the selectors API if available. 31641 rootSelector = selectors?.root; 31642 } else if (supports?.__experimentalSelector) { 31643 // Use the old experimental selector supports property if set. 31644 rootSelector = supports.__experimentalSelector; 31645 } else { 31646 // If no root selector found, generate default block class selector. 31647 rootSelector = '.wp-block-' + name.replace('core/', '').replace('/', '-'); 31648 } 31649 31650 // Return selector if it's the root target we are looking for. 31651 if (path === 'root') { 31652 return rootSelector; 31653 } 31654 31655 // If target is not `root` or `duotone` we have a feature or subfeature 31656 // as the target. If the target is a string convert to an array. 31657 const pathArray = Array.isArray(target) ? target : target.split('.'); 31658 31659 // Feature selectors ( may fallback to root selector ); 31660 if (pathArray.length === 1) { 31661 const fallbackSelector = fallback ? rootSelector : null; 31662 31663 // Prefer the selectors API if available. 31664 if (hasSelectors) { 31665 // Get selector from either `feature.root` or shorthand path. 31666 const featureSelector = getValueFromObjectPath(selectors, `$path}.root`, null) || getValueFromObjectPath(selectors, path, null); 31667 31668 // Return feature selector if found or any available fallback. 31669 return featureSelector || fallbackSelector; 31670 } 31671 31672 // Try getting old experimental supports selector value. 31673 const featureSelector = getValueFromObjectPath(supports, `$path}.__experimentalSelector`, null); 31674 31675 // If nothing to work with, provide fallback selector if available. 31676 if (!featureSelector) { 31677 return fallbackSelector; 31678 } 31679 31680 // Scope the feature selector by the block's root selector. 31681 return scopeSelector(rootSelector, featureSelector); 31682 } 31683 31684 // Subfeature selector. 31685 // This may fallback either to parent feature or root selector. 31686 let subfeatureSelector; 31687 31688 // Use selectors API if available. 31689 if (hasSelectors) { 31690 subfeatureSelector = getValueFromObjectPath(selectors, path, null); 31691 } 31692 31693 // Only return if we have a subfeature selector. 31694 if (subfeatureSelector) { 31695 return subfeatureSelector; 31696 } 31697 31698 // To this point we don't have a subfeature selector. If a fallback has been 31699 // requested, remove subfeature from target path and return results of a 31700 // call for the parent feature's selector. 31701 if (fallback) { 31702 return getBlockCSSSelector(blockType, pathArray[0], options); 31703 } 31704 31705 // We tried. 31706 return null; 31707 } 31708 31709 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/global-styles/filters-panel.js 31710 31711 /** 31712 * External dependencies 31713 */ 31714 31715 31716 /** 31717 * WordPress dependencies 31718 */ 31719 31720 31721 31722 31723 /** 31724 * Internal dependencies 31725 */ 31726 31727 31728 const filters_panel_EMPTY_ARRAY = []; 31729 function useMultiOriginColorPresets(settings, { 31730 presetSetting, 31731 defaultSetting 31732 }) { 31733 const disableDefault = !settings?.color?.[defaultSetting]; 31734 const userPresets = settings?.color?.[presetSetting]?.custom || filters_panel_EMPTY_ARRAY; 31735 const themePresets = settings?.color?.[presetSetting]?.theme || filters_panel_EMPTY_ARRAY; 31736 const defaultPresets = settings?.color?.[presetSetting]?.default || filters_panel_EMPTY_ARRAY; 31737 return (0,external_wp_element_namespaceObject.useMemo)(() => [...userPresets, ...themePresets, ...(disableDefault ? filters_panel_EMPTY_ARRAY : defaultPresets)], [disableDefault, userPresets, themePresets, defaultPresets]); 31738 } 31739 function useHasFiltersPanel(settings) { 31740 return useHasDuotoneControl(settings); 31741 } 31742 function useHasDuotoneControl(settings) { 31743 return settings.color.customDuotone || settings.color.defaultDuotone || settings.color.duotone.length > 0; 31744 } 31745 function FiltersToolsPanel({ 31746 resetAllFilter, 31747 onChange, 31748 value, 31749 panelId, 31750 children 31751 }) { 31752 const resetAll = () => { 31753 const updatedValue = resetAllFilter(value); 31754 onChange(updatedValue); 31755 }; 31756 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanel, { 31757 label: (0,external_wp_i18n_namespaceObject._x)('Filters', 'Name for applying graphical effects'), 31758 resetAll: resetAll, 31759 panelId: panelId, 31760 dropdownMenuProps: TOOLSPANEL_DROPDOWNMENU_PROPS 31761 }, children); 31762 } 31763 const filters_panel_DEFAULT_CONTROLS = { 31764 duotone: true 31765 }; 31766 const filters_panel_popoverProps = { 31767 placement: 'left-start', 31768 offset: 36, 31769 shift: true, 31770 className: 'block-editor-duotone-control__popover', 31771 headerTitle: (0,external_wp_i18n_namespaceObject.__)('Duotone') 31772 }; 31773 const LabeledColorIndicator = ({ 31774 indicator, 31775 label 31776 }) => (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, { 31777 justify: "flex-start" 31778 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalZStack, { 31779 isLayered: false, 31780 offset: -8 31781 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Flex, { 31782 expanded: false 31783 }, indicator === 'unset' || !indicator ? (0,external_React_.createElement)(external_wp_components_namespaceObject.ColorIndicator, { 31784 className: "block-editor-duotone-control__unset-indicator" 31785 }) : (0,external_React_.createElement)(external_wp_components_namespaceObject.DuotoneSwatch, { 31786 values: indicator 31787 }))), (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexItem, { 31788 title: label 31789 }, label)); 31790 function FiltersPanel({ 31791 as: Wrapper = FiltersToolsPanel, 31792 value, 31793 onChange, 31794 inheritedValue = value, 31795 settings, 31796 panelId, 31797 defaultControls = filters_panel_DEFAULT_CONTROLS 31798 }) { 31799 const decodeValue = rawValue => getValueFromVariable({ 31800 settings 31801 }, '', rawValue); 31802 31803 // Duotone 31804 const hasDuotoneEnabled = useHasDuotoneControl(settings); 31805 const duotonePalette = useMultiOriginColorPresets(settings, { 31806 presetSetting: 'duotone', 31807 defaultSetting: 'defaultDuotone' 31808 }); 31809 const colorPalette = useMultiOriginColorPresets(settings, { 31810 presetSetting: 'palette', 31811 defaultSetting: 'defaultPalette' 31812 }); 31813 const duotone = decodeValue(inheritedValue?.filter?.duotone); 31814 const setDuotone = newValue => { 31815 const duotonePreset = duotonePalette.find(({ 31816 colors 31817 }) => { 31818 return colors === newValue; 31819 }); 31820 const settedValue = duotonePreset ? `var:preset|duotone|$duotonePreset.slug}` : newValue; 31821 onChange(setImmutably(value, ['filter', 'duotone'], settedValue)); 31822 }; 31823 const hasDuotone = () => !!value?.filter?.duotone; 31824 const resetDuotone = () => setDuotone(undefined); 31825 const resetAllFilter = (0,external_wp_element_namespaceObject.useCallback)(previousValue => { 31826 return { 31827 ...previousValue, 31828 filter: { 31829 ...previousValue.filter, 31830 duotone: undefined 31831 } 31832 }; 31833 }, []); 31834 return (0,external_React_.createElement)(Wrapper, { 31835 resetAllFilter: resetAllFilter, 31836 value: value, 31837 onChange: onChange, 31838 panelId: panelId 31839 }, hasDuotoneEnabled && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 31840 label: (0,external_wp_i18n_namespaceObject.__)('Duotone'), 31841 hasValue: hasDuotone, 31842 onDeselect: resetDuotone, 31843 isShownByDefault: defaultControls.duotone, 31844 panelId: panelId 31845 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Dropdown, { 31846 popoverProps: filters_panel_popoverProps, 31847 className: "block-editor-global-styles-filters-panel__dropdown", 31848 renderToggle: ({ 31849 onToggle, 31850 isOpen 31851 }) => { 31852 const toggleProps = { 31853 onClick: onToggle, 31854 className: classnames_default()({ 31855 'is-open': isOpen 31856 }), 31857 'aria-expanded': isOpen 31858 }; 31859 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalItemGroup, { 31860 isBordered: true, 31861 isSeparated: true 31862 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 31863 ...toggleProps 31864 }, (0,external_React_.createElement)(LabeledColorIndicator, { 31865 indicator: duotone, 31866 label: (0,external_wp_i18n_namespaceObject.__)('Duotone') 31867 }))); 31868 }, 31869 renderContent: () => (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalDropdownContentWrapper, { 31870 paddingSize: "small" 31871 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuGroup, { 31872 label: (0,external_wp_i18n_namespaceObject.__)('Duotone') 31873 }, (0,external_React_.createElement)("p", null, (0,external_wp_i18n_namespaceObject.__)('Create a two-tone color effect without losing your original image.')), (0,external_React_.createElement)(external_wp_components_namespaceObject.DuotonePicker, { 31874 colorPalette: colorPalette, 31875 duotonePalette: duotonePalette 31876 // TODO: Re-enable both when custom colors are supported for block-level styles. 31877 , 31878 disableCustomColors: true, 31879 disableCustomDuotone: true, 31880 value: duotone, 31881 onChange: setDuotone 31882 }))) 31883 }))); 31884 } 31885 31886 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/duotone.js 31887 31888 /** 31889 * External dependencies 31890 */ 31891 31892 31893 31894 /** 31895 * WordPress dependencies 31896 */ 31897 31898 31899 31900 31901 31902 /** 31903 * Internal dependencies 31904 */ 31905 31906 31907 31908 31909 31910 31911 31912 31913 const duotone_EMPTY_ARRAY = []; 31914 31915 // Safari does not always update the duotone filter when the duotone colors 31916 // are changed. This browser check is later used to force a re-render of the block 31917 // element to ensure the duotone filter is updated. The check is included at the 31918 // root of this file as it only needs to be run once per page load. 31919 const isSafari = window?.navigator.userAgent && window.navigator.userAgent.includes('Safari') && !window.navigator.userAgent.includes('Chrome') && !window.navigator.userAgent.includes('Chromium'); 31920 k([names]); 31921 function useMultiOriginPresets({ 31922 presetSetting, 31923 defaultSetting 31924 }) { 31925 const [enableDefault, userPresets, themePresets, defaultPresets] = use_settings_useSettings(defaultSetting, `$presetSetting}.custom`, `$presetSetting}.theme`, `$presetSetting}.default`); 31926 return (0,external_wp_element_namespaceObject.useMemo)(() => [...(userPresets || duotone_EMPTY_ARRAY), ...(themePresets || duotone_EMPTY_ARRAY), ...(enableDefault && defaultPresets || duotone_EMPTY_ARRAY)], [enableDefault, userPresets, themePresets, defaultPresets]); 31927 } 31928 function getColorsFromDuotonePreset(duotone, duotonePalette) { 31929 if (!duotone) { 31930 return; 31931 } 31932 const preset = duotonePalette?.find(({ 31933 slug 31934 }) => { 31935 return duotone === `var:preset|duotone|$slug}`; 31936 }); 31937 return preset ? preset.colors : undefined; 31938 } 31939 function getDuotonePresetFromColors(colors, duotonePalette) { 31940 if (!colors || !Array.isArray(colors)) { 31941 return; 31942 } 31943 const preset = duotonePalette?.find(duotonePreset => { 31944 return duotonePreset?.colors?.every((val, index) => val === colors[index]); 31945 }); 31946 return preset ? `var:preset|duotone|$preset.slug}` : undefined; 31947 } 31948 function DuotonePanelPure({ 31949 style, 31950 setAttributes, 31951 name 31952 }) { 31953 const duotoneStyle = style?.color?.duotone; 31954 const settings = useBlockSettings(name); 31955 const blockEditingMode = useBlockEditingMode(); 31956 const duotonePalette = useMultiOriginPresets({ 31957 presetSetting: 'color.duotone', 31958 defaultSetting: 'color.defaultDuotone' 31959 }); 31960 const colorPalette = useMultiOriginPresets({ 31961 presetSetting: 'color.palette', 31962 defaultSetting: 'color.defaultPalette' 31963 }); 31964 const [enableCustomColors, enableCustomDuotone] = use_settings_useSettings('color.custom', 'color.customDuotone'); 31965 const disableCustomColors = !enableCustomColors; 31966 const disableCustomDuotone = !enableCustomDuotone || colorPalette?.length === 0 && disableCustomColors; 31967 if (duotonePalette?.length === 0 && disableCustomDuotone) { 31968 return null; 31969 } 31970 if (blockEditingMode !== 'default') { 31971 return null; 31972 } 31973 const duotonePresetOrColors = !Array.isArray(duotoneStyle) ? getColorsFromDuotonePreset(duotoneStyle, duotonePalette) : duotoneStyle; 31974 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(inspector_controls, { 31975 group: "filter" 31976 }, (0,external_React_.createElement)(FiltersPanel, { 31977 value: { 31978 filter: { 31979 duotone: duotonePresetOrColors 31980 } 31981 }, 31982 onChange: newDuotone => { 31983 const newStyle = { 31984 ...style, 31985 color: { 31986 ...newDuotone?.filter 31987 } 31988 }; 31989 setAttributes({ 31990 style: newStyle 31991 }); 31992 }, 31993 settings: settings 31994 })), (0,external_React_.createElement)(block_controls, { 31995 group: "block", 31996 __experimentalShareWithChildBlocks: true 31997 }, (0,external_React_.createElement)(duotone_control, { 31998 duotonePalette: duotonePalette, 31999 colorPalette: colorPalette, 32000 disableCustomDuotone: disableCustomDuotone, 32001 disableCustomColors: disableCustomColors, 32002 value: duotonePresetOrColors, 32003 onChange: newDuotone => { 32004 const maybePreset = getDuotonePresetFromColors(newDuotone, duotonePalette); 32005 const newStyle = { 32006 ...style, 32007 color: { 32008 ...style?.color, 32009 duotone: maybePreset !== null && maybePreset !== void 0 ? maybePreset : newDuotone // use preset or fallback to custom colors. 32010 } 32011 }; 32012 setAttributes({ 32013 style: newStyle 32014 }); 32015 }, 32016 settings: settings 32017 }))); 32018 } 32019 /* harmony default export */ const duotone = ({ 32020 shareWithChildBlocks: true, 32021 edit: DuotonePanelPure, 32022 useBlockProps: duotone_useBlockProps, 32023 attributeKeys: ['style'], 32024 hasSupport(name) { 32025 return (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, 'filter.duotone'); 32026 } 32027 }); 32028 32029 /** 32030 * Filters registered block settings, extending attributes to include 32031 * the `duotone` attribute. 32032 * 32033 * @param {Object} settings Original block settings. 32034 * 32035 * @return {Object} Filtered block settings. 32036 */ 32037 function addDuotoneAttributes(settings) { 32038 // Previous `color.__experimentalDuotone` support flag is migrated via 32039 // block_type_metadata_settings filter in `lib/block-supports/duotone.php`. 32040 if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(settings, 'filter.duotone')) { 32041 return settings; 32042 } 32043 32044 // Allow blocks to specify their own attribute definition with default 32045 // values if needed. 32046 if (!settings.attributes.style) { 32047 Object.assign(settings.attributes, { 32048 style: { 32049 type: 'object' 32050 } 32051 }); 32052 } 32053 return settings; 32054 } 32055 function useDuotoneStyles({ 32056 clientId, 32057 id: filterId, 32058 selector: duotoneSelector, 32059 attribute: duotoneAttr 32060 }) { 32061 const duotonePalette = useMultiOriginPresets({ 32062 presetSetting: 'color.duotone', 32063 defaultSetting: 'color.defaultDuotone' 32064 }); 32065 32066 // Possible values for duotone attribute: 32067 // 1. Array of colors - e.g. ['#000000', '#ffffff']. 32068 // 2. Variable for an existing Duotone preset - e.g. 'var:preset|duotone|green-blue' or 'var(--wp--preset--duotone--green-blue)'' 32069 // 3. A CSS string - e.g. 'unset' to remove globally applied duotone. 32070 const isCustom = Array.isArray(duotoneAttr); 32071 const duotonePreset = isCustom ? undefined : getColorsFromDuotonePreset(duotoneAttr, duotonePalette); 32072 const isPreset = typeof duotoneAttr === 'string' && duotonePreset; 32073 const isCSS = typeof duotoneAttr === 'string' && !isPreset; 32074 32075 // Match the structure of WP_Duotone_Gutenberg::render_duotone_support() in PHP. 32076 let colors = null; 32077 if (isPreset) { 32078 // Array of colors. 32079 colors = duotonePreset; 32080 } else if (isCSS) { 32081 // CSS filter property string (e.g. 'unset'). 32082 colors = duotoneAttr; 32083 } else if (isCustom) { 32084 // Array of colors. 32085 colors = duotoneAttr; 32086 } 32087 32088 // Build the CSS selectors to which the filter will be applied. 32089 const selectors = duotoneSelector.split(','); 32090 const selectorsScoped = selectors.map(selectorPart => { 32091 // Extra .editor-styles-wrapper specificity is needed in the editor 32092 // since we're not using inline styles to apply the filter. We need to 32093 // override duotone applied by global styles and theme.json. 32094 32095 // Assuming the selector part is a subclass selector (not a tag name) 32096 // so we can prepend the filter id class. If we want to support elements 32097 // such as `img` or namespaces, we'll need to add a case for that here. 32098 return `.$filterId}$selectorPart.trim()}`; 32099 }); 32100 const selector = selectorsScoped.join(', '); 32101 const isValidFilter = Array.isArray(colors) || colors === 'unset'; 32102 useStyleOverride(isValidFilter ? { 32103 css: colors !== 'unset' ? getDuotoneStylesheet(selector, filterId) : getDuotoneUnsetStylesheet(selector), 32104 __unstableType: 'presets' 32105 } : undefined); 32106 useStyleOverride(isValidFilter ? { 32107 assets: colors !== 'unset' ? getDuotoneFilter(filterId, colors) : '', 32108 __unstableType: 'svgs' 32109 } : undefined); 32110 const blockElement = useBlockElement(clientId); 32111 (0,external_wp_element_namespaceObject.useEffect)(() => { 32112 if (!isValidFilter) return; 32113 32114 // Safari does not always update the duotone filter when the duotone colors 32115 // are changed. When using Safari, force the block element to be repainted by 32116 // the browser to ensure any changes are reflected visually. This logic matches 32117 // that used on the site frontend in `block-supports/duotone.php`. 32118 if (blockElement && isSafari) { 32119 const display = blockElement.style.display; 32120 // Switch to `inline-block` to force a repaint. In the editor, `inline-block` 32121 // is used instead of `none` to ensure that scroll position is not affected, 32122 // as `none` results in the editor scrolling to the top of the block. 32123 blockElement.style.display = 'inline-block'; 32124 // Simply accessing el.offsetHeight flushes layout and style 32125 // changes in WebKit without having to wait for setTimeout. 32126 // eslint-disable-next-line no-unused-expressions 32127 blockElement.offsetHeight; 32128 blockElement.style.display = display; 32129 } 32130 }, [isValidFilter, blockElement]); 32131 } 32132 function duotone_useBlockProps({ 32133 name, 32134 style 32135 }) { 32136 const id = (0,external_wp_compose_namespaceObject.useInstanceId)(duotone_useBlockProps); 32137 const selector = (0,external_wp_element_namespaceObject.useMemo)(() => { 32138 const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(name); 32139 if (blockType) { 32140 // Backwards compatibility for `supports.color.__experimentalDuotone` 32141 // is provided via the `block_type_metadata_settings` filter. If 32142 // `supports.filter.duotone` has not been set and the 32143 // experimental property has been, the experimental property 32144 // value is copied into `supports.filter.duotone`. 32145 const duotoneSupport = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockType, 'filter.duotone', false); 32146 if (!duotoneSupport) { 32147 return null; 32148 } 32149 32150 // If the experimental duotone support was set, that value is 32151 // to be treated as a selector and requires scoping. 32152 const experimentalDuotone = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockType, 'color.__experimentalDuotone', false); 32153 if (experimentalDuotone) { 32154 const rootSelector = getBlockCSSSelector(blockType); 32155 return typeof experimentalDuotone === 'string' ? scopeSelector(rootSelector, experimentalDuotone) : rootSelector; 32156 } 32157 32158 // Regular filter.duotone support uses filter.duotone selectors with fallbacks. 32159 return getBlockCSSSelector(blockType, 'filter.duotone', { 32160 fallback: true 32161 }); 32162 } 32163 }, [name]); 32164 const attribute = style?.color?.duotone; 32165 const filterClass = `wp-duotone-$id}`; 32166 const shouldRender = selector && attribute; 32167 useDuotoneStyles({ 32168 clientId: id, 32169 id: filterClass, 32170 selector, 32171 attribute 32172 }); 32173 return { 32174 className: shouldRender ? filterClass : '' 32175 }; 32176 } 32177 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/editor/duotone/add-attributes', addDuotoneAttributes); 32178 32179 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/use-block-display-information/index.js 32180 /** 32181 * WordPress dependencies 32182 */ 32183 32184 32185 32186 32187 /** 32188 * Internal dependencies 32189 */ 32190 32191 32192 /** @typedef {import('@wordpress/blocks').WPIcon} WPIcon */ 32193 32194 /** 32195 * Contains basic block's information for display reasons. 32196 * 32197 * @typedef {Object} WPBlockDisplayInformation 32198 * 32199 * @property {boolean} isSynced True if is a reusable block or template part 32200 * @property {string} title Human-readable block type label. 32201 * @property {WPIcon} icon Block type icon. 32202 * @property {string} description A detailed block type description. 32203 * @property {string} anchor HTML anchor. 32204 * @property {name} name A custom, human readable name for the block. 32205 */ 32206 32207 /** 32208 * Get the display label for a block's position type. 32209 * 32210 * @param {Object} attributes Block attributes. 32211 * @return {string} The position type label. 32212 */ 32213 function getPositionTypeLabel(attributes) { 32214 const positionType = attributes?.style?.position?.type; 32215 if (positionType === 'sticky') { 32216 return (0,external_wp_i18n_namespaceObject.__)('Sticky'); 32217 } 32218 if (positionType === 'fixed') { 32219 return (0,external_wp_i18n_namespaceObject.__)('Fixed'); 32220 } 32221 return null; 32222 } 32223 32224 /** 32225 * Hook used to try to find a matching block variation and return 32226 * the appropriate information for display reasons. In order to 32227 * to try to find a match we need to things: 32228 * 1. Block's client id to extract it's current attributes. 32229 * 2. A block variation should have set `isActive` prop to a proper function. 32230 * 32231 * If for any reason a block variation match cannot be found, 32232 * the returned information come from the Block Type. 32233 * If no blockType is found with the provided clientId, returns null. 32234 * 32235 * @param {string} clientId Block's client id. 32236 * @return {?WPBlockDisplayInformation} Block's display information, or `null` when the block or its type not found. 32237 */ 32238 32239 function useBlockDisplayInformation(clientId) { 32240 return (0,external_wp_data_namespaceObject.useSelect)(select => { 32241 if (!clientId) return null; 32242 const { 32243 getBlockName, 32244 getBlockAttributes, 32245 __experimentalGetReusableBlockTitle 32246 } = select(store); 32247 const { 32248 getBlockType, 32249 getActiveBlockVariation 32250 } = select(external_wp_blocks_namespaceObject.store); 32251 const blockName = getBlockName(clientId); 32252 const blockType = getBlockType(blockName); 32253 if (!blockType) return null; 32254 const attributes = getBlockAttributes(clientId); 32255 const match = getActiveBlockVariation(blockName, attributes); 32256 const isReusable = (0,external_wp_blocks_namespaceObject.isReusableBlock)(blockType); 32257 const resusableTitle = isReusable ? __experimentalGetReusableBlockTitle(attributes.ref) : undefined; 32258 const title = resusableTitle || blockType.title; 32259 const isSynced = isReusable || (0,external_wp_blocks_namespaceObject.isTemplatePart)(blockType); 32260 const positionLabel = getPositionTypeLabel(attributes); 32261 const blockTypeInfo = { 32262 isSynced, 32263 title, 32264 icon: blockType.icon, 32265 description: blockType.description, 32266 anchor: attributes?.anchor, 32267 positionLabel, 32268 positionType: attributes?.style?.position?.type, 32269 name: attributes?.metadata?.name 32270 }; 32271 if (!match) return blockTypeInfo; 32272 return { 32273 isSynced, 32274 title: match.title || blockType.title, 32275 icon: match.icon || blockType.icon, 32276 description: match.description || blockType.description, 32277 anchor: attributes?.anchor, 32278 positionLabel, 32279 positionType: attributes?.style?.position?.type, 32280 name: attributes?.metadata?.name 32281 }; 32282 }, [clientId]); 32283 } 32284 32285 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/position.js 32286 32287 /** 32288 * External dependencies 32289 */ 32290 32291 32292 /** 32293 * WordPress dependencies 32294 */ 32295 32296 32297 32298 32299 32300 32301 32302 /** 32303 * Internal dependencies 32304 */ 32305 32306 32307 32308 32309 32310 32311 const { 32312 CustomSelectControl 32313 } = unlock(external_wp_components_namespaceObject.privateApis); 32314 const POSITION_SUPPORT_KEY = 'position'; 32315 const OPTION_CLASSNAME = 'block-editor-hooks__position-selection__select-control__option'; 32316 const DEFAULT_OPTION = { 32317 key: 'default', 32318 value: '', 32319 name: (0,external_wp_i18n_namespaceObject.__)('Default'), 32320 className: OPTION_CLASSNAME 32321 }; 32322 const STICKY_OPTION = { 32323 key: 'sticky', 32324 value: 'sticky', 32325 name: (0,external_wp_i18n_namespaceObject._x)('Sticky', 'Name for the value of the CSS position property'), 32326 className: OPTION_CLASSNAME, 32327 __experimentalHint: (0,external_wp_i18n_namespaceObject.__)('The block will stick to the top of the window instead of scrolling.') 32328 }; 32329 const FIXED_OPTION = { 32330 key: 'fixed', 32331 value: 'fixed', 32332 name: (0,external_wp_i18n_namespaceObject._x)('Fixed', 'Name for the value of the CSS position property'), 32333 className: OPTION_CLASSNAME, 32334 __experimentalHint: (0,external_wp_i18n_namespaceObject.__)('The block will not move when the page is scrolled.') 32335 }; 32336 const POSITION_SIDES = ['top', 'right', 'bottom', 'left']; 32337 const VALID_POSITION_TYPES = ['sticky', 'fixed']; 32338 32339 /** 32340 * Get calculated position CSS. 32341 * 32342 * @param {Object} props Component props. 32343 * @param {string} props.selector Selector to use. 32344 * @param {Object} props.style Style object. 32345 * @return {string} The generated CSS rules. 32346 */ 32347 function getPositionCSS({ 32348 selector, 32349 style 32350 }) { 32351 let output = ''; 32352 const { 32353 type: positionType 32354 } = style?.position || {}; 32355 if (!VALID_POSITION_TYPES.includes(positionType)) { 32356 return output; 32357 } 32358 output += `$selector} {`; 32359 output += `position: $positionType};`; 32360 POSITION_SIDES.forEach(side => { 32361 if (style?.position?.[side] !== undefined) { 32362 output += `$side}: $style.position[side]};`; 32363 } 32364 }); 32365 if (positionType === 'sticky' || positionType === 'fixed') { 32366 // TODO: Replace hard-coded z-index value with a z-index preset approach in theme.json. 32367 output += `z-index: 10`; 32368 } 32369 output += `}`; 32370 return output; 32371 } 32372 32373 /** 32374 * Determines if there is sticky position support. 32375 * 32376 * @param {string|Object} blockType Block name or Block Type object. 32377 * 32378 * @return {boolean} Whether there is support. 32379 */ 32380 function hasStickyPositionSupport(blockType) { 32381 const support = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockType, POSITION_SUPPORT_KEY); 32382 return !!(true === support || support?.sticky); 32383 } 32384 32385 /** 32386 * Determines if there is fixed position support. 32387 * 32388 * @param {string|Object} blockType Block name or Block Type object. 32389 * 32390 * @return {boolean} Whether there is support. 32391 */ 32392 function hasFixedPositionSupport(blockType) { 32393 const support = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockType, POSITION_SUPPORT_KEY); 32394 return !!(true === support || support?.fixed); 32395 } 32396 32397 /** 32398 * Determines if there is position support. 32399 * 32400 * @param {string|Object} blockType Block name or Block Type object. 32401 * 32402 * @return {boolean} Whether there is support. 32403 */ 32404 function hasPositionSupport(blockType) { 32405 const support = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockType, POSITION_SUPPORT_KEY); 32406 return !!support; 32407 } 32408 32409 /** 32410 * Checks if there is a current value in the position block support attributes. 32411 * 32412 * @param {Object} props Block props. 32413 * @return {boolean} Whether or not the block has a position value set. 32414 */ 32415 function hasPositionValue(props) { 32416 return props.attributes.style?.position?.type !== undefined; 32417 } 32418 32419 /** 32420 * Checks if the block is currently set to a sticky or fixed position. 32421 * This check is helpful for determining how to position block toolbars or other elements. 32422 * 32423 * @param {Object} attributes Block attributes. 32424 * @return {boolean} Whether or not the block is set to a sticky or fixed position. 32425 */ 32426 function hasStickyOrFixedPositionValue(attributes) { 32427 const positionType = attributes.style?.position?.type; 32428 return positionType === 'sticky' || positionType === 'fixed'; 32429 } 32430 32431 /** 32432 * Resets the position block support attributes. This can be used when disabling 32433 * the position support controls for a block via a `ToolsPanel`. 32434 * 32435 * @param {Object} props Block props. 32436 * @param {Object} props.attributes Block's attributes. 32437 * @param {Object} props.setAttributes Function to set block's attributes. 32438 */ 32439 function resetPosition({ 32440 attributes = {}, 32441 setAttributes 32442 }) { 32443 const { 32444 style = {} 32445 } = attributes; 32446 setAttributes({ 32447 style: cleanEmptyObject({ 32448 ...style, 32449 position: { 32450 ...style?.position, 32451 type: undefined, 32452 top: undefined, 32453 right: undefined, 32454 bottom: undefined, 32455 left: undefined 32456 } 32457 }) 32458 }); 32459 } 32460 32461 /** 32462 * Custom hook that checks if position settings have been disabled. 32463 * 32464 * @param {string} name The name of the block. 32465 * 32466 * @return {boolean} Whether padding setting is disabled. 32467 */ 32468 function useIsPositionDisabled({ 32469 name: blockName 32470 } = {}) { 32471 const [allowFixed, allowSticky] = use_settings_useSettings('position.fixed', 'position.sticky'); 32472 const isDisabled = !allowFixed && !allowSticky; 32473 return !hasPositionSupport(blockName) || isDisabled; 32474 } 32475 32476 /* 32477 * Position controls rendered in an inspector control panel. 32478 * 32479 * @param {Object} props 32480 * 32481 * @return {Element} Position panel. 32482 */ 32483 function PositionPanelPure({ 32484 style = {}, 32485 clientId, 32486 name: blockName, 32487 setAttributes 32488 }) { 32489 const allowFixed = hasFixedPositionSupport(blockName); 32490 const allowSticky = hasStickyPositionSupport(blockName); 32491 const value = style?.position?.type; 32492 const { 32493 firstParentClientId 32494 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 32495 const { 32496 getBlockParents 32497 } = select(store); 32498 const parents = getBlockParents(clientId); 32499 return { 32500 firstParentClientId: parents[parents.length - 1] 32501 }; 32502 }, [clientId]); 32503 const blockInformation = useBlockDisplayInformation(firstParentClientId); 32504 const stickyHelpText = allowSticky && value === STICKY_OPTION.value && blockInformation ? (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: the name of the parent block. */ 32505 (0,external_wp_i18n_namespaceObject.__)('The block will stick to the scrollable area of the parent %s block.'), blockInformation.title) : null; 32506 const options = (0,external_wp_element_namespaceObject.useMemo)(() => { 32507 const availableOptions = [DEFAULT_OPTION]; 32508 // Display options if they are allowed, or if a block already has a valid value set. 32509 // This allows for a block to be switched off from a position type that is not allowed. 32510 if (allowSticky || value === STICKY_OPTION.value) { 32511 availableOptions.push(STICKY_OPTION); 32512 } 32513 if (allowFixed || value === FIXED_OPTION.value) { 32514 availableOptions.push(FIXED_OPTION); 32515 } 32516 return availableOptions; 32517 }, [allowFixed, allowSticky, value]); 32518 const onChangeType = next => { 32519 // For now, use a hard-coded `0px` value for the position. 32520 // `0px` is preferred over `0` as it can be used in `calc()` functions. 32521 // In the future, it could be useful to allow for an offset value. 32522 const placementValue = '0px'; 32523 const newStyle = { 32524 ...style, 32525 position: { 32526 ...style?.position, 32527 type: next, 32528 top: next === 'sticky' || next === 'fixed' ? placementValue : undefined 32529 } 32530 }; 32531 setAttributes({ 32532 style: utils_cleanEmptyObject(newStyle) 32533 }); 32534 }; 32535 const selectedOption = value ? options.find(option => option.value === value) || DEFAULT_OPTION : DEFAULT_OPTION; 32536 32537 // Only display position controls if there is at least one option to choose from. 32538 return external_wp_element_namespaceObject.Platform.select({ 32539 web: options.length > 1 ? (0,external_React_.createElement)(inspector_controls, { 32540 group: "position" 32541 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.BaseControl, { 32542 className: "block-editor-hooks__position-selection", 32543 __nextHasNoMarginBottom: true, 32544 help: stickyHelpText 32545 }, (0,external_React_.createElement)(CustomSelectControl, { 32546 __nextUnconstrainedWidth: true, 32547 __next40pxDefaultSize: true, 32548 className: "block-editor-hooks__position-selection__select-control", 32549 label: (0,external_wp_i18n_namespaceObject.__)('Position'), 32550 hideLabelFromVision: true, 32551 describedBy: (0,external_wp_i18n_namespaceObject.sprintf)( 32552 // translators: %s: Currently selected position. 32553 (0,external_wp_i18n_namespaceObject.__)('Currently selected position: %s'), selectedOption.name), 32554 options: options, 32555 value: selectedOption, 32556 __experimentalShowSelectedHint: true, 32557 onChange: ({ 32558 selectedItem 32559 }) => { 32560 onChangeType(selectedItem.value); 32561 }, 32562 size: '__unstable-large' 32563 }))) : null, 32564 native: null 32565 }); 32566 } 32567 /* harmony default export */ const position = ({ 32568 edit: function Edit(props) { 32569 const isPositionDisabled = useIsPositionDisabled(props); 32570 if (isPositionDisabled) { 32571 return null; 32572 } 32573 return (0,external_React_.createElement)(PositionPanelPure, { 32574 ...props 32575 }); 32576 }, 32577 useBlockProps: position_useBlockProps, 32578 attributeKeys: ['style'], 32579 hasSupport(name) { 32580 return (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, POSITION_SUPPORT_KEY); 32581 } 32582 }); 32583 function position_useBlockProps({ 32584 name, 32585 style 32586 }) { 32587 const hasPositionBlockSupport = (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, POSITION_SUPPORT_KEY); 32588 const isPositionDisabled = useIsPositionDisabled({ 32589 name 32590 }); 32591 const allowPositionStyles = hasPositionBlockSupport && !isPositionDisabled; 32592 const id = (0,external_wp_compose_namespaceObject.useInstanceId)(position_useBlockProps); 32593 32594 // Higher specificity to override defaults in editor UI. 32595 const positionSelector = `.wp-container-$id}.wp-container-$id}`; 32596 32597 // Get CSS string for the current position values. 32598 let css; 32599 if (allowPositionStyles) { 32600 css = getPositionCSS({ 32601 selector: positionSelector, 32602 style 32603 }) || ''; 32604 } 32605 32606 // Attach a `wp-container-` id-based class name. 32607 const className = classnames_default()({ 32608 [`wp-container-$id}`]: allowPositionStyles && !!css, 32609 // Only attach a container class if there is generated CSS to be attached. 32610 [`is-position-$style?.position?.type}`]: allowPositionStyles && !!css && !!style?.position?.type 32611 }); 32612 useStyleOverride({ 32613 css 32614 }); 32615 return { 32616 className 32617 }; 32618 } 32619 32620 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/layout.js 32621 32622 /** 32623 * External dependencies 32624 */ 32625 32626 32627 /** 32628 * WordPress dependencies 32629 */ 32630 32631 32632 32633 32634 32635 32636 32637 /** 32638 * Internal dependencies 32639 */ 32640 32641 32642 32643 32644 32645 32646 32647 32648 const layoutBlockSupportKey = 'layout'; 32649 function hasLayoutBlockSupport(blockName) { 32650 return (0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockName, 'layout') || (0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockName, '__experimentalLayout'); 32651 } 32652 32653 /** 32654 * Generates the utility classnames for the given block's layout attributes. 32655 * 32656 * @param { Object } blockAttributes Block attributes. 32657 * @param { string } blockName Block name. 32658 * 32659 * @return { Array } Array of CSS classname strings. 32660 */ 32661 function useLayoutClasses(blockAttributes = {}, blockName = '') { 32662 const { 32663 kebabCase 32664 } = unlock(external_wp_components_namespaceObject.privateApis); 32665 const rootPaddingAlignment = (0,external_wp_data_namespaceObject.useSelect)(select => { 32666 const { 32667 getSettings 32668 } = select(store); 32669 return getSettings().__experimentalFeatures?.useRootPaddingAwareAlignments; 32670 }, []); 32671 const { 32672 layout 32673 } = blockAttributes; 32674 const { 32675 default: defaultBlockLayout 32676 } = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockName, layoutBlockSupportKey) || {}; 32677 const usedLayout = layout?.inherit || layout?.contentSize || layout?.wideSize ? { 32678 ...layout, 32679 type: 'constrained' 32680 } : layout || defaultBlockLayout || {}; 32681 const layoutClassnames = []; 32682 if (LAYOUT_DEFINITIONS[usedLayout?.type || 'default']?.className) { 32683 const baseClassName = LAYOUT_DEFINITIONS[usedLayout?.type || 'default']?.className; 32684 const splitBlockName = blockName.split('/'); 32685 const fullBlockName = splitBlockName[0] === 'core' ? splitBlockName.pop() : splitBlockName.join('-'); 32686 const compoundClassName = `wp-block-$fullBlockName}-$baseClassName}`; 32687 layoutClassnames.push(baseClassName, compoundClassName); 32688 } 32689 if ((usedLayout?.inherit || usedLayout?.contentSize || usedLayout?.type === 'constrained') && rootPaddingAlignment) { 32690 layoutClassnames.push('has-global-padding'); 32691 } 32692 if (usedLayout?.orientation) { 32693 layoutClassnames.push(`is-$kebabCase(usedLayout.orientation)}`); 32694 } 32695 if (usedLayout?.justifyContent) { 32696 layoutClassnames.push(`is-content-justification-$kebabCase(usedLayout.justifyContent)}`); 32697 } 32698 if (usedLayout?.flexWrap && usedLayout.flexWrap === 'nowrap') { 32699 layoutClassnames.push('is-nowrap'); 32700 } 32701 return layoutClassnames; 32702 } 32703 32704 /** 32705 * Generates a CSS rule with the given block's layout styles. 32706 * 32707 * @param { Object } blockAttributes Block attributes. 32708 * @param { string } blockName Block name. 32709 * @param { string } selector A selector to use in generating the CSS rule. 32710 * 32711 * @return { string } CSS rule. 32712 */ 32713 function useLayoutStyles(blockAttributes = {}, blockName, selector) { 32714 const { 32715 layout = {}, 32716 style = {} 32717 } = blockAttributes; 32718 // Update type for blocks using legacy layouts. 32719 const usedLayout = layout?.inherit || layout?.contentSize || layout?.wideSize ? { 32720 ...layout, 32721 type: 'constrained' 32722 } : layout || {}; 32723 const fullLayoutType = getLayoutType(usedLayout?.type || 'default'); 32724 const [blockGapSupport] = use_settings_useSettings('spacing.blockGap'); 32725 const hasBlockGapSupport = blockGapSupport !== null; 32726 const css = fullLayoutType?.getLayoutStyle?.({ 32727 blockName, 32728 selector, 32729 layout, 32730 style, 32731 hasBlockGapSupport 32732 }); 32733 return css; 32734 } 32735 function LayoutPanelPure({ 32736 layout, 32737 setAttributes, 32738 name: blockName 32739 }) { 32740 const settings = useBlockSettings(blockName); 32741 // Block settings come from theme.json under settings.[blockName]. 32742 const { 32743 layout: layoutSettings 32744 } = settings; 32745 // Layout comes from block attributes. 32746 const [defaultThemeLayout] = use_settings_useSettings('layout'); 32747 const { 32748 themeSupportsLayout 32749 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 32750 const { 32751 getSettings 32752 } = select(store); 32753 return { 32754 themeSupportsLayout: getSettings().supportsLayout 32755 }; 32756 }, []); 32757 const blockEditingMode = useBlockEditingMode(); 32758 if (blockEditingMode !== 'default') { 32759 return null; 32760 } 32761 32762 // Layout block support comes from the block's block.json. 32763 const layoutBlockSupport = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockName, layoutBlockSupportKey, {}); 32764 const blockSupportAndThemeSettings = { 32765 ...layoutSettings, 32766 ...layoutBlockSupport 32767 }; 32768 const { 32769 allowSwitching, 32770 allowEditing = true, 32771 allowInheriting = true, 32772 default: defaultBlockLayout 32773 } = blockSupportAndThemeSettings; 32774 if (!allowEditing) { 32775 return null; 32776 } 32777 32778 // Only show the inherit toggle if it's supported, 32779 // a default theme layout is set (e.g. one that provides `contentSize` and/or `wideSize` values), 32780 // and either the default / flow or the constrained layout type is in use, as the toggle switches from one to the other. 32781 const showInheritToggle = !!(allowInheriting && !!defaultThemeLayout && (!layout?.type || layout?.type === 'default' || layout?.type === 'constrained' || layout?.inherit)); 32782 const usedLayout = layout || defaultBlockLayout || {}; 32783 const { 32784 inherit = false, 32785 type = 'default', 32786 contentSize = null 32787 } = usedLayout; 32788 /** 32789 * `themeSupportsLayout` is only relevant to the `default/flow` or 32790 * `constrained` layouts and it should not be taken into account when other 32791 * `layout` types are used. 32792 */ 32793 if ((type === 'default' || type === 'constrained') && !themeSupportsLayout) { 32794 return null; 32795 } 32796 const layoutType = getLayoutType(type); 32797 const constrainedType = getLayoutType('constrained'); 32798 const displayControlsForLegacyLayouts = !usedLayout.type && (contentSize || inherit); 32799 const hasContentSizeOrLegacySettings = !!inherit || !!contentSize; 32800 const onChangeType = newType => setAttributes({ 32801 layout: { 32802 type: newType 32803 } 32804 }); 32805 const onChangeLayout = newLayout => setAttributes({ 32806 layout: newLayout 32807 }); 32808 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(inspector_controls, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.PanelBody, { 32809 title: (0,external_wp_i18n_namespaceObject.__)('Layout') 32810 }, showInheritToggle && (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.ToggleControl, { 32811 __nextHasNoMarginBottom: true, 32812 className: "block-editor-hooks__toggle-control", 32813 label: (0,external_wp_i18n_namespaceObject.__)('Inner blocks use content width'), 32814 checked: layoutType?.name === 'constrained' || hasContentSizeOrLegacySettings, 32815 onChange: () => setAttributes({ 32816 layout: { 32817 type: layoutType?.name === 'constrained' || hasContentSizeOrLegacySettings ? 'default' : 'constrained' 32818 } 32819 }), 32820 help: layoutType?.name === 'constrained' || hasContentSizeOrLegacySettings ? (0,external_wp_i18n_namespaceObject.__)('Nested blocks use content width with options for full and wide widths.') : (0,external_wp_i18n_namespaceObject.__)('Nested blocks will fill the width of this container. Toggle to constrain.') 32821 })), !inherit && allowSwitching && (0,external_React_.createElement)(LayoutTypeSwitcher, { 32822 type: type, 32823 onChange: onChangeType 32824 }), layoutType && layoutType.name !== 'default' && (0,external_React_.createElement)(layoutType.inspectorControls, { 32825 layout: usedLayout, 32826 onChange: onChangeLayout, 32827 layoutBlockSupport: blockSupportAndThemeSettings 32828 }), constrainedType && displayControlsForLegacyLayouts && (0,external_React_.createElement)(constrainedType.inspectorControls, { 32829 layout: usedLayout, 32830 onChange: onChangeLayout, 32831 layoutBlockSupport: blockSupportAndThemeSettings 32832 }))), !inherit && layoutType && (0,external_React_.createElement)(layoutType.toolBarControls, { 32833 layout: usedLayout, 32834 onChange: onChangeLayout, 32835 layoutBlockSupport: layoutBlockSupport 32836 })); 32837 } 32838 /* harmony default export */ const layout = ({ 32839 shareWithChildBlocks: true, 32840 edit: LayoutPanelPure, 32841 attributeKeys: ['layout'], 32842 hasSupport(name) { 32843 return hasLayoutBlockSupport(name); 32844 } 32845 }); 32846 function LayoutTypeSwitcher({ 32847 type, 32848 onChange 32849 }) { 32850 return (0,external_React_.createElement)(external_wp_components_namespaceObject.ButtonGroup, null, getLayoutTypes().map(({ 32851 name, 32852 label 32853 }) => { 32854 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 32855 key: name, 32856 isPressed: type === name, 32857 onClick: () => onChange(name) 32858 }, label); 32859 })); 32860 } 32861 32862 /** 32863 * Filters registered block settings, extending attributes to include `layout`. 32864 * 32865 * @param {Object} settings Original block settings. 32866 * 32867 * @return {Object} Filtered block settings. 32868 */ 32869 function layout_addAttribute(settings) { 32870 var _settings$attributes$; 32871 if ('type' in ((_settings$attributes$ = settings.attributes?.layout) !== null && _settings$attributes$ !== void 0 ? _settings$attributes$ : {})) { 32872 return settings; 32873 } 32874 if (hasLayoutBlockSupport(settings)) { 32875 settings.attributes = { 32876 ...settings.attributes, 32877 layout: { 32878 type: 'object' 32879 } 32880 }; 32881 } 32882 return settings; 32883 } 32884 function BlockWithLayoutStyles({ 32885 block: BlockListBlock, 32886 props 32887 }) { 32888 const { 32889 name, 32890 attributes 32891 } = props; 32892 const id = (0,external_wp_compose_namespaceObject.useInstanceId)(BlockListBlock); 32893 const { 32894 layout 32895 } = attributes; 32896 const { 32897 default: defaultBlockLayout 32898 } = (0,external_wp_blocks_namespaceObject.getBlockSupport)(name, layoutBlockSupportKey) || {}; 32899 const usedLayout = layout?.inherit || layout?.contentSize || layout?.wideSize ? { 32900 ...layout, 32901 type: 'constrained' 32902 } : layout || defaultBlockLayout || {}; 32903 const layoutClasses = useLayoutClasses(attributes, name); 32904 const { 32905 kebabCase 32906 } = unlock(external_wp_components_namespaceObject.privateApis); 32907 const selectorPrefix = `wp-container-$kebabCase(name)}-is-layout-`; 32908 // Higher specificity to override defaults from theme.json. 32909 const selector = `.$selectorPrefix}$id}.$selectorPrefix}$id}`; 32910 const [blockGapSupport] = use_settings_useSettings('spacing.blockGap'); 32911 const hasBlockGapSupport = blockGapSupport !== null; 32912 32913 // Get CSS string for the current layout type. 32914 // The CSS and `style` element is only output if it is not empty. 32915 const fullLayoutType = getLayoutType(usedLayout?.type || 'default'); 32916 const css = fullLayoutType?.getLayoutStyle?.({ 32917 blockName: name, 32918 selector, 32919 layout: usedLayout, 32920 style: attributes?.style, 32921 hasBlockGapSupport 32922 }); 32923 32924 // Attach a `wp-container-` id-based class name as well as a layout class name such as `is-layout-flex`. 32925 const layoutClassNames = classnames_default()({ 32926 [`$selectorPrefix}$id}`]: !!css // Only attach a container class if there is generated CSS to be attached. 32927 }, layoutClasses); 32928 useStyleOverride({ 32929 css 32930 }); 32931 return (0,external_React_.createElement)(BlockListBlock, { 32932 ...props, 32933 __unstableLayoutClassNames: layoutClassNames 32934 }); 32935 } 32936 32937 /** 32938 * Override the default block element to add the layout styles. 32939 * 32940 * @param {Function} BlockListBlock Original component. 32941 * 32942 * @return {Function} Wrapped component. 32943 */ 32944 const withLayoutStyles = (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(BlockListBlock => props => { 32945 const blockSupportsLayout = hasLayoutBlockSupport(props.name); 32946 const shouldRenderLayoutStyles = (0,external_wp_data_namespaceObject.useSelect)(select => { 32947 // The callback returns early to avoid block editor subscription. 32948 if (!blockSupportsLayout) { 32949 return false; 32950 } 32951 return !select(store).getSettings().disableLayoutStyles; 32952 }, [blockSupportsLayout]); 32953 if (!shouldRenderLayoutStyles) { 32954 return (0,external_React_.createElement)(BlockListBlock, { 32955 ...props 32956 }); 32957 } 32958 return (0,external_React_.createElement)(BlockWithLayoutStyles, { 32959 block: BlockListBlock, 32960 props: props 32961 }); 32962 }, 'withLayoutStyles'); 32963 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/layout/addAttribute', layout_addAttribute); 32964 (0,external_wp_hooks_namespaceObject.addFilter)('editor.BlockListBlock', 'core/editor/layout/with-layout-styles', withLayoutStyles); 32965 32966 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/layout-child.js 32967 /** 32968 * WordPress dependencies 32969 */ 32970 32971 32972 32973 /** 32974 * Internal dependencies 32975 */ 32976 32977 32978 function useBlockPropsChildLayoutStyles({ 32979 style 32980 }) { 32981 var _style$layout; 32982 const shouldRenderChildLayoutStyles = (0,external_wp_data_namespaceObject.useSelect)(select => { 32983 return !select(store).getSettings().disableLayoutStyles; 32984 }); 32985 const layout = (_style$layout = style?.layout) !== null && _style$layout !== void 0 ? _style$layout : {}; 32986 const { 32987 selfStretch, 32988 flexSize 32989 } = layout; 32990 const id = (0,external_wp_compose_namespaceObject.useInstanceId)(useBlockPropsChildLayoutStyles); 32991 const selector = `.wp-container-content-$id}`; 32992 let css = ''; 32993 if (shouldRenderChildLayoutStyles) { 32994 if (selfStretch === 'fixed' && flexSize) { 32995 css = `$selector} { 32996 flex-basis: $flexSize}; 32997 box-sizing: border-box; 32998 }`; 32999 } else if (selfStretch === 'fill') { 33000 css = `$selector} { 33001 flex-grow: 1; 33002 }`; 33003 } 33004 } 33005 useStyleOverride({ 33006 css 33007 }); 33008 33009 // Only attach a container class if there is generated CSS to be attached. 33010 if (!css) { 33011 return; 33012 } 33013 33014 // Attach a `wp-container-content` id-based classname. 33015 return { 33016 className: `wp-container-content-$id}` 33017 }; 33018 } 33019 /* harmony default export */ const layout_child = ({ 33020 useBlockProps: useBlockPropsChildLayoutStyles, 33021 attributeKeys: ['style'], 33022 hasSupport() { 33023 return true; 33024 } 33025 }); 33026 33027 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/convert-to-group-buttons/use-convert-to-group-button-props.js 33028 /** 33029 * WordPress dependencies 33030 */ 33031 33032 33033 33034 /** 33035 * Internal dependencies 33036 */ 33037 33038 33039 /** 33040 * Contains the properties `ConvertToGroupButton` component needs. 33041 * 33042 * @typedef {Object} ConvertToGroupButtonProps 33043 * @property {string[]} clientIds An array of the selected client ids. 33044 * @property {boolean} isGroupable Indicates if the selected blocks can be grouped. 33045 * @property {boolean} isUngroupable Indicates if the selected blocks can be ungrouped. 33046 * @property {WPBlock[]} blocksSelection An array of the selected blocks. 33047 * @property {string} groupingBlockName The name of block used for handling grouping interactions. 33048 */ 33049 33050 /** 33051 * Returns the properties `ConvertToGroupButton` component needs to work properly. 33052 * It is used in `BlockSettingsMenuControls` to know if `ConvertToGroupButton` 33053 * should be rendered, to avoid ending up with an empty MenuGroup. 33054 * 33055 * @param {?string[]} selectedClientIds An optional array of clientIds to group. The selected blocks 33056 * from the block editor store are used if this is not provided. 33057 * 33058 * @return {ConvertToGroupButtonProps} Returns the properties needed by `ConvertToGroupButton`. 33059 */ 33060 function useConvertToGroupButtonProps(selectedClientIds) { 33061 return (0,external_wp_data_namespaceObject.useSelect)(select => { 33062 const { 33063 getBlocksByClientId, 33064 getSelectedBlockClientIds, 33065 isUngroupable, 33066 isGroupable 33067 } = select(store); 33068 const { 33069 getGroupingBlockName, 33070 getBlockType 33071 } = select(external_wp_blocks_namespaceObject.store); 33072 const clientIds = selectedClientIds?.length ? selectedClientIds : getSelectedBlockClientIds(); 33073 const blocksSelection = getBlocksByClientId(clientIds); 33074 const [firstSelectedBlock] = blocksSelection; 33075 const _isUngroupable = clientIds.length === 1 && isUngroupable(clientIds[0]); 33076 return { 33077 clientIds, 33078 isGroupable: isGroupable(clientIds), 33079 isUngroupable: _isUngroupable, 33080 blocksSelection, 33081 groupingBlockName: getGroupingBlockName(), 33082 onUngroup: _isUngroupable && getBlockType(firstSelectedBlock.name)?.transforms?.ungroup 33083 }; 33084 }, [selectedClientIds]); 33085 } 33086 33087 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/convert-to-group-buttons/index.js 33088 33089 /** 33090 * WordPress dependencies 33091 */ 33092 33093 33094 33095 33096 33097 /** 33098 * Internal dependencies 33099 */ 33100 33101 33102 33103 function ConvertToGroupButton({ 33104 clientIds, 33105 isGroupable, 33106 isUngroupable, 33107 onUngroup, 33108 blocksSelection, 33109 groupingBlockName, 33110 onClose = () => {} 33111 }) { 33112 const { 33113 replaceBlocks 33114 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 33115 const onConvertToGroup = () => { 33116 // Activate the `transform` on the Grouping Block which does the conversion. 33117 const newBlocks = (0,external_wp_blocks_namespaceObject.switchToBlockType)(blocksSelection, groupingBlockName); 33118 if (newBlocks) { 33119 replaceBlocks(clientIds, newBlocks); 33120 } 33121 }; 33122 const onConvertFromGroup = () => { 33123 let innerBlocks = blocksSelection[0].innerBlocks; 33124 if (!innerBlocks.length) { 33125 return; 33126 } 33127 if (onUngroup) { 33128 innerBlocks = onUngroup(blocksSelection[0].attributes, blocksSelection[0].innerBlocks); 33129 } 33130 replaceBlocks(clientIds, innerBlocks); 33131 }; 33132 if (!isGroupable && !isUngroupable) { 33133 return null; 33134 } 33135 return (0,external_React_.createElement)(external_React_.Fragment, null, isGroupable && (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 33136 onClick: () => { 33137 onConvertToGroup(); 33138 onClose(); 33139 } 33140 }, (0,external_wp_i18n_namespaceObject._x)('Group', 'verb')), isUngroupable && (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 33141 onClick: () => { 33142 onConvertFromGroup(); 33143 onClose(); 33144 } 33145 }, (0,external_wp_i18n_namespaceObject._x)('Ungroup', 'Ungrouping blocks from within a grouping block back into individual blocks within the Editor '))); 33146 } 33147 33148 33149 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-lock/use-block-lock.js 33150 /** 33151 * WordPress dependencies 33152 */ 33153 33154 33155 /** 33156 * Internal dependencies 33157 */ 33158 33159 33160 /** 33161 * Return details about the block lock status. 33162 * 33163 * @param {string} clientId The block client Id. 33164 * 33165 * @return {Object} Block lock status 33166 */ 33167 function useBlockLock(clientId) { 33168 return (0,external_wp_data_namespaceObject.useSelect)(select => { 33169 const { 33170 canEditBlock, 33171 canMoveBlock, 33172 canRemoveBlock, 33173 canLockBlockType, 33174 getBlockName, 33175 getBlockRootClientId, 33176 getTemplateLock 33177 } = select(store); 33178 const rootClientId = getBlockRootClientId(clientId); 33179 const canEdit = canEditBlock(clientId); 33180 const canMove = canMoveBlock(clientId, rootClientId); 33181 const canRemove = canRemoveBlock(clientId, rootClientId); 33182 return { 33183 canEdit, 33184 canMove, 33185 canRemove, 33186 canLock: canLockBlockType(getBlockName(clientId)), 33187 isContentLocked: getTemplateLock(clientId) === 'contentOnly', 33188 isLocked: !canEdit || !canMove || !canRemove 33189 }; 33190 }, [clientId]); 33191 } 33192 33193 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/unlock.js 33194 33195 /** 33196 * WordPress dependencies 33197 */ 33198 33199 const unlock_unlock = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 33200 viewBox: "0 0 24 24", 33201 xmlns: "http://www.w3.org/2000/svg" 33202 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 33203 d: "M17 10h-1.2V7c0-2.1-1.7-3.8-3.8-3.8-2.1 0-3.8 1.7-3.8 3.8h1.5c0-1.2 1-2.2 2.2-2.2s2.2 1 2.2 2.2v3H7c-.6 0-1 .4-1 1v8c0 .6.4 1 1 1h10c.6 0 1-.4 1-1v-8c0-.6-.4-1-1-1z" 33204 })); 33205 /* harmony default export */ const library_unlock = (unlock_unlock); 33206 33207 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/lock-outline.js 33208 33209 /** 33210 * WordPress dependencies 33211 */ 33212 33213 const lockOutline = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 33214 viewBox: "0 0 24 24", 33215 xmlns: "http://www.w3.org/2000/svg" 33216 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 33217 d: "M17 10h-1.2V7c0-2.1-1.7-3.8-3.8-3.8-2.1 0-3.8 1.7-3.8 3.8v3H7c-.6 0-1 .4-1 1v8c0 .6.4 1 1 1h10c.6 0 1-.4 1-1v-8c0-.6-.4-1-1-1zM9.8 7c0-1.2 1-2.2 2.2-2.2 1.2 0 2.2 1 2.2 2.2v3H9.8V7zm6.7 11.5h-9v-7h9v7z" 33218 })); 33219 /* harmony default export */ const lock_outline = (lockOutline); 33220 33221 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/lock.js 33222 33223 /** 33224 * WordPress dependencies 33225 */ 33226 33227 const lock_lock = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 33228 viewBox: "0 0 24 24", 33229 xmlns: "http://www.w3.org/2000/svg" 33230 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 33231 d: "M17 10h-1.2V7c0-2.1-1.7-3.8-3.8-3.8-2.1 0-3.8 1.7-3.8 3.8v3H7c-.6 0-1 .4-1 1v8c0 .6.4 1 1 1h10c.6 0 1-.4 1-1v-8c0-.6-.4-1-1-1zm-2.8 0H9.8V7c0-1.2 1-2.2 2.2-2.2s2.2 1 2.2 2.2v3z" 33232 })); 33233 /* harmony default export */ const library_lock = (lock_lock); 33234 33235 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-lock/modal.js 33236 33237 /** 33238 * WordPress dependencies 33239 */ 33240 33241 33242 33243 33244 33245 33246 33247 33248 /** 33249 * Internal dependencies 33250 */ 33251 33252 33253 33254 33255 // Entity based blocks which allow edit locking 33256 const ALLOWS_EDIT_LOCKING = ['core/block', 'core/navigation']; 33257 function getTemplateLockValue(lock) { 33258 // Prevents all operations. 33259 if (lock.remove && lock.move) { 33260 return 'all'; 33261 } 33262 33263 // Prevents inserting or removing blocks, but allows moving existing blocks. 33264 if (lock.remove && !lock.move) { 33265 return 'insert'; 33266 } 33267 return false; 33268 } 33269 function BlockLockModal({ 33270 clientId, 33271 onClose 33272 }) { 33273 const [lock, setLock] = (0,external_wp_element_namespaceObject.useState)({ 33274 move: false, 33275 remove: false 33276 }); 33277 const { 33278 canEdit, 33279 canMove, 33280 canRemove 33281 } = useBlockLock(clientId); 33282 const { 33283 allowsEditLocking, 33284 templateLock, 33285 hasTemplateLock 33286 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 33287 const { 33288 getBlockName, 33289 getBlockAttributes 33290 } = select(store); 33291 const blockName = getBlockName(clientId); 33292 const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockName); 33293 return { 33294 allowsEditLocking: ALLOWS_EDIT_LOCKING.includes(blockName), 33295 templateLock: getBlockAttributes(clientId)?.templateLock, 33296 hasTemplateLock: !!blockType?.attributes?.templateLock 33297 }; 33298 }, [clientId]); 33299 const [applyTemplateLock, setApplyTemplateLock] = (0,external_wp_element_namespaceObject.useState)(!!templateLock); 33300 const { 33301 updateBlockAttributes 33302 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 33303 const blockInformation = useBlockDisplayInformation(clientId); 33304 const instanceId = (0,external_wp_compose_namespaceObject.useInstanceId)(BlockLockModal, 'block-editor-block-lock-modal__options-title'); 33305 (0,external_wp_element_namespaceObject.useEffect)(() => { 33306 setLock({ 33307 move: !canMove, 33308 remove: !canRemove, 33309 ...(allowsEditLocking ? { 33310 edit: !canEdit 33311 } : {}) 33312 }); 33313 }, [canEdit, canMove, canRemove, allowsEditLocking]); 33314 const isAllChecked = Object.values(lock).every(Boolean); 33315 const isMixed = Object.values(lock).some(Boolean) && !isAllChecked; 33316 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Modal, { 33317 title: (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: Name of the block. */ 33318 (0,external_wp_i18n_namespaceObject.__)('Lock %s'), blockInformation.title), 33319 overlayClassName: "block-editor-block-lock-modal", 33320 onRequestClose: onClose 33321 }, (0,external_React_.createElement)("p", null, (0,external_wp_i18n_namespaceObject.__)('Choose specific attributes to restrict or lock all available options.')), (0,external_React_.createElement)("form", { 33322 onSubmit: event => { 33323 event.preventDefault(); 33324 updateBlockAttributes([clientId], { 33325 lock, 33326 templateLock: applyTemplateLock ? getTemplateLockValue(lock) : undefined 33327 }); 33328 onClose(); 33329 } 33330 }, (0,external_React_.createElement)("div", { 33331 role: "group", 33332 "aria-labelledby": instanceId, 33333 className: "block-editor-block-lock-modal__options" 33334 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.CheckboxControl, { 33335 __nextHasNoMarginBottom: true, 33336 className: "block-editor-block-lock-modal__options-title", 33337 label: (0,external_React_.createElement)("span", { 33338 id: instanceId 33339 }, (0,external_wp_i18n_namespaceObject.__)('Lock all')), 33340 checked: isAllChecked, 33341 indeterminate: isMixed, 33342 onChange: newValue => setLock({ 33343 move: newValue, 33344 remove: newValue, 33345 ...(allowsEditLocking ? { 33346 edit: newValue 33347 } : {}) 33348 }) 33349 }), (0,external_React_.createElement)("ul", { 33350 className: "block-editor-block-lock-modal__checklist" 33351 }, allowsEditLocking && (0,external_React_.createElement)("li", { 33352 className: "block-editor-block-lock-modal__checklist-item" 33353 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.CheckboxControl, { 33354 __nextHasNoMarginBottom: true, 33355 label: (0,external_wp_i18n_namespaceObject.__)('Restrict editing'), 33356 checked: !!lock.edit, 33357 onChange: edit => setLock(prevLock => ({ 33358 ...prevLock, 33359 edit 33360 })) 33361 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.Icon, { 33362 className: "block-editor-block-lock-modal__lock-icon", 33363 icon: lock.edit ? library_lock : library_unlock 33364 })), (0,external_React_.createElement)("li", { 33365 className: "block-editor-block-lock-modal__checklist-item" 33366 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.CheckboxControl, { 33367 __nextHasNoMarginBottom: true, 33368 label: (0,external_wp_i18n_namespaceObject.__)('Disable movement'), 33369 checked: lock.move, 33370 onChange: move => setLock(prevLock => ({ 33371 ...prevLock, 33372 move 33373 })) 33374 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.Icon, { 33375 className: "block-editor-block-lock-modal__lock-icon", 33376 icon: lock.move ? library_lock : library_unlock 33377 })), (0,external_React_.createElement)("li", { 33378 className: "block-editor-block-lock-modal__checklist-item" 33379 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.CheckboxControl, { 33380 __nextHasNoMarginBottom: true, 33381 label: (0,external_wp_i18n_namespaceObject.__)('Prevent removal'), 33382 checked: lock.remove, 33383 onChange: remove => setLock(prevLock => ({ 33384 ...prevLock, 33385 remove 33386 })) 33387 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.Icon, { 33388 className: "block-editor-block-lock-modal__lock-icon", 33389 icon: lock.remove ? library_lock : library_unlock 33390 }))), hasTemplateLock && (0,external_React_.createElement)(external_wp_components_namespaceObject.ToggleControl, { 33391 __nextHasNoMarginBottom: true, 33392 className: "block-editor-block-lock-modal__template-lock", 33393 label: (0,external_wp_i18n_namespaceObject.__)('Apply to all blocks inside'), 33394 checked: applyTemplateLock, 33395 disabled: lock.move && !lock.remove, 33396 onChange: () => setApplyTemplateLock(!applyTemplateLock) 33397 })), (0,external_React_.createElement)(external_wp_components_namespaceObject.Flex, { 33398 className: "block-editor-block-lock-modal__actions", 33399 justify: "flex-end", 33400 expanded: false 33401 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexItem, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 33402 variant: "tertiary", 33403 onClick: onClose 33404 }, (0,external_wp_i18n_namespaceObject.__)('Cancel'))), (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexItem, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 33405 variant: "primary", 33406 type: "submit" 33407 }, (0,external_wp_i18n_namespaceObject.__)('Apply')))))); 33408 } 33409 33410 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-lock/menu-item.js 33411 33412 /** 33413 * WordPress dependencies 33414 */ 33415 33416 33417 33418 33419 33420 /** 33421 * Internal dependencies 33422 */ 33423 33424 33425 function BlockLockMenuItem({ 33426 clientId 33427 }) { 33428 const { 33429 canLock, 33430 isLocked 33431 } = useBlockLock(clientId); 33432 const [isModalOpen, toggleModal] = (0,external_wp_element_namespaceObject.useReducer)(isActive => !isActive, false); 33433 if (!canLock) { 33434 return null; 33435 } 33436 const label = isLocked ? (0,external_wp_i18n_namespaceObject.__)('Unlock') : (0,external_wp_i18n_namespaceObject.__)('Lock'); 33437 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 33438 icon: isLocked ? library_unlock : lock_outline, 33439 onClick: toggleModal, 33440 "aria-expanded": isModalOpen, 33441 "aria-haspopup": "dialog" 33442 }, label), isModalOpen && (0,external_React_.createElement)(BlockLockModal, { 33443 clientId: clientId, 33444 onClose: toggleModal 33445 })); 33446 } 33447 33448 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-settings-menu/block-mode-toggle.js 33449 33450 /** 33451 * WordPress dependencies 33452 */ 33453 33454 33455 33456 33457 33458 33459 /** 33460 * Internal dependencies 33461 */ 33462 33463 const block_mode_toggle_noop = () => {}; 33464 function BlockModeToggle({ 33465 blockType, 33466 mode, 33467 onToggleMode, 33468 small = false, 33469 isCodeEditingEnabled = true 33470 }) { 33471 if (!blockType || !(0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, 'html', true) || !isCodeEditingEnabled) { 33472 return null; 33473 } 33474 const label = mode === 'visual' ? (0,external_wp_i18n_namespaceObject.__)('Edit as HTML') : (0,external_wp_i18n_namespaceObject.__)('Edit visually'); 33475 return (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 33476 onClick: onToggleMode 33477 }, !small && label); 33478 } 33479 /* harmony default export */ const block_mode_toggle = ((0,external_wp_compose_namespaceObject.compose)([(0,external_wp_data_namespaceObject.withSelect)((select, { 33480 clientId 33481 }) => { 33482 const { 33483 getBlock, 33484 getBlockMode, 33485 getSettings 33486 } = select(store); 33487 const block = getBlock(clientId); 33488 const isCodeEditingEnabled = getSettings().codeEditingEnabled; 33489 return { 33490 mode: getBlockMode(clientId), 33491 blockType: block ? (0,external_wp_blocks_namespaceObject.getBlockType)(block.name) : null, 33492 isCodeEditingEnabled 33493 }; 33494 }), (0,external_wp_data_namespaceObject.withDispatch)((dispatch, { 33495 onToggle = block_mode_toggle_noop, 33496 clientId 33497 }) => ({ 33498 onToggleMode() { 33499 dispatch(store).toggleBlockMode(clientId); 33500 onToggle(); 33501 } 33502 }))])(BlockModeToggle)); 33503 33504 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-rename/use-block-rename.js 33505 /** 33506 * WordPress dependencies 33507 */ 33508 33509 function useBlockRename(name) { 33510 return { 33511 canRename: (0,external_wp_blocks_namespaceObject.getBlockSupport)(name, 'renaming', true) 33512 }; 33513 } 33514 33515 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-rename/is-empty-string.js 33516 function isEmptyString(testString) { 33517 return testString?.trim()?.length === 0; 33518 } 33519 33520 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-rename/modal.js 33521 33522 /** 33523 * WordPress dependencies 33524 */ 33525 33526 33527 33528 33529 33530 33531 /** 33532 * Internal dependencies 33533 */ 33534 33535 function BlockRenameModal({ 33536 blockName, 33537 originalBlockName, 33538 onClose, 33539 onSave 33540 }) { 33541 const [editedBlockName, setEditedBlockName] = (0,external_wp_element_namespaceObject.useState)(blockName); 33542 const nameHasChanged = editedBlockName !== blockName; 33543 const nameIsOriginal = editedBlockName === originalBlockName; 33544 const nameIsEmpty = isEmptyString(editedBlockName); 33545 const isNameValid = nameHasChanged || nameIsOriginal; 33546 const autoSelectInputText = event => event.target.select(); 33547 const dialogDescription = (0,external_wp_compose_namespaceObject.useInstanceId)(BlockRenameModal, `block-editor-rename-modal__description`); 33548 const handleSubmit = () => { 33549 const message = nameIsOriginal || nameIsEmpty ? (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: new name/label for the block */ 33550 (0,external_wp_i18n_namespaceObject.__)('Block name reset to: "%s".'), editedBlockName) : (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: new name/label for the block */ 33551 (0,external_wp_i18n_namespaceObject.__)('Block name changed to: "%s".'), editedBlockName); 33552 33553 // Must be assertive to immediately announce change. 33554 (0,external_wp_a11y_namespaceObject.speak)(message, 'assertive'); 33555 onSave(editedBlockName); 33556 33557 // Immediate close avoids ability to hit save multiple times. 33558 onClose(); 33559 }; 33560 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Modal, { 33561 title: (0,external_wp_i18n_namespaceObject.__)('Rename'), 33562 onRequestClose: onClose, 33563 overlayClassName: "block-editor-block-rename-modal", 33564 aria: { 33565 describedby: dialogDescription 33566 }, 33567 focusOnMount: "firstContentElement" 33568 }, (0,external_React_.createElement)("p", { 33569 id: dialogDescription 33570 }, (0,external_wp_i18n_namespaceObject.__)('Enter a custom name for this block.')), (0,external_React_.createElement)("form", { 33571 onSubmit: e => { 33572 e.preventDefault(); 33573 if (!isNameValid) { 33574 return; 33575 } 33576 handleSubmit(); 33577 } 33578 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalVStack, { 33579 spacing: "3" 33580 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.TextControl, { 33581 __nextHasNoMarginBottom: true, 33582 __next40pxDefaultSize: true, 33583 value: editedBlockName, 33584 label: (0,external_wp_i18n_namespaceObject.__)('Block name'), 33585 hideLabelFromVision: true, 33586 placeholder: originalBlockName, 33587 onChange: setEditedBlockName, 33588 onFocus: autoSelectInputText 33589 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, { 33590 justify: "right" 33591 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 33592 __next40pxDefaultSize: true, 33593 variant: "tertiary", 33594 onClick: onClose 33595 }, (0,external_wp_i18n_namespaceObject.__)('Cancel')), (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 33596 __next40pxDefaultSize: true, 33597 "aria-disabled": !isNameValid, 33598 variant: "primary", 33599 type: "submit" 33600 }, (0,external_wp_i18n_namespaceObject.__)('Save')))))); 33601 } 33602 33603 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-rename/rename-control.js 33604 33605 /** 33606 * WordPress dependencies 33607 */ 33608 33609 33610 33611 33612 33613 /** 33614 * Internal dependencies 33615 */ 33616 33617 33618 33619 33620 function BlockRenameControl({ 33621 clientId 33622 }) { 33623 const [renamingBlock, setRenamingBlock] = (0,external_wp_element_namespaceObject.useState)(false); 33624 const { 33625 metadata 33626 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 33627 const { 33628 getBlockAttributes 33629 } = select(store); 33630 const _metadata = getBlockAttributes(clientId)?.metadata; 33631 return { 33632 metadata: _metadata 33633 }; 33634 }, [clientId]); 33635 const { 33636 updateBlockAttributes 33637 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 33638 const customName = metadata?.name; 33639 function onChange(newName) { 33640 updateBlockAttributes([clientId], { 33641 metadata: { 33642 ...(metadata && metadata), 33643 name: newName 33644 } 33645 }); 33646 } 33647 const blockInformation = useBlockDisplayInformation(clientId); 33648 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 33649 onClick: () => { 33650 setRenamingBlock(true); 33651 }, 33652 "aria-expanded": renamingBlock, 33653 "aria-haspopup": "dialog" 33654 }, (0,external_wp_i18n_namespaceObject.__)('Rename')), renamingBlock && (0,external_React_.createElement)(BlockRenameModal, { 33655 blockName: customName || '', 33656 originalBlockName: blockInformation?.title, 33657 onClose: () => setRenamingBlock(false), 33658 onSave: newName => { 33659 // If the new value is the block's original name (e.g. `Group`) 33660 // or it is an empty string then assume the intent is to reset 33661 // the value. Therefore reset the metadata. 33662 if (newName === blockInformation?.title || isEmptyString(newName)) { 33663 newName = undefined; 33664 } 33665 onChange(newName); 33666 } 33667 })); 33668 } 33669 33670 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-settings-menu-controls/index.js 33671 33672 /** 33673 * WordPress dependencies 33674 */ 33675 33676 33677 33678 33679 33680 /** 33681 * Internal dependencies 33682 */ 33683 33684 33685 33686 33687 33688 const { 33689 Fill, 33690 Slot 33691 } = (0,external_wp_components_namespaceObject.createSlotFill)('BlockSettingsMenuControls'); 33692 const BlockSettingsMenuControlsSlot = ({ 33693 fillProps, 33694 clientIds = null, 33695 __unstableDisplayLocation 33696 }) => { 33697 const { 33698 selectedBlocks, 33699 selectedClientIds 33700 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 33701 const { 33702 getBlockNamesByClientId, 33703 getSelectedBlockClientIds 33704 } = select(store); 33705 const ids = clientIds !== null ? clientIds : getSelectedBlockClientIds(); 33706 return { 33707 selectedBlocks: getBlockNamesByClientId(ids), 33708 selectedClientIds: ids 33709 }; 33710 }, [clientIds]); 33711 const { 33712 canLock 33713 } = useBlockLock(selectedClientIds[0]); 33714 const { 33715 canRename 33716 } = useBlockRename(selectedBlocks[0]); 33717 const showLockButton = selectedClientIds.length === 1 && canLock; 33718 const showRenameButton = selectedClientIds.length === 1 && canRename; 33719 33720 // Check if current selection of blocks is Groupable or Ungroupable 33721 // and pass this props down to ConvertToGroupButton. 33722 const convertToGroupButtonProps = useConvertToGroupButtonProps(selectedClientIds); 33723 const { 33724 isGroupable, 33725 isUngroupable 33726 } = convertToGroupButtonProps; 33727 const showConvertToGroupButton = isGroupable || isUngroupable; 33728 return (0,external_React_.createElement)(Slot, { 33729 fillProps: { 33730 ...fillProps, 33731 __unstableDisplayLocation, 33732 selectedBlocks, 33733 selectedClientIds 33734 } 33735 }, fills => { 33736 if (!fills?.length > 0 && !showConvertToGroupButton && !showLockButton) { 33737 return null; 33738 } 33739 return (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuGroup, null, showConvertToGroupButton && (0,external_React_.createElement)(ConvertToGroupButton, { 33740 ...convertToGroupButtonProps, 33741 onClose: fillProps?.onClose 33742 }), showLockButton && (0,external_React_.createElement)(BlockLockMenuItem, { 33743 clientId: selectedClientIds[0] 33744 }), showRenameButton && (0,external_React_.createElement)(BlockRenameControl, { 33745 clientId: selectedClientIds[0] 33746 }), fills, fillProps?.canMove && !fillProps?.onlyBlock && (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 33747 onClick: (0,external_wp_compose_namespaceObject.pipe)(fillProps?.onClose, fillProps?.onMoveTo) 33748 }, (0,external_wp_i18n_namespaceObject.__)('Move to')), fillProps?.count === 1 && (0,external_React_.createElement)(block_mode_toggle, { 33749 clientId: fillProps?.firstBlockClientId, 33750 onToggle: fillProps?.onClose 33751 })); 33752 }); 33753 }; 33754 33755 /** 33756 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-settings-menu-controls/README.md 33757 * 33758 * @param {Object} props Fill props. 33759 * @return {Element} Element. 33760 */ 33761 function BlockSettingsMenuControls({ 33762 ...props 33763 }) { 33764 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalStyleProvider, { 33765 document: document 33766 }, (0,external_React_.createElement)(Fill, { 33767 ...props 33768 })); 33769 } 33770 BlockSettingsMenuControls.Slot = BlockSettingsMenuControlsSlot; 33771 /* harmony default export */ const block_settings_menu_controls = (BlockSettingsMenuControls); 33772 33773 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/content-lock-ui.js 33774 33775 /** 33776 * WordPress dependencies 33777 */ 33778 33779 33780 33781 33782 33783 /** 33784 * Internal dependencies 33785 */ 33786 33787 33788 33789 33790 // The implementation of content locking is mainly in this file, although the mechanism 33791 // to stop temporarily editing as blocks when an outside block is selected is on component StopEditingAsBlocksOnOutsideSelect 33792 // at block-editor/src/components/block-list/index.js. 33793 // Besides the components on this file and the file referenced above the implementation 33794 // also includes artifacts on the store (actions, reducers, and selector). 33795 33796 function ContentLockControlsPure({ 33797 clientId, 33798 isSelected 33799 }) { 33800 const { 33801 getBlockListSettings, 33802 getSettings 33803 } = (0,external_wp_data_namespaceObject.useSelect)(store); 33804 const { 33805 templateLock, 33806 isLockedByParent, 33807 isEditingAsBlocks 33808 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 33809 const { 33810 __unstableGetContentLockingParent, 33811 getTemplateLock, 33812 __unstableGetTemporarilyEditingAsBlocks 33813 } = select(store); 33814 return { 33815 templateLock: getTemplateLock(clientId), 33816 isLockedByParent: !!__unstableGetContentLockingParent(clientId), 33817 isEditingAsBlocks: __unstableGetTemporarilyEditingAsBlocks() === clientId 33818 }; 33819 }, [clientId]); 33820 const { 33821 updateSettings, 33822 updateBlockListSettings, 33823 __unstableSetTemporarilyEditingAsBlocks 33824 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 33825 const { 33826 stopEditingAsBlocks 33827 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store)); 33828 const isContentLocked = !isLockedByParent && templateLock === 'contentOnly'; 33829 const { 33830 __unstableMarkNextChangeAsNotPersistent, 33831 updateBlockAttributes 33832 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 33833 const stopEditingAsBlockCallback = (0,external_wp_element_namespaceObject.useCallback)(() => { 33834 stopEditingAsBlocks(clientId); 33835 }, [clientId, stopEditingAsBlocks]); 33836 if (!isContentLocked && !isEditingAsBlocks) { 33837 return null; 33838 } 33839 const showStopEditingAsBlocks = isEditingAsBlocks && !isContentLocked; 33840 const showStartEditingAsBlocks = !isEditingAsBlocks && isContentLocked && isSelected; 33841 return (0,external_React_.createElement)(external_React_.Fragment, null, showStopEditingAsBlocks && (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(block_controls, { 33842 group: "other" 33843 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarButton, { 33844 onClick: stopEditingAsBlockCallback 33845 }, (0,external_wp_i18n_namespaceObject.__)('Done')))), showStartEditingAsBlocks && (0,external_React_.createElement)(block_settings_menu_controls, null, ({ 33846 onClose 33847 }) => (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 33848 onClick: () => { 33849 __unstableMarkNextChangeAsNotPersistent(); 33850 updateBlockAttributes(clientId, { 33851 templateLock: undefined 33852 }); 33853 updateBlockListSettings(clientId, { 33854 ...getBlockListSettings(clientId), 33855 templateLock: false 33856 }); 33857 const focusModeToRevert = getSettings().focusMode; 33858 updateSettings({ 33859 focusMode: true 33860 }); 33861 __unstableSetTemporarilyEditingAsBlocks(clientId, focusModeToRevert); 33862 onClose(); 33863 } 33864 }, (0,external_wp_i18n_namespaceObject.__)('Modify')))); 33865 } 33866 /* harmony default export */ const content_lock_ui = ({ 33867 edit: ContentLockControlsPure, 33868 hasSupport() { 33869 return true; 33870 } 33871 }); 33872 33873 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/metadata.js 33874 /** 33875 * WordPress dependencies 33876 */ 33877 33878 const META_ATTRIBUTE_NAME = 'metadata'; 33879 33880 /** 33881 * Filters registered block settings, extending attributes to include `metadata`. 33882 * 33883 * see: https://github.com/WordPress/gutenberg/pull/40393/files#r864632012 33884 * 33885 * @param {Object} blockTypeSettings Original block settings. 33886 * @return {Object} Filtered block settings. 33887 */ 33888 function addMetaAttribute(blockTypeSettings) { 33889 // Allow blocks to specify their own attribute definition with default values if needed. 33890 if (blockTypeSettings?.attributes?.[META_ATTRIBUTE_NAME]?.type) { 33891 return blockTypeSettings; 33892 } 33893 blockTypeSettings.attributes = { 33894 ...blockTypeSettings.attributes, 33895 [META_ATTRIBUTE_NAME]: { 33896 type: 'object' 33897 } 33898 }; 33899 return blockTypeSettings; 33900 } 33901 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/metadata/addMetaAttribute', addMetaAttribute); 33902 33903 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/block-default.js 33904 33905 /** 33906 * WordPress dependencies 33907 */ 33908 33909 const blockDefault = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 33910 xmlns: "http://www.w3.org/2000/svg", 33911 viewBox: "0 0 24 24" 33912 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 33913 d: "M19 8h-1V6h-5v2h-2V6H6v2H5c-1.1 0-2 .9-2 2v8c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-8c0-1.1-.9-2-2-2zm.5 10c0 .3-.2.5-.5.5H5c-.3 0-.5-.2-.5-.5v-8c0-.3.2-.5.5-.5h14c.3 0 .5.2.5.5v8z" 33914 })); 33915 /* harmony default export */ const block_default = (blockDefault); 33916 33917 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-icon/index.js 33918 33919 /** 33920 * External dependencies 33921 */ 33922 33923 33924 /** 33925 * WordPress dependencies 33926 */ 33927 33928 33929 33930 function BlockIcon({ 33931 icon, 33932 showColors = false, 33933 className, 33934 context 33935 }) { 33936 if (icon?.src === 'block-default') { 33937 icon = { 33938 src: block_default 33939 }; 33940 } 33941 const renderedIcon = (0,external_React_.createElement)(external_wp_components_namespaceObject.Icon, { 33942 icon: icon && icon.src ? icon.src : icon, 33943 context: context 33944 }); 33945 const style = showColors ? { 33946 backgroundColor: icon && icon.background, 33947 color: icon && icon.foreground 33948 } : {}; 33949 return (0,external_React_.createElement)("span", { 33950 style: style, 33951 className: classnames_default()('block-editor-block-icon', className, { 33952 'has-colors': showColors 33953 }) 33954 }, renderedIcon); 33955 } 33956 33957 /** 33958 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-icon/README.md 33959 */ 33960 /* harmony default export */ const block_icon = ((0,external_wp_element_namespaceObject.memo)(BlockIcon)); 33961 33962 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/block-hooks.js 33963 33964 /** 33965 * WordPress dependencies 33966 */ 33967 33968 33969 33970 33971 33972 33973 /** 33974 * Internal dependencies 33975 */ 33976 33977 33978 const EMPTY_OBJECT = {}; 33979 function BlockHooksControlPure({ 33980 name, 33981 clientId, 33982 metadata: { 33983 ignoredHookedBlocks = [] 33984 } = {} 33985 }) { 33986 const blockTypes = (0,external_wp_data_namespaceObject.useSelect)(select => select(external_wp_blocks_namespaceObject.store).getBlockTypes(), []); 33987 33988 // A hooked block added via a filter will not be exposed through a block 33989 // type's `blockHooks` property; however, if the containing layout has been 33990 // modified, it will be present in the anchor block's `ignoredHookedBlocks` 33991 // metadata. 33992 const hookedBlocksForCurrentBlock = (0,external_wp_element_namespaceObject.useMemo)(() => blockTypes?.filter(({ 33993 name: blockName, 33994 blockHooks 33995 }) => blockHooks && name in blockHooks || ignoredHookedBlocks.includes(blockName)), [blockTypes, name, ignoredHookedBlocks]); 33996 const { 33997 blockIndex, 33998 rootClientId, 33999 innerBlocksLength 34000 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 34001 const { 34002 getBlocks, 34003 getBlockIndex, 34004 getBlockRootClientId 34005 } = select(store); 34006 return { 34007 blockIndex: getBlockIndex(clientId), 34008 innerBlocksLength: getBlocks(clientId)?.length, 34009 rootClientId: getBlockRootClientId(clientId) 34010 }; 34011 }, [clientId]); 34012 const hookedBlockClientIds = (0,external_wp_data_namespaceObject.useSelect)(select => { 34013 const { 34014 getBlocks, 34015 getGlobalBlockCount 34016 } = select(store); 34017 const _hookedBlockClientIds = hookedBlocksForCurrentBlock.reduce((clientIds, block) => { 34018 // If the block doesn't exist anywhere in the block tree, 34019 // we know that we have to set the toggle to disabled. 34020 if (getGlobalBlockCount(block.name) === 0) { 34021 return clientIds; 34022 } 34023 const relativePosition = block?.blockHooks?.[name]; 34024 let candidates; 34025 switch (relativePosition) { 34026 case 'before': 34027 case 'after': 34028 // Any of the current block's siblings (with the right block type) qualifies 34029 // as a hooked block (inserted `before` or `after` the current one), as the block 34030 // might've been automatically inserted and then moved around a bit by the user. 34031 candidates = getBlocks(rootClientId); 34032 break; 34033 case 'first_child': 34034 case 'last_child': 34035 // Any of the current block's child blocks (with the right block type) qualifies 34036 // as a hooked first or last child block, as the block might've been automatically 34037 // inserted and then moved around a bit by the user. 34038 candidates = getBlocks(clientId); 34039 break; 34040 case undefined: 34041 // If we haven't found a blockHooks field with a relative position for the hooked 34042 // block, it means that it was added by a filter. In this case, we look for the block 34043 // both among the current block's siblings and its children. 34044 candidates = [...getBlocks(rootClientId), ...getBlocks(clientId)]; 34045 break; 34046 } 34047 const hookedBlock = candidates?.find(candidate => candidate.name === block.name); 34048 34049 // If the block exists in the designated location, we consider it hooked 34050 // and show the toggle as enabled. 34051 if (hookedBlock) { 34052 return { 34053 ...clientIds, 34054 [block.name]: hookedBlock.clientId 34055 }; 34056 } 34057 34058 // If no hooked block was found in any of its designated locations, 34059 // we set the toggle to disabled. 34060 return clientIds; 34061 }, {}); 34062 if (Object.values(_hookedBlockClientIds).length > 0) { 34063 return _hookedBlockClientIds; 34064 } 34065 return EMPTY_OBJECT; 34066 }, [hookedBlocksForCurrentBlock, name, clientId, rootClientId]); 34067 const { 34068 insertBlock, 34069 removeBlock 34070 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 34071 if (!hookedBlocksForCurrentBlock.length) { 34072 return null; 34073 } 34074 34075 // Group by block namespace (i.e. prefix before the slash). 34076 const groupedHookedBlocks = hookedBlocksForCurrentBlock.reduce((groups, block) => { 34077 const [namespace] = block.name.split('/'); 34078 if (!groups[namespace]) { 34079 groups[namespace] = []; 34080 } 34081 groups[namespace].push(block); 34082 return groups; 34083 }, {}); 34084 const insertBlockIntoDesignatedLocation = (block, relativePosition) => { 34085 switch (relativePosition) { 34086 case 'before': 34087 case 'after': 34088 insertBlock(block, relativePosition === 'after' ? blockIndex + 1 : blockIndex, rootClientId, 34089 // Insert as a child of the current block's parent 34090 false); 34091 break; 34092 case 'first_child': 34093 case 'last_child': 34094 insertBlock(block, 34095 // TODO: It'd be great if insertBlock() would accept negative indices for insertion. 34096 relativePosition === 'first_child' ? 0 : innerBlocksLength, clientId, 34097 // Insert as a child of the current block. 34098 false); 34099 break; 34100 case undefined: 34101 // If we do not know the relative position, it is because the block was 34102 // added via a filter. In this case, we default to inserting it after the 34103 // current block. 34104 insertBlock(block, blockIndex + 1, rootClientId, 34105 // Insert as a child of the current block's parent 34106 false); 34107 break; 34108 } 34109 }; 34110 return (0,external_React_.createElement)(inspector_controls, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.PanelBody, { 34111 className: "block-editor-hooks__block-hooks", 34112 title: (0,external_wp_i18n_namespaceObject.__)('Plugins'), 34113 initialOpen: true 34114 }, (0,external_React_.createElement)("p", { 34115 className: "block-editor-hooks__block-hooks-helptext" 34116 }, (0,external_wp_i18n_namespaceObject.__)('Manage the inclusion of blocks added automatically by plugins.')), Object.keys(groupedHookedBlocks).map(vendor => { 34117 return (0,external_React_.createElement)(external_wp_element_namespaceObject.Fragment, { 34118 key: vendor 34119 }, (0,external_React_.createElement)("h3", null, vendor), groupedHookedBlocks[vendor].map(block => { 34120 const checked = (block.name in hookedBlockClientIds); 34121 return (0,external_React_.createElement)(external_wp_components_namespaceObject.ToggleControl, { 34122 checked: checked, 34123 key: block.title, 34124 label: (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, { 34125 justify: "flex-start" 34126 }, (0,external_React_.createElement)(block_icon, { 34127 icon: block.icon 34128 }), (0,external_React_.createElement)("span", null, block.title)), 34129 onChange: () => { 34130 if (!checked) { 34131 // Create and insert block. 34132 const relativePosition = block.blockHooks[name]; 34133 insertBlockIntoDesignatedLocation((0,external_wp_blocks_namespaceObject.createBlock)(block.name), relativePosition); 34134 return; 34135 } 34136 34137 // Remove block. 34138 removeBlock(hookedBlockClientIds[block.name], false); 34139 } 34140 }); 34141 })); 34142 }))); 34143 } 34144 /* harmony default export */ const block_hooks = ({ 34145 edit: BlockHooksControlPure, 34146 attributeKeys: ['metadata'], 34147 hasSupport() { 34148 return true; 34149 } 34150 }); 34151 34152 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/block-renaming.js 34153 34154 /** 34155 * WordPress dependencies 34156 */ 34157 34158 34159 34160 34161 34162 /** 34163 * Internal dependencies 34164 */ 34165 34166 34167 /** 34168 * Filters registered block settings, adding an `__experimentalLabel` callback if one does not already exist. 34169 * 34170 * @param {Object} settings Original block settings. 34171 * 34172 * @return {Object} Filtered block settings. 34173 */ 34174 function addLabelCallback(settings) { 34175 // If blocks provide their own label callback, do not override it. 34176 if (settings.__experimentalLabel) { 34177 return settings; 34178 } 34179 const supportsBlockNaming = (0,external_wp_blocks_namespaceObject.hasBlockSupport)(settings, 'renaming', true // default value 34180 ); 34181 34182 // Check whether block metadata is supported before using it. 34183 if (supportsBlockNaming) { 34184 settings.__experimentalLabel = (attributes, { 34185 context 34186 }) => { 34187 const { 34188 metadata 34189 } = attributes; 34190 34191 // In the list view, use the block's name attribute as the label. 34192 if (context === 'list-view' && metadata?.name) { 34193 return metadata.name; 34194 } 34195 }; 34196 } 34197 return settings; 34198 } 34199 function BlockRenameControlPure({ 34200 metadata, 34201 setAttributes 34202 }) { 34203 return (0,external_React_.createElement)(inspector_controls, { 34204 group: "advanced" 34205 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.TextControl, { 34206 __nextHasNoMarginBottom: true, 34207 __next40pxDefaultSize: true, 34208 label: (0,external_wp_i18n_namespaceObject.__)('Block name'), 34209 value: metadata?.name || '', 34210 onChange: newName => { 34211 setAttributes({ 34212 metadata: { 34213 ...metadata, 34214 name: newName 34215 } 34216 }); 34217 } 34218 })); 34219 } 34220 /* harmony default export */ const block_renaming = ({ 34221 edit: BlockRenameControlPure, 34222 attributeKeys: ['metadata'], 34223 hasSupport(name) { 34224 return (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, 'renaming', true); 34225 } 34226 }); 34227 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/metadata/addLabelCallback', addLabelCallback); 34228 34229 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/use-bindings-attributes.js 34230 34231 /** 34232 * WordPress dependencies 34233 */ 34234 34235 34236 34237 34238 34239 34240 34241 /** 34242 * Internal dependencies 34243 */ 34244 34245 34246 /** @typedef {import('@wordpress/compose').WPHigherOrderComponent} WPHigherOrderComponent */ 34247 /** @typedef {import('@wordpress/blocks').WPBlockSettings} WPBlockSettings */ 34248 34249 /** 34250 * Given a binding of block attributes, returns a higher order component that 34251 * overrides its `attributes` and `setAttributes` props to sync any changes needed. 34252 * 34253 * @return {WPHigherOrderComponent} Higher-order component. 34254 */ 34255 34256 const BLOCK_BINDINGS_ALLOWED_BLOCKS = { 34257 'core/paragraph': ['content'], 34258 'core/heading': ['content'], 34259 'core/image': ['url', 'title', 'alt'], 34260 'core/button': ['url', 'text', 'linkTarget'] 34261 }; 34262 34263 /** 34264 * Based on the given block name, 34265 * check if it is possible to bind the block. 34266 * 34267 * @param {string} blockName - The block name. 34268 * @return {boolean} Whether it is possible to bind the block to sources. 34269 */ 34270 function canBindBlock(blockName) { 34271 return blockName in BLOCK_BINDINGS_ALLOWED_BLOCKS; 34272 } 34273 34274 /** 34275 * Based on the given block name and attribute name, 34276 * check if it is possible to bind the block attribute. 34277 * 34278 * @param {string} blockName - The block name. 34279 * @param {string} attributeName - The attribute name. 34280 * @return {boolean} Whether it is possible to bind the block attribute. 34281 */ 34282 function canBindAttribute(blockName, attributeName) { 34283 return canBindBlock(blockName) && BLOCK_BINDINGS_ALLOWED_BLOCKS[blockName].includes(attributeName); 34284 } 34285 34286 /** 34287 * This component is responsible for detecting and 34288 * propagating data changes from the source to the block. 34289 * 34290 * @param {Object} props - The component props. 34291 * @param {string} props.attrName - The attribute name. 34292 * @param {Object} props.blockProps - The block props with bound attribute. 34293 * @param {Object} props.source - Source handler. 34294 * @param {Object} props.args - The arguments to pass to the source. 34295 * @param {Function} props.onPropValueChange - The function to call when the attribute value changes. 34296 * @return {null} Data-handling component. Render nothing. 34297 */ 34298 const BindingConnector = ({ 34299 args, 34300 attrName, 34301 blockProps, 34302 source, 34303 onPropValueChange 34304 }) => { 34305 const { 34306 placeholder, 34307 value: propValue 34308 } = source.useSource(blockProps, args); 34309 const { 34310 name: blockName 34311 } = blockProps; 34312 const attrValue = blockProps.attributes[attrName]; 34313 const updateBoundAttibute = (0,external_wp_element_namespaceObject.useCallback)((newAttrValue, prevAttrValue) => { 34314 /* 34315 * If the attribute is a RichTextData instance, 34316 * (core/paragraph, core/heading, core/button, etc.) 34317 * compare its HTML representation with the new value. 34318 * 34319 * To do: it looks like a workaround. 34320 * Consider improving the attribute and metadata fields types. 34321 */ 34322 if (prevAttrValue instanceof external_wp_richText_namespaceObject.RichTextData) { 34323 // Bail early if the Rich Text value is the same. 34324 if (prevAttrValue.toHTMLString() === newAttrValue) { 34325 return; 34326 } 34327 34328 /* 34329 * To preserve the value type, 34330 * convert the new value to a RichTextData instance. 34331 */ 34332 newAttrValue = external_wp_richText_namespaceObject.RichTextData.fromHTMLString(newAttrValue); 34333 } 34334 if (prevAttrValue === newAttrValue) { 34335 return; 34336 } 34337 onPropValueChange({ 34338 [attrName]: newAttrValue 34339 }); 34340 }, [attrName, onPropValueChange]); 34341 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 34342 if (typeof propValue !== 'undefined') { 34343 updateBoundAttibute(propValue, attrValue); 34344 } else if (placeholder) { 34345 /* 34346 * Placeholder fallback. 34347 * If the attribute is `src` or `href`, 34348 * a placeholder can't be used because it is not a valid url. 34349 * Adding this workaround until 34350 * attributes and metadata fields types are improved and include `url`. 34351 */ 34352 const htmlAttribute = (0,external_wp_blocks_namespaceObject.getBlockType)(blockName).attributes[attrName].attribute; 34353 if (htmlAttribute === 'src' || htmlAttribute === 'href') { 34354 updateBoundAttibute(null); 34355 return; 34356 } 34357 updateBoundAttibute(placeholder); 34358 } 34359 }, [updateBoundAttibute, propValue, attrValue, placeholder, blockName, attrName]); 34360 return null; 34361 }; 34362 34363 /** 34364 * BlockBindingBridge acts like a component wrapper 34365 * that connects the bound attributes of a block 34366 * to the source handlers. 34367 * For this, it creates a BindingConnector for each bound attribute. 34368 * 34369 * @param {Object} props - The component props. 34370 * @param {Object} props.blockProps - The BlockEdit props object. 34371 * @param {Object} props.bindings - The block bindings settings. 34372 * @param {Function} props.onPropValueChange - The function to call when the attribute value changes. 34373 * @return {null} Data-handling component. Render nothing. 34374 */ 34375 function BlockBindingBridge({ 34376 blockProps, 34377 bindings, 34378 onPropValueChange 34379 }) { 34380 const blockBindingsSources = unlock((0,external_wp_data_namespaceObject.useSelect)(external_wp_blocks_namespaceObject.store)).getAllBlockBindingsSources(); 34381 return (0,external_React_.createElement)(external_React_.Fragment, null, Object.entries(bindings).map(([attrName, boundAttribute]) => { 34382 // Bail early if the block doesn't have a valid source handler. 34383 const source = blockBindingsSources[boundAttribute.source]; 34384 if (!source?.useSource) { 34385 return null; 34386 } 34387 return (0,external_React_.createElement)(BindingConnector, { 34388 key: attrName, 34389 attrName: attrName, 34390 source: source, 34391 blockProps: blockProps, 34392 args: boundAttribute.args, 34393 onPropValueChange: onPropValueChange 34394 }); 34395 })); 34396 } 34397 const withBlockBindingSupport = (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(BlockEdit => props => { 34398 /* 34399 * Collect and update the bound attributes 34400 * in a separate state. 34401 */ 34402 const [boundAttributes, setBoundAttributes] = (0,external_wp_element_namespaceObject.useState)({}); 34403 const updateBoundAttributes = (0,external_wp_element_namespaceObject.useCallback)(newAttributes => setBoundAttributes(prev => ({ 34404 ...prev, 34405 ...newAttributes 34406 })), []); 34407 34408 /* 34409 * Create binding object filtering 34410 * only the attributes that can be bound. 34411 */ 34412 const bindings = Object.fromEntries(Object.entries(props.attributes.metadata?.bindings || {}).filter(([attrName]) => canBindAttribute(props.name, attrName))); 34413 return (0,external_React_.createElement)(external_React_.Fragment, null, Object.keys(bindings).length > 0 && (0,external_React_.createElement)(BlockBindingBridge, { 34414 blockProps: props, 34415 bindings: bindings, 34416 onPropValueChange: updateBoundAttributes 34417 }), (0,external_React_.createElement)(BlockEdit, { 34418 ...props, 34419 attributes: { 34420 ...props.attributes, 34421 ...boundAttributes 34422 } 34423 })); 34424 }, 'withBlockBindingSupport'); 34425 34426 /** 34427 * Filters a registered block's settings to enhance a block's `edit` component 34428 * to upgrade bound attributes. 34429 * 34430 * @param {WPBlockSettings} settings - Registered block settings. 34431 * @param {string} name - Block name. 34432 * @return {WPBlockSettings} Filtered block settings. 34433 */ 34434 function shimAttributeSource(settings, name) { 34435 if (!canBindBlock(name)) { 34436 return settings; 34437 } 34438 return { 34439 ...settings, 34440 edit: withBlockBindingSupport(settings.edit) 34441 }; 34442 } 34443 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/editor/custom-sources-backwards-compatibility/shim-attribute-source', shimAttributeSource); 34444 34445 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/use-border-props.js 34446 /** 34447 * Internal dependencies 34448 */ 34449 34450 34451 34452 34453 // This utility is intended to assist where the serialization of the border 34454 // block support is being skipped for a block but the border related CSS classes 34455 // & styles still need to be generated so they can be applied to inner elements. 34456 34457 /** 34458 * Provides the CSS class names and inline styles for a block's border support 34459 * attributes. 34460 * 34461 * @param {Object} attributes Block attributes. 34462 * @return {Object} Border block support derived CSS classes & styles. 34463 */ 34464 function getBorderClassesAndStyles(attributes) { 34465 const border = attributes.style?.border || {}; 34466 const className = getBorderClasses(attributes); 34467 return { 34468 className: className || undefined, 34469 style: getInlineStyles({ 34470 border 34471 }) 34472 }; 34473 } 34474 34475 /** 34476 * Derives the border related props for a block from its border block support 34477 * attributes. 34478 * 34479 * Inline styles are forced for named colors to ensure these selections are 34480 * reflected when themes do not load their color stylesheets in the editor. 34481 * 34482 * @param {Object} attributes Block attributes. 34483 * 34484 * @return {Object} ClassName & style props from border block support. 34485 */ 34486 function useBorderProps(attributes) { 34487 const { 34488 colors 34489 } = useMultipleOriginColorsAndGradients(); 34490 const borderProps = getBorderClassesAndStyles(attributes); 34491 const { 34492 borderColor 34493 } = attributes; 34494 34495 // Force inline styles to apply named border colors when themes do not load 34496 // their color stylesheets in the editor. 34497 if (borderColor) { 34498 const borderColorObject = getMultiOriginColor({ 34499 colors, 34500 namedColor: borderColor 34501 }); 34502 borderProps.style.borderColor = borderColorObject.color; 34503 } 34504 return borderProps; 34505 } 34506 34507 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/use-shadow-props.js 34508 /** 34509 * Internal dependencies 34510 */ 34511 34512 34513 // This utility is intended to assist where the serialization of the shadow 34514 // block support is being skipped for a block but the shadow related CSS classes 34515 // & styles still need to be generated so they can be applied to inner elements. 34516 34517 /** 34518 * Provides the CSS class names and inline styles for a block's shadow support 34519 * attributes. 34520 * 34521 * @param {Object} attributes Block attributes. 34522 * @return {Object} Shadow block support derived CSS classes & styles. 34523 */ 34524 function getShadowClassesAndStyles(attributes) { 34525 const shadow = attributes.style?.shadow || ''; 34526 return { 34527 style: getInlineStyles({ 34528 shadow 34529 }) 34530 }; 34531 } 34532 34533 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/use-color-props.js 34534 /** 34535 * External dependencies 34536 */ 34537 34538 34539 /** 34540 * WordPress dependencies 34541 */ 34542 34543 34544 /** 34545 * Internal dependencies 34546 */ 34547 34548 34549 34550 34551 34552 // The code in this file has largely been lifted from the color block support 34553 // hook. 34554 // 34555 // This utility is intended to assist where the serialization of the colors 34556 // block support is being skipped for a block but the color related CSS classes 34557 // & styles still need to be generated so they can be applied to inner elements. 34558 34559 /** 34560 * Provides the CSS class names and inline styles for a block's color support 34561 * attributes. 34562 * 34563 * @param {Object} attributes Block attributes. 34564 * 34565 * @return {Object} Color block support derived CSS classes & styles. 34566 */ 34567 function getColorClassesAndStyles(attributes) { 34568 const { 34569 backgroundColor, 34570 textColor, 34571 gradient, 34572 style 34573 } = attributes; 34574 34575 // Collect color CSS classes. 34576 const backgroundClass = getColorClassName('background-color', backgroundColor); 34577 const textClass = getColorClassName('color', textColor); 34578 const gradientClass = __experimentalGetGradientClass(gradient); 34579 const hasGradient = gradientClass || style?.color?.gradient; 34580 34581 // Determine color CSS class name list. 34582 const className = classnames_default()(textClass, gradientClass, { 34583 // Don't apply the background class if there's a gradient. 34584 [backgroundClass]: !hasGradient && !!backgroundClass, 34585 'has-text-color': textColor || style?.color?.text, 34586 'has-background': backgroundColor || style?.color?.background || gradient || style?.color?.gradient, 34587 'has-link-color': style?.elements?.link?.color 34588 }); 34589 34590 // Collect inline styles for colors. 34591 const colorStyles = style?.color || {}; 34592 const styleProp = getInlineStyles({ 34593 color: colorStyles 34594 }); 34595 return { 34596 className: className || undefined, 34597 style: styleProp 34598 }; 34599 } 34600 34601 /** 34602 * Determines the color related props for a block derived from its color block 34603 * support attributes. 34604 * 34605 * Inline styles are forced for named colors to ensure these selections are 34606 * reflected when themes do not load their color stylesheets in the editor. 34607 * 34608 * @param {Object} attributes Block attributes. 34609 * 34610 * @return {Object} ClassName & style props from colors block support. 34611 */ 34612 function useColorProps(attributes) { 34613 const { 34614 backgroundColor, 34615 textColor, 34616 gradient 34617 } = attributes; 34618 const [userPalette, themePalette, defaultPalette, userGradients, themeGradients, defaultGradients] = use_settings_useSettings('color.palette.custom', 'color.palette.theme', 'color.palette.default', 'color.gradients.custom', 'color.gradients.theme', 'color.gradients.default'); 34619 const colors = (0,external_wp_element_namespaceObject.useMemo)(() => [...(userPalette || []), ...(themePalette || []), ...(defaultPalette || [])], [userPalette, themePalette, defaultPalette]); 34620 const gradients = (0,external_wp_element_namespaceObject.useMemo)(() => [...(userGradients || []), ...(themeGradients || []), ...(defaultGradients || [])], [userGradients, themeGradients, defaultGradients]); 34621 const colorProps = getColorClassesAndStyles(attributes); 34622 34623 // Force inline styles to apply colors when themes do not load their color 34624 // stylesheets in the editor. 34625 if (backgroundColor) { 34626 const backgroundColorObject = getColorObjectByAttributeValues(colors, backgroundColor); 34627 colorProps.style.backgroundColor = backgroundColorObject.color; 34628 } 34629 if (gradient) { 34630 colorProps.style.background = getGradientValueBySlug(gradients, gradient); 34631 } 34632 if (textColor) { 34633 const textColorObject = getColorObjectByAttributeValues(colors, textColor); 34634 colorProps.style.color = textColorObject.color; 34635 } 34636 return colorProps; 34637 } 34638 34639 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/use-spacing-props.js 34640 /** 34641 * Internal dependencies 34642 */ 34643 34644 34645 // This utility is intended to assist where the serialization of the spacing 34646 // block support is being skipped for a block but the spacing related CSS 34647 // styles still need to be generated so they can be applied to inner elements. 34648 34649 /** 34650 * Provides the CSS class names and inline styles for a block's spacing support 34651 * attributes. 34652 * 34653 * @param {Object} attributes Block attributes. 34654 * 34655 * @return {Object} Spacing block support derived CSS classes & styles. 34656 */ 34657 function getSpacingClassesAndStyles(attributes) { 34658 const { 34659 style 34660 } = attributes; 34661 34662 // Collect inline styles for spacing. 34663 const spacingStyles = style?.spacing || {}; 34664 const styleProp = getInlineStyles({ 34665 spacing: spacingStyles 34666 }); 34667 return { 34668 style: styleProp 34669 }; 34670 } 34671 34672 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/use-typography-props.js 34673 /** 34674 * External dependencies 34675 */ 34676 34677 34678 /** 34679 * WordPress dependencies 34680 */ 34681 34682 34683 /** 34684 * Internal dependencies 34685 */ 34686 34687 34688 34689 34690 34691 /* 34692 * This utility is intended to assist where the serialization of the typography 34693 * block support is being skipped for a block but the typography related CSS 34694 * styles still need to be generated so they can be applied to inner elements. 34695 */ 34696 /** 34697 * Provides the CSS class names and inline styles for a block's typography support 34698 * attributes. 34699 * 34700 * @param {Object} attributes Block attributes. 34701 * @param {Object|boolean} settings Merged theme.json settings 34702 * 34703 * @return {Object} Typography block support derived CSS classes & styles. 34704 */ 34705 function getTypographyClassesAndStyles(attributes, settings) { 34706 const { 34707 kebabCase 34708 } = unlock(external_wp_components_namespaceObject.privateApis); 34709 let typographyStyles = attributes?.style?.typography || {}; 34710 const fluidTypographySettings = getFluidTypographyOptionsFromSettings(settings); 34711 typographyStyles = { 34712 ...typographyStyles, 34713 fontSize: getTypographyFontSizeValue({ 34714 size: attributes?.style?.typography?.fontSize 34715 }, fluidTypographySettings) 34716 }; 34717 const style = getInlineStyles({ 34718 typography: typographyStyles 34719 }); 34720 const fontFamilyClassName = !!attributes?.fontFamily ? `has-$kebabCase(attributes.fontFamily)}-font-family` : ''; 34721 const className = classnames_default()(fontFamilyClassName, getFontSizeClass(attributes?.fontSize)); 34722 return { 34723 className, 34724 style 34725 }; 34726 } 34727 34728 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/use-cached-truthy.js 34729 /** 34730 * WordPress dependencies 34731 */ 34732 34733 34734 /** 34735 * Keeps an up-to-date copy of the passed value and returns it. If value becomes falsy, it will return the last truthy copy. 34736 * 34737 * @param {any} value 34738 * @return {any} value 34739 */ 34740 function useCachedTruthy(value) { 34741 const [cachedValue, setCachedValue] = (0,external_wp_element_namespaceObject.useState)(value); 34742 (0,external_wp_element_namespaceObject.useEffect)(() => { 34743 if (value) { 34744 setCachedValue(value); 34745 } 34746 }, [value]); 34747 return cachedValue; 34748 } 34749 34750 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/index.js 34751 /** 34752 * Internal dependencies 34753 */ 34754 34755 34756 34757 34758 34759 34760 34761 34762 34763 34764 34765 34766 34767 34768 34769 34770 34771 34772 34773 34774 34775 34776 34777 34778 createBlockEditFilter([align, hooks_anchor, custom_class_name, style, duotone, position, layout, content_lock_ui, block_hooks, block_renaming].filter(Boolean)); 34779 createBlockListBlockFilter([align, style, color, dimensions, duotone, font_family, font_size, border, position, layout_child]); 34780 createBlockSaveFilter([align, hooks_anchor, aria_label, custom_class_name, border, color, style, font_family, font_size]); 34781 34782 34783 34784 34785 34786 34787 34788 34789 34790 34791 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/colors/with-colors.js 34792 34793 /** 34794 * WordPress dependencies 34795 */ 34796 34797 34798 34799 34800 /** 34801 * Internal dependencies 34802 */ 34803 34804 34805 34806 34807 /** 34808 * Capitalizes the first letter in a string. 34809 * 34810 * @param {string} str The string whose first letter the function will capitalize. 34811 * 34812 * @return {string} Capitalized string. 34813 */ 34814 const upperFirst = ([firstLetter, ...rest]) => firstLetter.toUpperCase() + rest.join(''); 34815 34816 /** 34817 * Higher order component factory for injecting the `colorsArray` argument as 34818 * the colors prop in the `withCustomColors` HOC. 34819 * 34820 * @param {Array} colorsArray An array of color objects. 34821 * 34822 * @return {Function} The higher order component. 34823 */ 34824 const withCustomColorPalette = colorsArray => (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(WrappedComponent => props => (0,external_React_.createElement)(WrappedComponent, { 34825 ...props, 34826 colors: colorsArray 34827 }), 'withCustomColorPalette'); 34828 34829 /** 34830 * Higher order component factory for injecting the editor colors as the 34831 * `colors` prop in the `withColors` HOC. 34832 * 34833 * @return {Function} The higher order component. 34834 */ 34835 const withEditorColorPalette = () => (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(WrappedComponent => props => { 34836 const [userPalette, themePalette, defaultPalette] = use_settings_useSettings('color.palette.custom', 'color.palette.theme', 'color.palette.default'); 34837 const allColors = (0,external_wp_element_namespaceObject.useMemo)(() => [...(userPalette || []), ...(themePalette || []), ...(defaultPalette || [])], [userPalette, themePalette, defaultPalette]); 34838 return (0,external_React_.createElement)(WrappedComponent, { 34839 ...props, 34840 colors: allColors 34841 }); 34842 }, 'withEditorColorPalette'); 34843 34844 /** 34845 * Helper function used with `createHigherOrderComponent` to create 34846 * higher order components for managing color logic. 34847 * 34848 * @param {Array} colorTypes An array of color types (e.g. 'backgroundColor, borderColor). 34849 * @param {Function} withColorPalette A HOC for injecting the 'colors' prop into the WrappedComponent. 34850 * 34851 * @return {Component} The component that can be used as a HOC. 34852 */ 34853 function createColorHOC(colorTypes, withColorPalette) { 34854 const { 34855 kebabCase 34856 } = unlock(external_wp_components_namespaceObject.privateApis); 34857 const colorMap = colorTypes.reduce((colorObject, colorType) => { 34858 return { 34859 ...colorObject, 34860 ...(typeof colorType === 'string' ? { 34861 [colorType]: kebabCase(colorType) 34862 } : colorType) 34863 }; 34864 }, {}); 34865 return (0,external_wp_compose_namespaceObject.compose)([withColorPalette, WrappedComponent => { 34866 return class extends external_wp_element_namespaceObject.Component { 34867 constructor(props) { 34868 super(props); 34869 this.setters = this.createSetters(); 34870 this.colorUtils = { 34871 getMostReadableColor: this.getMostReadableColor.bind(this) 34872 }; 34873 this.state = {}; 34874 } 34875 getMostReadableColor(colorValue) { 34876 const { 34877 colors 34878 } = this.props; 34879 return getMostReadableColor(colors, colorValue); 34880 } 34881 createSetters() { 34882 return Object.keys(colorMap).reduce((settersAccumulator, colorAttributeName) => { 34883 const upperFirstColorAttributeName = upperFirst(colorAttributeName); 34884 const customColorAttributeName = `custom$upperFirstColorAttributeName}`; 34885 settersAccumulator[`set$upperFirstColorAttributeName}`] = this.createSetColor(colorAttributeName, customColorAttributeName); 34886 return settersAccumulator; 34887 }, {}); 34888 } 34889 createSetColor(colorAttributeName, customColorAttributeName) { 34890 return colorValue => { 34891 const colorObject = getColorObjectByColorValue(this.props.colors, colorValue); 34892 this.props.setAttributes({ 34893 [colorAttributeName]: colorObject && colorObject.slug ? colorObject.slug : undefined, 34894 [customColorAttributeName]: colorObject && colorObject.slug ? undefined : colorValue 34895 }); 34896 }; 34897 } 34898 static getDerivedStateFromProps({ 34899 attributes, 34900 colors 34901 }, previousState) { 34902 return Object.entries(colorMap).reduce((newState, [colorAttributeName, colorContext]) => { 34903 const colorObject = getColorObjectByAttributeValues(colors, attributes[colorAttributeName], attributes[`custom$upperFirst(colorAttributeName)}`]); 34904 const previousColorObject = previousState[colorAttributeName]; 34905 const previousColor = previousColorObject?.color; 34906 /** 34907 * The "and previousColorObject" condition checks that a previous color object was already computed. 34908 * At the start previousColorObject and colorValue are both equal to undefined 34909 * bus as previousColorObject does not exist we should compute the object. 34910 */ 34911 if (previousColor === colorObject.color && previousColorObject) { 34912 newState[colorAttributeName] = previousColorObject; 34913 } else { 34914 newState[colorAttributeName] = { 34915 ...colorObject, 34916 class: getColorClassName(colorContext, colorObject.slug) 34917 }; 34918 } 34919 return newState; 34920 }, {}); 34921 } 34922 render() { 34923 return (0,external_React_.createElement)(WrappedComponent, { 34924 ...this.props, 34925 colors: undefined, 34926 ...this.state, 34927 ...this.setters, 34928 colorUtils: this.colorUtils 34929 }); 34930 } 34931 }; 34932 }]); 34933 } 34934 34935 /** 34936 * A higher-order component factory for creating a 'withCustomColors' HOC, which handles color logic 34937 * for class generation color value, retrieval and color attribute setting. 34938 * 34939 * Use this higher-order component to work with a custom set of colors. 34940 * 34941 * @example 34942 * 34943 * ```jsx 34944 * const CUSTOM_COLORS = [ { name: 'Red', slug: 'red', color: '#ff0000' }, { name: 'Blue', slug: 'blue', color: '#0000ff' } ]; 34945 * const withCustomColors = createCustomColorsHOC( CUSTOM_COLORS ); 34946 * // ... 34947 * export default compose( 34948 * withCustomColors( 'backgroundColor', 'borderColor' ), 34949 * MyColorfulComponent, 34950 * ); 34951 * ``` 34952 * 34953 * @param {Array} colorsArray The array of color objects (name, slug, color, etc... ). 34954 * 34955 * @return {Function} Higher-order component. 34956 */ 34957 function createCustomColorsHOC(colorsArray) { 34958 return (...colorTypes) => { 34959 const withColorPalette = withCustomColorPalette(colorsArray); 34960 return (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(createColorHOC(colorTypes, withColorPalette), 'withCustomColors'); 34961 }; 34962 } 34963 34964 /** 34965 * A higher-order component, which handles color logic for class generation color value, retrieval and color attribute setting. 34966 * 34967 * For use with the default editor/theme color palette. 34968 * 34969 * @example 34970 * 34971 * ```jsx 34972 * export default compose( 34973 * withColors( 'backgroundColor', { textColor: 'color' } ), 34974 * MyColorfulComponent, 34975 * ); 34976 * ``` 34977 * 34978 * @param {...(Object|string)} colorTypes The arguments can be strings or objects. If the argument is an object, 34979 * it should contain the color attribute name as key and the color context as value. 34980 * If the argument is a string the value should be the color attribute name, 34981 * the color context is computed by applying a kebab case transform to the value. 34982 * Color context represents the context/place where the color is going to be used. 34983 * The class name of the color is generated using 'has' followed by the color name 34984 * and ending with the color context all in kebab case e.g: has-green-background-color. 34985 * 34986 * @return {Function} Higher-order component. 34987 */ 34988 function withColors(...colorTypes) { 34989 const withColorPalette = withEditorColorPalette(); 34990 return (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(createColorHOC(colorTypes, withColorPalette), 'withColors'); 34991 } 34992 34993 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/colors/index.js 34994 34995 34996 34997 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/gradients/index.js 34998 34999 35000 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/font-sizes/font-size-picker.js 35001 35002 /** 35003 * WordPress dependencies 35004 */ 35005 35006 35007 /** 35008 * Internal dependencies 35009 */ 35010 35011 function font_size_picker_FontSizePicker(props) { 35012 const [fontSizes, customFontSize] = use_settings_useSettings('typography.fontSizes', 'typography.customFontSize'); 35013 return (0,external_React_.createElement)(external_wp_components_namespaceObject.FontSizePicker, { 35014 ...props, 35015 fontSizes: fontSizes, 35016 disableCustomFontSizes: !customFontSize 35017 }); 35018 } 35019 35020 /** 35021 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/font-sizes/README.md 35022 */ 35023 /* harmony default export */ const font_size_picker = (font_size_picker_FontSizePicker); 35024 35025 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/font-sizes/with-font-sizes.js 35026 35027 /** 35028 * WordPress dependencies 35029 */ 35030 35031 35032 35033 /** 35034 * Internal dependencies 35035 */ 35036 35037 35038 const DEFAULT_FONT_SIZES = []; 35039 35040 /** 35041 * Capitalizes the first letter in a string. 35042 * 35043 * @param {string} str The string whose first letter the function will capitalize. 35044 * 35045 * @return {string} Capitalized string. 35046 */ 35047 const with_font_sizes_upperFirst = ([firstLetter, ...rest]) => firstLetter.toUpperCase() + rest.join(''); 35048 35049 /** 35050 * Higher-order component, which handles font size logic for class generation, 35051 * font size value retrieval, and font size change handling. 35052 * 35053 * @param {...(Object|string)} fontSizeNames The arguments should all be strings. 35054 * Each string contains the font size 35055 * attribute name e.g: 'fontSize'. 35056 * 35057 * @return {Function} Higher-order component. 35058 */ 35059 /* harmony default export */ const with_font_sizes = ((...fontSizeNames) => { 35060 /* 35061 * Computes an object whose key is the font size attribute name as passed in the array, 35062 * and the value is the custom font size attribute name. 35063 * Custom font size is automatically compted by appending custom followed by the font size attribute name in with the first letter capitalized. 35064 */ 35065 const fontSizeAttributeNames = fontSizeNames.reduce((fontSizeAttributeNamesAccumulator, fontSizeAttributeName) => { 35066 fontSizeAttributeNamesAccumulator[fontSizeAttributeName] = `custom$with_font_sizes_upperFirst(fontSizeAttributeName)}`; 35067 return fontSizeAttributeNamesAccumulator; 35068 }, {}); 35069 return (0,external_wp_compose_namespaceObject.createHigherOrderComponent)((0,external_wp_compose_namespaceObject.compose)([(0,external_wp_compose_namespaceObject.createHigherOrderComponent)(WrappedComponent => props => { 35070 const [fontSizes] = use_settings_useSettings('typography.fontSizes'); 35071 return (0,external_React_.createElement)(WrappedComponent, { 35072 ...props, 35073 fontSizes: fontSizes || DEFAULT_FONT_SIZES 35074 }); 35075 }, 'withFontSizes'), WrappedComponent => { 35076 return class extends external_wp_element_namespaceObject.Component { 35077 constructor(props) { 35078 super(props); 35079 this.setters = this.createSetters(); 35080 this.state = {}; 35081 } 35082 createSetters() { 35083 return Object.entries(fontSizeAttributeNames).reduce((settersAccumulator, [fontSizeAttributeName, customFontSizeAttributeName]) => { 35084 const upperFirstFontSizeAttributeName = with_font_sizes_upperFirst(fontSizeAttributeName); 35085 settersAccumulator[`set$upperFirstFontSizeAttributeName}`] = this.createSetFontSize(fontSizeAttributeName, customFontSizeAttributeName); 35086 return settersAccumulator; 35087 }, {}); 35088 } 35089 createSetFontSize(fontSizeAttributeName, customFontSizeAttributeName) { 35090 return fontSizeValue => { 35091 const fontSizeObject = this.props.fontSizes?.find(({ 35092 size 35093 }) => size === Number(fontSizeValue)); 35094 this.props.setAttributes({ 35095 [fontSizeAttributeName]: fontSizeObject && fontSizeObject.slug ? fontSizeObject.slug : undefined, 35096 [customFontSizeAttributeName]: fontSizeObject && fontSizeObject.slug ? undefined : fontSizeValue 35097 }); 35098 }; 35099 } 35100 static getDerivedStateFromProps({ 35101 attributes, 35102 fontSizes 35103 }, previousState) { 35104 const didAttributesChange = (customFontSizeAttributeName, fontSizeAttributeName) => { 35105 if (previousState[fontSizeAttributeName]) { 35106 // If new font size is name compare with the previous slug. 35107 if (attributes[fontSizeAttributeName]) { 35108 return attributes[fontSizeAttributeName] !== previousState[fontSizeAttributeName].slug; 35109 } 35110 // If font size is not named, update when the font size value changes. 35111 return previousState[fontSizeAttributeName].size !== attributes[customFontSizeAttributeName]; 35112 } 35113 // In this case we need to build the font size object. 35114 return true; 35115 }; 35116 if (!Object.values(fontSizeAttributeNames).some(didAttributesChange)) { 35117 return null; 35118 } 35119 const newState = Object.entries(fontSizeAttributeNames).filter(([key, value]) => didAttributesChange(value, key)).reduce((newStateAccumulator, [fontSizeAttributeName, customFontSizeAttributeName]) => { 35120 const fontSizeAttributeValue = attributes[fontSizeAttributeName]; 35121 const fontSizeObject = utils_getFontSize(fontSizes, fontSizeAttributeValue, attributes[customFontSizeAttributeName]); 35122 newStateAccumulator[fontSizeAttributeName] = { 35123 ...fontSizeObject, 35124 class: getFontSizeClass(fontSizeAttributeValue) 35125 }; 35126 return newStateAccumulator; 35127 }, {}); 35128 return { 35129 ...previousState, 35130 ...newState 35131 }; 35132 } 35133 render() { 35134 return (0,external_React_.createElement)(WrappedComponent, { 35135 ...this.props, 35136 fontSizes: undefined, 35137 ...this.state, 35138 ...this.setters 35139 }); 35140 } 35141 }; 35142 }]), 'withFontSizes'); 35143 }); 35144 35145 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/font-sizes/index.js 35146 35147 35148 35149 35150 35151 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/align-left.js 35152 35153 /** 35154 * WordPress dependencies 35155 */ 35156 35157 const alignLeft = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 35158 xmlns: "http://www.w3.org/2000/svg", 35159 viewBox: "0 0 24 24" 35160 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 35161 d: "M13 5.5H4V4h9v1.5Zm7 7H4V11h16v1.5Zm-7 7H4V18h9v1.5Z" 35162 })); 35163 /* harmony default export */ const align_left = (alignLeft); 35164 35165 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/align-center.js 35166 35167 /** 35168 * WordPress dependencies 35169 */ 35170 35171 const align_center_alignCenter = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 35172 xmlns: "http://www.w3.org/2000/svg", 35173 viewBox: "0 0 24 24" 35174 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 35175 d: "M7.5 5.5h9V4h-9v1.5Zm-3.5 7h16V11H4v1.5Zm3.5 7h9V18h-9v1.5Z" 35176 })); 35177 /* harmony default export */ const align_center = (align_center_alignCenter); 35178 35179 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/align-right.js 35180 35181 /** 35182 * WordPress dependencies 35183 */ 35184 35185 const alignRight = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 35186 xmlns: "http://www.w3.org/2000/svg", 35187 viewBox: "0 0 24 24" 35188 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 35189 d: "M11.111 5.5H20V4h-8.889v1.5ZM4 12.5h16V11H4v1.5Zm7.111 7H20V18h-8.889v1.5Z" 35190 })); 35191 /* harmony default export */ const align_right = (alignRight); 35192 35193 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/alignment-control/ui.js 35194 35195 /** 35196 * WordPress dependencies 35197 */ 35198 35199 35200 35201 const DEFAULT_ALIGNMENT_CONTROLS = [{ 35202 icon: align_left, 35203 title: (0,external_wp_i18n_namespaceObject.__)('Align text left'), 35204 align: 'left' 35205 }, { 35206 icon: align_center, 35207 title: (0,external_wp_i18n_namespaceObject.__)('Align text center'), 35208 align: 'center' 35209 }, { 35210 icon: align_right, 35211 title: (0,external_wp_i18n_namespaceObject.__)('Align text right'), 35212 align: 'right' 35213 }]; 35214 const ui_POPOVER_PROPS = { 35215 placement: 'bottom-start' 35216 }; 35217 function AlignmentUI({ 35218 value, 35219 onChange, 35220 alignmentControls = DEFAULT_ALIGNMENT_CONTROLS, 35221 label = (0,external_wp_i18n_namespaceObject.__)('Align text'), 35222 describedBy = (0,external_wp_i18n_namespaceObject.__)('Change text alignment'), 35223 isCollapsed = true, 35224 isToolbar 35225 }) { 35226 function applyOrUnset(align) { 35227 return () => onChange(value === align ? undefined : align); 35228 } 35229 const activeAlignment = alignmentControls.find(control => control.align === value); 35230 function setIcon() { 35231 if (activeAlignment) return activeAlignment.icon; 35232 return (0,external_wp_i18n_namespaceObject.isRTL)() ? align_right : align_left; 35233 } 35234 const UIComponent = isToolbar ? external_wp_components_namespaceObject.ToolbarGroup : external_wp_components_namespaceObject.ToolbarDropdownMenu; 35235 const extraProps = isToolbar ? { 35236 isCollapsed 35237 } : { 35238 toggleProps: { 35239 describedBy 35240 }, 35241 popoverProps: ui_POPOVER_PROPS 35242 }; 35243 return (0,external_React_.createElement)(UIComponent, { 35244 icon: setIcon(), 35245 label: label, 35246 controls: alignmentControls.map(control => { 35247 const { 35248 align 35249 } = control; 35250 const isActive = value === align; 35251 return { 35252 ...control, 35253 isActive, 35254 role: isCollapsed ? 'menuitemradio' : undefined, 35255 onClick: applyOrUnset(align) 35256 }; 35257 }), 35258 ...extraProps 35259 }); 35260 } 35261 /* harmony default export */ const alignment_control_ui = (AlignmentUI); 35262 35263 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/alignment-control/index.js 35264 35265 /** 35266 * Internal dependencies 35267 */ 35268 35269 const AlignmentControl = props => { 35270 return (0,external_React_.createElement)(alignment_control_ui, { 35271 ...props, 35272 isToolbar: false 35273 }); 35274 }; 35275 const AlignmentToolbar = props => { 35276 return (0,external_React_.createElement)(alignment_control_ui, { 35277 ...props, 35278 isToolbar: true 35279 }); 35280 }; 35281 35282 /** 35283 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/alignment-control/README.md 35284 */ 35285 35286 35287 // EXTERNAL MODULE: ./node_modules/remove-accents/index.js 35288 var remove_accents = __webpack_require__(9681); 35289 var remove_accents_default = /*#__PURE__*/__webpack_require__.n(remove_accents); 35290 ;// CONCATENATED MODULE: ./node_modules/lower-case/dist.es2015/index.js 35291 /** 35292 * Source: ftp://ftp.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt 35293 */ 35294 var SUPPORTED_LOCALE = { 35295 tr: { 35296 regexp: /\u0130|\u0049|\u0049\u0307/g, 35297 map: { 35298 İ: "\u0069", 35299 I: "\u0131", 35300 İ: "\u0069", 35301 }, 35302 }, 35303 az: { 35304 regexp: /\u0130/g, 35305 map: { 35306 İ: "\u0069", 35307 I: "\u0131", 35308 İ: "\u0069", 35309 }, 35310 }, 35311 lt: { 35312 regexp: /\u0049|\u004A|\u012E|\u00CC|\u00CD|\u0128/g, 35313 map: { 35314 I: "\u0069\u0307", 35315 J: "\u006A\u0307", 35316 Į: "\u012F\u0307", 35317 Ì: "\u0069\u0307\u0300", 35318 Í: "\u0069\u0307\u0301", 35319 Ĩ: "\u0069\u0307\u0303", 35320 }, 35321 }, 35322 }; 35323 /** 35324 * Localized lower case. 35325 */ 35326 function localeLowerCase(str, locale) { 35327 var lang = SUPPORTED_LOCALE[locale.toLowerCase()]; 35328 if (lang) 35329 return lowerCase(str.replace(lang.regexp, function (m) { return lang.map[m]; })); 35330 return lowerCase(str); 35331 } 35332 /** 35333 * Lower case as a function. 35334 */ 35335 function lowerCase(str) { 35336 return str.toLowerCase(); 35337 } 35338 35339 ;// CONCATENATED MODULE: ./node_modules/no-case/dist.es2015/index.js 35340 35341 // Support camel case ("camelCase" -> "camel Case" and "CAMELCase" -> "CAMEL Case"). 35342 var DEFAULT_SPLIT_REGEXP = [/([a-z0-9])([A-Z])/g, /([A-Z])([A-Z][a-z])/g]; 35343 // Remove all non-word characters. 35344 var DEFAULT_STRIP_REGEXP = /[^A-Z0-9]+/gi; 35345 /** 35346 * Normalize the string into something other libraries can manipulate easier. 35347 */ 35348 function noCase(input, options) { 35349 if (options === void 0) { options = {}; } 35350 var _a = options.splitRegexp, splitRegexp = _a === void 0 ? DEFAULT_SPLIT_REGEXP : _a, _b = options.stripRegexp, stripRegexp = _b === void 0 ? DEFAULT_STRIP_REGEXP : _b, _c = options.transform, transform = _c === void 0 ? lowerCase : _c, _d = options.delimiter, delimiter = _d === void 0 ? " " : _d; 35351 var result = dist_es2015_replace(dist_es2015_replace(input, splitRegexp, "$1\0$2"), stripRegexp, "\0"); 35352 var start = 0; 35353 var end = result.length; 35354 // Trim the delimiter from around the output string. 35355 while (result.charAt(start) === "\0") 35356 start++; 35357 while (result.charAt(end - 1) === "\0") 35358 end--; 35359 // Transform each token independently. 35360 return result.slice(start, end).split("\0").map(transform).join(delimiter); 35361 } 35362 /** 35363 * Replace `re` in the input string with the replacement value. 35364 */ 35365 function dist_es2015_replace(input, re, value) { 35366 if (re instanceof RegExp) 35367 return input.replace(re, value); 35368 return re.reduce(function (input, re) { return input.replace(re, value); }, input); 35369 } 35370 35371 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/search-items.js 35372 /** 35373 * External dependencies 35374 */ 35375 35376 35377 35378 // Default search helpers. 35379 const defaultGetName = item => item.name || ''; 35380 const defaultGetTitle = item => item.title; 35381 const defaultGetDescription = item => item.description || ''; 35382 const defaultGetKeywords = item => item.keywords || []; 35383 const defaultGetCategory = item => item.category; 35384 const defaultGetCollection = () => null; 35385 35386 /** 35387 * Extracts words from an input string. 35388 * 35389 * @param {string} input The input string. 35390 * 35391 * @return {Array} Words, extracted from the input string. 35392 */ 35393 function extractWords(input = '') { 35394 return noCase(input, { 35395 splitRegexp: [/([\p{Ll}\p{Lo}\p{N}])([\p{Lu}\p{Lt}])/gu, 35396 // One lowercase or digit, followed by one uppercase. 35397 /([\p{Lu}\p{Lt}])([\p{Lu}\p{Lt}][\p{Ll}\p{Lo}])/gu // One uppercase followed by one uppercase and one lowercase. 35398 ], 35399 stripRegexp: /(\p{C}|\p{P}|\p{S})+/giu // Anything that's not a punctuation, symbol or control/format character. 35400 }).split(' ').filter(Boolean); 35401 } 35402 35403 /** 35404 * Sanitizes the search input string. 35405 * 35406 * @param {string} input The search input to normalize. 35407 * 35408 * @return {string} The normalized search input. 35409 */ 35410 function normalizeSearchInput(input = '') { 35411 // Disregard diacritics. 35412 // Input: "média" 35413 input = remove_accents_default()(input); 35414 35415 // Accommodate leading slash, matching autocomplete expectations. 35416 // Input: "/media" 35417 input = input.replace(/^\//, ''); 35418 35419 // Lowercase. 35420 // Input: "MEDIA" 35421 input = input.toLowerCase(); 35422 return input; 35423 } 35424 35425 /** 35426 * Converts the search term into a list of normalized terms. 35427 * 35428 * @param {string} input The search term to normalize. 35429 * 35430 * @return {string[]} The normalized list of search terms. 35431 */ 35432 const getNormalizedSearchTerms = (input = '') => { 35433 return extractWords(normalizeSearchInput(input)); 35434 }; 35435 const removeMatchingTerms = (unmatchedTerms, unprocessedTerms) => { 35436 return unmatchedTerms.filter(term => !getNormalizedSearchTerms(unprocessedTerms).some(unprocessedTerm => unprocessedTerm.includes(term))); 35437 }; 35438 const searchBlockItems = (items, categories, collections, searchInput) => { 35439 const normalizedSearchTerms = getNormalizedSearchTerms(searchInput); 35440 if (normalizedSearchTerms.length === 0) { 35441 return items; 35442 } 35443 const config = { 35444 getCategory: item => categories.find(({ 35445 slug 35446 }) => slug === item.category)?.title, 35447 getCollection: item => collections[item.name.split('/')[0]]?.title 35448 }; 35449 return searchItems(items, searchInput, config); 35450 }; 35451 35452 /** 35453 * Filters an item list given a search term. 35454 * 35455 * @param {Array} items Item list 35456 * @param {string} searchInput Search input. 35457 * @param {Object} config Search Config. 35458 * 35459 * @return {Array} Filtered item list. 35460 */ 35461 const searchItems = (items = [], searchInput = '', config = {}) => { 35462 const normalizedSearchTerms = getNormalizedSearchTerms(searchInput); 35463 if (normalizedSearchTerms.length === 0) { 35464 return items; 35465 } 35466 const rankedItems = items.map(item => { 35467 return [item, getItemSearchRank(item, searchInput, config)]; 35468 }).filter(([, rank]) => rank > 0); 35469 rankedItems.sort(([, rank1], [, rank2]) => rank2 - rank1); 35470 return rankedItems.map(([item]) => item); 35471 }; 35472 35473 /** 35474 * Get the search rank for a given item and a specific search term. 35475 * The better the match, the higher the rank. 35476 * If the rank equals 0, it should be excluded from the results. 35477 * 35478 * @param {Object} item Item to filter. 35479 * @param {string} searchTerm Search term. 35480 * @param {Object} config Search Config. 35481 * 35482 * @return {number} Search Rank. 35483 */ 35484 function getItemSearchRank(item, searchTerm, config = {}) { 35485 const { 35486 getName = defaultGetName, 35487 getTitle = defaultGetTitle, 35488 getDescription = defaultGetDescription, 35489 getKeywords = defaultGetKeywords, 35490 getCategory = defaultGetCategory, 35491 getCollection = defaultGetCollection 35492 } = config; 35493 const name = getName(item); 35494 const title = getTitle(item); 35495 const description = getDescription(item); 35496 const keywords = getKeywords(item); 35497 const category = getCategory(item); 35498 const collection = getCollection(item); 35499 const normalizedSearchInput = normalizeSearchInput(searchTerm); 35500 const normalizedTitle = normalizeSearchInput(title); 35501 let rank = 0; 35502 35503 // Prefers exact matches 35504 // Then prefers if the beginning of the title matches the search term 35505 // name, keywords, categories, collection, variations match come later. 35506 if (normalizedSearchInput === normalizedTitle) { 35507 rank += 30; 35508 } else if (normalizedTitle.startsWith(normalizedSearchInput)) { 35509 rank += 20; 35510 } else { 35511 const terms = [name, title, description, ...keywords, category, collection].join(' '); 35512 const normalizedSearchTerms = extractWords(normalizedSearchInput); 35513 const unmatchedTerms = removeMatchingTerms(normalizedSearchTerms, terms); 35514 if (unmatchedTerms.length === 0) { 35515 rank += 10; 35516 } 35517 } 35518 35519 // Give a better rank to "core" namespaced items. 35520 if (rank !== 0 && name.startsWith('core/')) { 35521 const isCoreBlockVariation = name !== item.id; 35522 // Give a bit better rank to "core" blocks over "core" block variations. 35523 rank += isCoreBlockVariation ? 1 : 2; 35524 } 35525 return rank; 35526 } 35527 35528 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/hooks/use-block-types-state.js 35529 /** 35530 * WordPress dependencies 35531 */ 35532 35533 35534 35535 35536 /** 35537 * Internal dependencies 35538 */ 35539 35540 35541 /** 35542 * Retrieves the block types inserter state. 35543 * 35544 * @param {string=} rootClientId Insertion's root client ID. 35545 * @param {Function} onInsert function called when inserter a list of blocks. 35546 * @return {Array} Returns the block types state. (block types, categories, collections, onSelect handler) 35547 */ 35548 const useBlockTypesState = (rootClientId, onInsert) => { 35549 const [items] = (0,external_wp_data_namespaceObject.useSelect)(select => [select(store).getInserterItems(rootClientId)], [rootClientId]); 35550 const [categories, collections] = (0,external_wp_data_namespaceObject.useSelect)(select => { 35551 const { 35552 getCategories, 35553 getCollections 35554 } = select(external_wp_blocks_namespaceObject.store); 35555 return [getCategories(), getCollections()]; 35556 }, []); 35557 const onSelectItem = (0,external_wp_element_namespaceObject.useCallback)(({ 35558 name, 35559 initialAttributes, 35560 innerBlocks, 35561 syncStatus, 35562 content 35563 }, shouldFocusBlock) => { 35564 const insertedBlock = syncStatus === 'unsynced' ? (0,external_wp_blocks_namespaceObject.parse)(content, { 35565 __unstableSkipMigrationLogs: true 35566 }) : (0,external_wp_blocks_namespaceObject.createBlock)(name, initialAttributes, (0,external_wp_blocks_namespaceObject.createBlocksFromInnerBlocksTemplate)(innerBlocks)); 35567 onInsert(insertedBlock, undefined, shouldFocusBlock); 35568 }, [onInsert]); 35569 return [items, categories, collections, onSelectItem]; 35570 }; 35571 /* harmony default export */ const use_block_types_state = (useBlockTypesState); 35572 35573 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/order-inserter-block-items.js 35574 /** @typedef {import('../store/selectors').WPEditorInserterItem} WPEditorInserterItem */ 35575 35576 /** 35577 * Helper function to order inserter block items according to a provided array of prioritized blocks. 35578 * 35579 * @param {WPEditorInserterItem[]} items The array of editor inserter block items to be sorted. 35580 * @param {string[]} priority The array of block names to be prioritized. 35581 * @return {WPEditorInserterItem[]} The sorted array of editor inserter block items. 35582 */ 35583 const orderInserterBlockItems = (items, priority) => { 35584 if (!priority) { 35585 return items; 35586 } 35587 items.sort(({ 35588 id: aName 35589 }, { 35590 id: bName 35591 }) => { 35592 // Sort block items according to `priority`. 35593 let aIndex = priority.indexOf(aName); 35594 let bIndex = priority.indexOf(bName); 35595 // All other block items should come after that. 35596 if (aIndex < 0) aIndex = priority.length; 35597 if (bIndex < 0) bIndex = priority.length; 35598 return aIndex - bIndex; 35599 }); 35600 return items; 35601 }; 35602 35603 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/autocompleters/block.js 35604 35605 /** 35606 * WordPress dependencies 35607 */ 35608 35609 35610 35611 35612 /** 35613 * Internal dependencies 35614 */ 35615 35616 35617 35618 35619 35620 35621 const block_noop = () => {}; 35622 const SHOWN_BLOCK_TYPES = 9; 35623 35624 /** @typedef {import('@wordpress/components').WPCompleter} WPCompleter */ 35625 35626 /** 35627 * Creates a blocks repeater for replacing the current block with a selected block type. 35628 * 35629 * @return {WPCompleter} A blocks completer. 35630 */ 35631 function createBlockCompleter() { 35632 return { 35633 name: 'blocks', 35634 className: 'block-editor-autocompleters__block', 35635 triggerPrefix: '/', 35636 useItems(filterValue) { 35637 const { 35638 rootClientId, 35639 selectedBlockName, 35640 prioritizedBlocks 35641 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 35642 const { 35643 getSelectedBlockClientId, 35644 getBlockName, 35645 getBlockListSettings, 35646 getBlockRootClientId 35647 } = select(store); 35648 const selectedBlockClientId = getSelectedBlockClientId(); 35649 const _rootClientId = getBlockRootClientId(selectedBlockClientId); 35650 return { 35651 selectedBlockName: selectedBlockClientId ? getBlockName(selectedBlockClientId) : null, 35652 rootClientId: _rootClientId, 35653 prioritizedBlocks: getBlockListSettings(_rootClientId)?.prioritizedInserterBlocks 35654 }; 35655 }, []); 35656 const [items, categories, collections] = use_block_types_state(rootClientId, block_noop); 35657 const filteredItems = (0,external_wp_element_namespaceObject.useMemo)(() => { 35658 const initialFilteredItems = !!filterValue.trim() ? searchBlockItems(items, categories, collections, filterValue) : orderInserterBlockItems(orderBy(items, 'frecency', 'desc'), prioritizedBlocks); 35659 return initialFilteredItems.filter(item => item.name !== selectedBlockName).slice(0, SHOWN_BLOCK_TYPES); 35660 }, [filterValue, selectedBlockName, items, categories, collections, prioritizedBlocks]); 35661 const options = (0,external_wp_element_namespaceObject.useMemo)(() => filteredItems.map(blockItem => { 35662 const { 35663 title, 35664 icon, 35665 isDisabled 35666 } = blockItem; 35667 return { 35668 key: `block-$blockItem.id}`, 35669 value: blockItem, 35670 label: (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(block_icon, { 35671 key: "icon", 35672 icon: icon, 35673 showColors: true 35674 }), title), 35675 isDisabled 35676 }; 35677 }), [filteredItems]); 35678 return [options]; 35679 }, 35680 allowContext(before, after) { 35681 return !(/\S/.test(before) || /\S/.test(after)); 35682 }, 35683 getOptionCompletion(inserterItem) { 35684 const { 35685 name, 35686 initialAttributes, 35687 innerBlocks, 35688 syncStatus, 35689 content 35690 } = inserterItem; 35691 return { 35692 action: 'replace', 35693 value: syncStatus === 'unsynced' ? (0,external_wp_blocks_namespaceObject.parse)(content, { 35694 __unstableSkipMigrationLogs: true 35695 }) : (0,external_wp_blocks_namespaceObject.createBlock)(name, initialAttributes, (0,external_wp_blocks_namespaceObject.createBlocksFromInnerBlocksTemplate)(innerBlocks)) 35696 }; 35697 } 35698 }; 35699 } 35700 35701 /** 35702 * Creates a blocks repeater for replacing the current block with a selected block type. 35703 * 35704 * @return {WPCompleter} A blocks completer. 35705 */ 35706 /* harmony default export */ const block = (createBlockCompleter()); 35707 35708 ;// CONCATENATED MODULE: external ["wp","apiFetch"] 35709 const external_wp_apiFetch_namespaceObject = window["wp"]["apiFetch"]; 35710 var external_wp_apiFetch_default = /*#__PURE__*/__webpack_require__.n(external_wp_apiFetch_namespaceObject); 35711 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/post.js 35712 35713 /** 35714 * WordPress dependencies 35715 */ 35716 35717 const post = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 35718 xmlns: "http://www.w3.org/2000/svg", 35719 viewBox: "0 0 24 24" 35720 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 35721 d: "m7.3 9.7 1.4 1.4c.2-.2.3-.3.4-.5 0 0 0-.1.1-.1.3-.5.4-1.1.3-1.6L12 7 9 4 7.2 6.5c-.6-.1-1.1 0-1.6.3 0 0-.1 0-.1.1-.3.1-.4.2-.6.4l1.4 1.4L4 11v1h1l2.3-2.3zM4 20h9v-1.5H4V20zm0-5.5V16h16v-1.5H4z" 35722 })); 35723 /* harmony default export */ const library_post = (post); 35724 35725 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/autocompleters/link.js 35726 35727 /** 35728 * WordPress dependencies 35729 */ 35730 // Disable Reason: Needs to be refactored. 35731 // eslint-disable-next-line no-restricted-imports 35732 35733 35734 35735 const SHOWN_SUGGESTIONS = 10; 35736 35737 /** @typedef {import('@wordpress/components').WPCompleter} WPCompleter */ 35738 35739 /** 35740 * Creates a suggestion list for links to posts or pages. 35741 * 35742 * @return {WPCompleter} A links completer. 35743 */ 35744 function createLinkCompleter() { 35745 return { 35746 name: 'links', 35747 className: 'block-editor-autocompleters__link', 35748 triggerPrefix: '[[', 35749 options: async letters => { 35750 let options = await external_wp_apiFetch_default()({ 35751 path: (0,external_wp_url_namespaceObject.addQueryArgs)('/wp/v2/search', { 35752 per_page: SHOWN_SUGGESTIONS, 35753 search: letters, 35754 type: 'post', 35755 order_by: 'menu_order' 35756 }) 35757 }); 35758 options = options.filter(option => option.title !== ''); 35759 return options; 35760 }, 35761 getOptionKeywords(item) { 35762 const expansionWords = item.title.split(/\s+/); 35763 return [...expansionWords]; 35764 }, 35765 getOptionLabel(item) { 35766 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(build_module_icon, { 35767 key: "icon", 35768 icon: item.subtype === 'page' ? library_page : library_post 35769 }), item.title); 35770 }, 35771 getOptionCompletion(item) { 35772 return (0,external_React_.createElement)("a", { 35773 href: item.url 35774 }, item.title); 35775 } 35776 }; 35777 } 35778 35779 /** 35780 * Creates a suggestion list for links to posts or pages.. 35781 * 35782 * @return {WPCompleter} A link completer. 35783 */ 35784 /* harmony default export */ const autocompleters_link = (createLinkCompleter()); 35785 35786 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/autocomplete/index.js 35787 35788 /** 35789 * WordPress dependencies 35790 */ 35791 35792 35793 35794 35795 35796 /** 35797 * Internal dependencies 35798 */ 35799 35800 35801 35802 35803 /** 35804 * Shared reference to an empty array for cases where it is important to avoid 35805 * returning a new array reference on every invocation. 35806 * 35807 * @type {Array} 35808 */ 35809 const autocomplete_EMPTY_ARRAY = []; 35810 function useCompleters({ 35811 completers = autocomplete_EMPTY_ARRAY 35812 }) { 35813 const { 35814 name 35815 } = useBlockEditContext(); 35816 return (0,external_wp_element_namespaceObject.useMemo)(() => { 35817 let filteredCompleters = [...completers, autocompleters_link]; 35818 if (name === (0,external_wp_blocks_namespaceObject.getDefaultBlockName)() || (0,external_wp_blocks_namespaceObject.getBlockSupport)(name, '__experimentalSlashInserter', false)) { 35819 filteredCompleters = [...filteredCompleters, block]; 35820 } 35821 if ((0,external_wp_hooks_namespaceObject.hasFilter)('editor.Autocomplete.completers')) { 35822 // Provide copies so filters may directly modify them. 35823 if (filteredCompleters === completers) { 35824 filteredCompleters = filteredCompleters.map(completer => ({ 35825 ...completer 35826 })); 35827 } 35828 filteredCompleters = (0,external_wp_hooks_namespaceObject.applyFilters)('editor.Autocomplete.completers', filteredCompleters, name); 35829 } 35830 return filteredCompleters; 35831 }, [completers, name]); 35832 } 35833 function useBlockEditorAutocompleteProps(props) { 35834 return (0,external_wp_components_namespaceObject.__unstableUseAutocompleteProps)({ 35835 ...props, 35836 completers: useCompleters(props) 35837 }); 35838 } 35839 35840 /** 35841 * Wrap the default Autocomplete component with one that supports a filter hook 35842 * for customizing its list of autocompleters. 35843 * 35844 * @type {import('react').FC} 35845 */ 35846 function BlockEditorAutocomplete(props) { 35847 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Autocomplete, { 35848 ...props, 35849 completers: useCompleters(props) 35850 }); 35851 } 35852 35853 /** 35854 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/autocomplete/README.md 35855 */ 35856 /* harmony default export */ const autocomplete = (BlockEditorAutocomplete); 35857 35858 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/fullscreen.js 35859 35860 /** 35861 * WordPress dependencies 35862 */ 35863 35864 const fullscreen = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 35865 xmlns: "http://www.w3.org/2000/svg", 35866 viewBox: "0 0 24 24" 35867 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 35868 d: "M6 4a2 2 0 0 0-2 2v3h1.5V6a.5.5 0 0 1 .5-.5h3V4H6Zm3 14.5H6a.5.5 0 0 1-.5-.5v-3H4v3a2 2 0 0 0 2 2h3v-1.5Zm6 1.5v-1.5h3a.5.5 0 0 0 .5-.5v-3H20v3a2 2 0 0 1-2 2h-3Zm3-16a2 2 0 0 1 2 2v3h-1.5V6a.5.5 0 0 0-.5-.5h-3V4h3Z" 35869 })); 35870 /* harmony default export */ const library_fullscreen = (fullscreen); 35871 35872 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-full-height-alignment-control/index.js 35873 35874 /** 35875 * WordPress dependencies 35876 */ 35877 35878 35879 35880 function BlockFullHeightAlignmentControl({ 35881 isActive, 35882 label = (0,external_wp_i18n_namespaceObject.__)('Toggle full height'), 35883 onToggle, 35884 isDisabled 35885 }) { 35886 return (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarButton, { 35887 isActive: isActive, 35888 icon: library_fullscreen, 35889 label: label, 35890 onClick: () => onToggle(!isActive), 35891 disabled: isDisabled 35892 }); 35893 } 35894 /* harmony default export */ const block_full_height_alignment_control = (BlockFullHeightAlignmentControl); 35895 35896 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-alignment-matrix-control/index.js 35897 35898 /** 35899 * WordPress dependencies 35900 */ 35901 35902 35903 35904 const block_alignment_matrix_control_noop = () => {}; 35905 function BlockAlignmentMatrixControl(props) { 35906 const { 35907 label = (0,external_wp_i18n_namespaceObject.__)('Change matrix alignment'), 35908 onChange = block_alignment_matrix_control_noop, 35909 value = 'center', 35910 isDisabled 35911 } = props; 35912 const icon = (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalAlignmentMatrixControl.Icon, { 35913 value: value 35914 }); 35915 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Dropdown, { 35916 popoverProps: { 35917 placement: 'bottom-start' 35918 }, 35919 renderToggle: ({ 35920 onToggle, 35921 isOpen 35922 }) => { 35923 const openOnArrowDown = event => { 35924 if (!isOpen && event.keyCode === external_wp_keycodes_namespaceObject.DOWN) { 35925 event.preventDefault(); 35926 onToggle(); 35927 } 35928 }; 35929 return (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarButton, { 35930 onClick: onToggle, 35931 "aria-haspopup": "true", 35932 "aria-expanded": isOpen, 35933 onKeyDown: openOnArrowDown, 35934 label: label, 35935 icon: icon, 35936 showTooltip: true, 35937 disabled: isDisabled 35938 }); 35939 }, 35940 renderContent: () => (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalAlignmentMatrixControl, { 35941 hasFocusBorder: false, 35942 onChange: onChange, 35943 value: value 35944 }) 35945 }); 35946 } 35947 /* harmony default export */ const block_alignment_matrix_control = (BlockAlignmentMatrixControl); 35948 35949 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-title/use-block-display-title.js 35950 /** 35951 * WordPress dependencies 35952 */ 35953 35954 35955 35956 /** 35957 * Internal dependencies 35958 */ 35959 35960 35961 /** 35962 * Returns the block's configured title as a string, or empty if the title 35963 * cannot be determined. 35964 * 35965 * @example 35966 * 35967 * ```js 35968 * useBlockDisplayTitle( { clientId: 'afd1cb17-2c08-4e7a-91be-007ba7ddc3a1', maximumLength: 17 } ); 35969 * ``` 35970 * 35971 * @param {Object} props 35972 * @param {string} props.clientId Client ID of block. 35973 * @param {number|undefined} props.maximumLength The maximum length that the block title string may be before truncated. 35974 * @param {string|undefined} props.context The context to pass to `getBlockLabel`. 35975 * @return {?string} Block title. 35976 */ 35977 function useBlockDisplayTitle({ 35978 clientId, 35979 maximumLength, 35980 context 35981 }) { 35982 const blockTitle = (0,external_wp_data_namespaceObject.useSelect)(select => { 35983 if (!clientId) { 35984 return null; 35985 } 35986 const { 35987 getBlockName, 35988 getBlockAttributes 35989 } = select(store); 35990 const { 35991 getBlockType, 35992 getActiveBlockVariation 35993 } = select(external_wp_blocks_namespaceObject.store); 35994 const blockName = getBlockName(clientId); 35995 const blockType = getBlockType(blockName); 35996 if (!blockType) { 35997 return null; 35998 } 35999 const attributes = getBlockAttributes(clientId); 36000 const label = (0,external_wp_blocks_namespaceObject.__experimentalGetBlockLabel)(blockType, attributes, context); 36001 // If the label is defined we prioritize it over a possible block variation title match. 36002 if (label !== blockType.title) { 36003 return label; 36004 } 36005 const match = getActiveBlockVariation(blockName, attributes); 36006 // Label will fallback to the title if no label is defined for the current label context. 36007 return match?.title || blockType.title; 36008 }, [clientId, context]); 36009 if (!blockTitle) { 36010 return null; 36011 } 36012 if (maximumLength && maximumLength > 0 && blockTitle.length > maximumLength) { 36013 const omission = '...'; 36014 return blockTitle.slice(0, maximumLength - omission.length) + omission; 36015 } 36016 return blockTitle; 36017 } 36018 36019 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-title/index.js 36020 /** 36021 * Internal dependencies 36022 */ 36023 36024 36025 36026 /** 36027 * Renders the block's configured title as a string, or empty if the title 36028 * cannot be determined. 36029 * 36030 * @example 36031 * 36032 * ```jsx 36033 * <BlockTitle clientId="afd1cb17-2c08-4e7a-91be-007ba7ddc3a1" maximumLength={ 17 }/> 36034 * ``` 36035 * 36036 * @param {Object} props 36037 * @param {string} props.clientId Client ID of block. 36038 * @param {number|undefined} props.maximumLength The maximum length that the block title string may be before truncated. 36039 * @param {string|undefined} props.context The context to pass to `getBlockLabel`. 36040 * 36041 * @return {JSX.Element} Block title. 36042 */ 36043 function BlockTitle({ 36044 clientId, 36045 maximumLength, 36046 context 36047 }) { 36048 return useBlockDisplayTitle({ 36049 clientId, 36050 maximumLength, 36051 context 36052 }); 36053 } 36054 36055 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-breadcrumb/index.js 36056 36057 /** 36058 * WordPress dependencies 36059 */ 36060 36061 36062 36063 36064 36065 /** 36066 * Internal dependencies 36067 */ 36068 36069 36070 36071 36072 /** 36073 * Block breadcrumb component, displaying the hierarchy of the current block selection as a breadcrumb. 36074 * 36075 * @param {Object} props Component props. 36076 * @param {string} props.rootLabelText Translated label for the root element of the breadcrumb trail. 36077 * @return {Element} Block Breadcrumb. 36078 */ 36079 function BlockBreadcrumb({ 36080 rootLabelText 36081 }) { 36082 const { 36083 selectBlock, 36084 clearSelectedBlock 36085 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 36086 const { 36087 clientId, 36088 parents, 36089 hasSelection 36090 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 36091 const { 36092 getSelectionStart, 36093 getSelectedBlockClientId, 36094 getEnabledBlockParents 36095 } = unlock(select(store)); 36096 const selectedBlockClientId = getSelectedBlockClientId(); 36097 return { 36098 parents: getEnabledBlockParents(selectedBlockClientId), 36099 clientId: selectedBlockClientId, 36100 hasSelection: !!getSelectionStart().clientId 36101 }; 36102 }, []); 36103 const rootLabel = rootLabelText || (0,external_wp_i18n_namespaceObject.__)('Document'); 36104 36105 /* 36106 * Disable reason: The `list` ARIA role is redundant but 36107 * Safari+VoiceOver won't announce the list otherwise. 36108 */ 36109 /* eslint-disable jsx-a11y/no-redundant-roles */ 36110 return (0,external_React_.createElement)("ul", { 36111 className: "block-editor-block-breadcrumb", 36112 role: "list", 36113 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Block breadcrumb') 36114 }, (0,external_React_.createElement)("li", { 36115 className: !hasSelection ? 'block-editor-block-breadcrumb__current' : undefined, 36116 "aria-current": !hasSelection ? 'true' : undefined 36117 }, hasSelection && (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 36118 className: "block-editor-block-breadcrumb__button", 36119 variant: "tertiary", 36120 onClick: clearSelectedBlock 36121 }, rootLabel), !hasSelection && rootLabel, !!clientId && (0,external_React_.createElement)(build_module_icon, { 36122 icon: chevron_right_small, 36123 className: "block-editor-block-breadcrumb__separator" 36124 })), parents.map(parentClientId => (0,external_React_.createElement)("li", { 36125 key: parentClientId 36126 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 36127 className: "block-editor-block-breadcrumb__button", 36128 variant: "tertiary", 36129 onClick: () => selectBlock(parentClientId) 36130 }, (0,external_React_.createElement)(BlockTitle, { 36131 clientId: parentClientId, 36132 maximumLength: 35 36133 })), (0,external_React_.createElement)(build_module_icon, { 36134 icon: chevron_right_small, 36135 className: "block-editor-block-breadcrumb__separator" 36136 }))), !!clientId && (0,external_React_.createElement)("li", { 36137 className: "block-editor-block-breadcrumb__current", 36138 "aria-current": "true" 36139 }, (0,external_React_.createElement)(BlockTitle, { 36140 clientId: clientId, 36141 maximumLength: 35 36142 }))) 36143 /* eslint-enable jsx-a11y/no-redundant-roles */; 36144 } 36145 /* harmony default export */ const block_breadcrumb = (BlockBreadcrumb); 36146 36147 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-content-overlay/index.js 36148 /** 36149 * WordPress dependencies 36150 */ 36151 36152 36153 /** 36154 * Internal dependencies 36155 */ 36156 36157 function useBlockOverlayActive(clientId) { 36158 return (0,external_wp_data_namespaceObject.useSelect)(select => { 36159 const { 36160 __unstableHasActiveBlockOverlayActive 36161 } = select(store); 36162 return __unstableHasActiveBlockOverlayActive(clientId); 36163 }, [clientId]); 36164 } 36165 36166 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-context/index.js 36167 36168 /** 36169 * WordPress dependencies 36170 */ 36171 36172 36173 /** @typedef {import('react').ReactNode} ReactNode */ 36174 36175 /** 36176 * @typedef BlockContextProviderProps 36177 * 36178 * @property {Record<string,*>} value Context value to merge with current 36179 * value. 36180 * @property {ReactNode} children Component children. 36181 */ 36182 36183 /** @type {import('react').Context<Record<string,*>>} */ 36184 const block_context_Context = (0,external_wp_element_namespaceObject.createContext)({}); 36185 36186 /** 36187 * Component which merges passed value with current consumed block context. 36188 * 36189 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-context/README.md 36190 * 36191 * @param {BlockContextProviderProps} props 36192 */ 36193 function BlockContextProvider({ 36194 value, 36195 children 36196 }) { 36197 const context = (0,external_wp_element_namespaceObject.useContext)(block_context_Context); 36198 const nextValue = (0,external_wp_element_namespaceObject.useMemo)(() => ({ 36199 ...context, 36200 ...value 36201 }), [context, value]); 36202 return (0,external_React_.createElement)(block_context_Context.Provider, { 36203 value: nextValue, 36204 children: children 36205 }); 36206 } 36207 /* harmony default export */ const block_context = (block_context_Context); 36208 36209 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-edit/edit.js 36210 36211 /** 36212 * External dependencies 36213 */ 36214 36215 36216 /** 36217 * WordPress dependencies 36218 */ 36219 36220 36221 36222 36223 /** 36224 * Internal dependencies 36225 */ 36226 36227 36228 /** 36229 * Default value used for blocks which do not define their own context needs, 36230 * used to guarantee that a block's `context` prop will always be an object. It 36231 * is assigned as a constant since it is always expected to be an empty object, 36232 * and in order to avoid unnecessary React reconciliations of a changing object. 36233 * 36234 * @type {{}} 36235 */ 36236 const DEFAULT_BLOCK_CONTEXT = {}; 36237 const Edit = props => { 36238 const { 36239 name 36240 } = props; 36241 const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(name); 36242 if (!blockType) { 36243 return null; 36244 } 36245 36246 // `edit` and `save` are functions or components describing the markup 36247 // with which a block is displayed. If `blockType` is valid, assign 36248 // them preferentially as the render value for the block. 36249 const Component = blockType.edit || blockType.save; 36250 return (0,external_React_.createElement)(Component, { 36251 ...props 36252 }); 36253 }; 36254 const EditWithFilters = (0,external_wp_components_namespaceObject.withFilters)('editor.BlockEdit')(Edit); 36255 const EditWithGeneratedProps = props => { 36256 const { 36257 attributes = {}, 36258 name 36259 } = props; 36260 const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(name); 36261 const blockContext = (0,external_wp_element_namespaceObject.useContext)(block_context); 36262 36263 // Assign context values using the block type's declared context needs. 36264 const context = (0,external_wp_element_namespaceObject.useMemo)(() => { 36265 return blockType && blockType.usesContext ? Object.fromEntries(Object.entries(blockContext).filter(([key]) => blockType.usesContext.includes(key))) : DEFAULT_BLOCK_CONTEXT; 36266 }, [blockType, blockContext]); 36267 if (!blockType) { 36268 return null; 36269 } 36270 if (blockType.apiVersion > 1) { 36271 return (0,external_React_.createElement)(EditWithFilters, { 36272 ...props, 36273 context: context 36274 }); 36275 } 36276 36277 // Generate a class name for the block's editable form. 36278 const generatedClassName = (0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, 'className', true) ? (0,external_wp_blocks_namespaceObject.getBlockDefaultClassName)(name) : null; 36279 const className = classnames_default()(generatedClassName, attributes.className, props.className); 36280 return (0,external_React_.createElement)(EditWithFilters, { 36281 ...props, 36282 context: context, 36283 className: className 36284 }); 36285 }; 36286 /* harmony default export */ const block_edit_edit = (EditWithGeneratedProps); 36287 36288 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-edit/index.js 36289 36290 /** 36291 * WordPress dependencies 36292 */ 36293 36294 36295 /** 36296 * Internal dependencies 36297 */ 36298 36299 36300 36301 /** 36302 * The `useBlockEditContext` hook provides information about the block this hook is being used in. 36303 * It returns an object with the `name`, `isSelected` state, and the `clientId` of the block. 36304 * It is useful if you want to create custom hooks that need access to the current blocks clientId 36305 * but don't want to rely on the data getting passed in as a parameter. 36306 * 36307 * @return {Object} Block edit context 36308 */ 36309 36310 function BlockEdit({ 36311 mayDisplayControls, 36312 mayDisplayParentControls, 36313 blockEditingMode, 36314 // The remaining props are passed through the BlockEdit filters and are thus 36315 // public API! 36316 ...props 36317 }) { 36318 const { 36319 name, 36320 isSelected, 36321 clientId, 36322 attributes = {}, 36323 __unstableLayoutClassNames 36324 } = props; 36325 const { 36326 layout = null, 36327 metadata = {} 36328 } = attributes; 36329 const { 36330 bindings 36331 } = metadata; 36332 const layoutSupport = (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, 'layout', false) || (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, '__experimentalLayout', false); 36333 return (0,external_React_.createElement)(Provider 36334 // It is important to return the same object if props haven't 36335 // changed to avoid unnecessary rerenders. 36336 // See https://reactjs.org/docs/context.html#caveats. 36337 , { 36338 value: (0,external_wp_element_namespaceObject.useMemo)(() => ({ 36339 name, 36340 isSelected, 36341 clientId, 36342 layout: layoutSupport ? layout : null, 36343 __unstableLayoutClassNames, 36344 // We use symbols in favour of an __unstable prefix to avoid 36345 // usage outside of the package (this context is exposed). 36346 [mayDisplayControlsKey]: mayDisplayControls, 36347 [mayDisplayParentControlsKey]: mayDisplayParentControls, 36348 [blockEditingModeKey]: blockEditingMode, 36349 [blockBindingsKey]: bindings 36350 }), [name, isSelected, clientId, layoutSupport, layout, __unstableLayoutClassNames, mayDisplayControls, mayDisplayParentControls, blockEditingMode, bindings]) 36351 }, (0,external_React_.createElement)(block_edit_edit, { 36352 ...props 36353 })); 36354 } 36355 36356 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/more-vertical.js 36357 36358 /** 36359 * WordPress dependencies 36360 */ 36361 36362 const moreVertical = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 36363 xmlns: "http://www.w3.org/2000/svg", 36364 viewBox: "0 0 24 24" 36365 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 36366 d: "M13 19h-2v-2h2v2zm0-6h-2v-2h2v2zm0-6h-2V5h2v2z" 36367 })); 36368 /* harmony default export */ const more_vertical = (moreVertical); 36369 36370 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/warning/index.js 36371 36372 /** 36373 * External dependencies 36374 */ 36375 36376 36377 /** 36378 * WordPress dependencies 36379 */ 36380 36381 36382 36383 36384 function Warning({ 36385 className, 36386 actions, 36387 children, 36388 secondaryActions 36389 }) { 36390 return (0,external_React_.createElement)("div", { 36391 style: { 36392 display: 'contents', 36393 all: 'initial' 36394 } 36395 }, (0,external_React_.createElement)("div", { 36396 className: classnames_default()(className, 'block-editor-warning') 36397 }, (0,external_React_.createElement)("div", { 36398 className: "block-editor-warning__contents" 36399 }, (0,external_React_.createElement)("p", { 36400 className: "block-editor-warning__message" 36401 }, children), (external_wp_element_namespaceObject.Children.count(actions) > 0 || secondaryActions) && (0,external_React_.createElement)("div", { 36402 className: "block-editor-warning__actions" 36403 }, external_wp_element_namespaceObject.Children.count(actions) > 0 && external_wp_element_namespaceObject.Children.map(actions, (action, i) => (0,external_React_.createElement)("span", { 36404 key: i, 36405 className: "block-editor-warning__action" 36406 }, action)), secondaryActions && (0,external_React_.createElement)(external_wp_components_namespaceObject.DropdownMenu, { 36407 className: "block-editor-warning__secondary", 36408 icon: more_vertical, 36409 label: (0,external_wp_i18n_namespaceObject.__)('More options'), 36410 popoverProps: { 36411 position: 'bottom left', 36412 className: 'block-editor-warning__dropdown' 36413 }, 36414 noIcons: true 36415 }, () => (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuGroup, null, secondaryActions.map((item, pos) => (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 36416 onClick: item.onClick, 36417 key: pos 36418 }, item.title)))))))); 36419 } 36420 36421 /** 36422 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/warning/README.md 36423 */ 36424 /* harmony default export */ const warning = (Warning); 36425 36426 // EXTERNAL MODULE: ./node_modules/diff/lib/diff/character.js 36427 var character = __webpack_require__(8021); 36428 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-compare/block-view.js 36429 36430 /** 36431 * WordPress dependencies 36432 */ 36433 36434 36435 36436 function BlockView({ 36437 title, 36438 rawContent, 36439 renderedContent, 36440 action, 36441 actionText, 36442 className 36443 }) { 36444 return (0,external_React_.createElement)("div", { 36445 className: className 36446 }, (0,external_React_.createElement)("div", { 36447 className: "block-editor-block-compare__content" 36448 }, (0,external_React_.createElement)("h2", { 36449 className: "block-editor-block-compare__heading" 36450 }, title), (0,external_React_.createElement)("div", { 36451 className: "block-editor-block-compare__html" 36452 }, rawContent), (0,external_React_.createElement)("div", { 36453 className: "block-editor-block-compare__preview edit-post-visual-editor" 36454 }, (0,external_React_.createElement)(external_wp_element_namespaceObject.RawHTML, null, (0,external_wp_dom_namespaceObject.safeHTML)(renderedContent)))), (0,external_React_.createElement)("div", { 36455 className: "block-editor-block-compare__action" 36456 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 36457 variant: "secondary", 36458 tabIndex: "0", 36459 onClick: action 36460 }, actionText))); 36461 } 36462 36463 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-compare/index.js 36464 36465 /** 36466 * External dependencies 36467 */ 36468 36469 // diff doesn't tree-shake correctly, so we import from the individual 36470 // module here, to avoid including too much of the library 36471 36472 36473 /** 36474 * WordPress dependencies 36475 */ 36476 36477 36478 36479 /** 36480 * Internal dependencies 36481 */ 36482 36483 function BlockCompare({ 36484 block, 36485 onKeep, 36486 onConvert, 36487 convertor, 36488 convertButtonText 36489 }) { 36490 function getDifference(originalContent, newContent) { 36491 const difference = (0,character/* diffChars */.JJ)(originalContent, newContent); 36492 return difference.map((item, pos) => { 36493 const classes = classnames_default()({ 36494 'block-editor-block-compare__added': item.added, 36495 'block-editor-block-compare__removed': item.removed 36496 }); 36497 return (0,external_React_.createElement)("span", { 36498 key: pos, 36499 className: classes 36500 }, item.value); 36501 }); 36502 } 36503 function getConvertedContent(convertedBlock) { 36504 // The convertor may return an array of items or a single item. 36505 const newBlocks = Array.isArray(convertedBlock) ? convertedBlock : [convertedBlock]; 36506 36507 // Get converted block details. 36508 const newContent = newBlocks.map(item => (0,external_wp_blocks_namespaceObject.getSaveContent)(item.name, item.attributes, item.innerBlocks)); 36509 return newContent.join(''); 36510 } 36511 const converted = getConvertedContent(convertor(block)); 36512 const difference = getDifference(block.originalContent, converted); 36513 return (0,external_React_.createElement)("div", { 36514 className: "block-editor-block-compare__wrapper" 36515 }, (0,external_React_.createElement)(BlockView, { 36516 title: (0,external_wp_i18n_namespaceObject.__)('Current'), 36517 className: "block-editor-block-compare__current", 36518 action: onKeep, 36519 actionText: (0,external_wp_i18n_namespaceObject.__)('Convert to HTML'), 36520 rawContent: block.originalContent, 36521 renderedContent: block.originalContent 36522 }), (0,external_React_.createElement)(BlockView, { 36523 title: (0,external_wp_i18n_namespaceObject.__)('After Conversion'), 36524 className: "block-editor-block-compare__converted", 36525 action: onConvert, 36526 actionText: convertButtonText, 36527 rawContent: difference, 36528 renderedContent: converted 36529 })); 36530 } 36531 /* harmony default export */ const block_compare = (BlockCompare); 36532 36533 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/block-invalid-warning.js 36534 36535 /** 36536 * WordPress dependencies 36537 */ 36538 36539 36540 36541 36542 36543 36544 /** 36545 * Internal dependencies 36546 */ 36547 36548 36549 36550 const blockToBlocks = block => (0,external_wp_blocks_namespaceObject.rawHandler)({ 36551 HTML: block.originalContent 36552 }); 36553 function BlockInvalidWarning({ 36554 clientId 36555 }) { 36556 const { 36557 block, 36558 canInsertHTMLBlock, 36559 canInsertClassicBlock 36560 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 36561 const { 36562 canInsertBlockType, 36563 getBlock, 36564 getBlockRootClientId 36565 } = select(store); 36566 const rootClientId = getBlockRootClientId(clientId); 36567 return { 36568 block: getBlock(clientId), 36569 canInsertHTMLBlock: canInsertBlockType('core/html', rootClientId), 36570 canInsertClassicBlock: canInsertBlockType('core/freeform', rootClientId) 36571 }; 36572 }, [clientId]); 36573 const { 36574 replaceBlock 36575 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 36576 const [compare, setCompare] = (0,external_wp_element_namespaceObject.useState)(false); 36577 const onCompareClose = (0,external_wp_element_namespaceObject.useCallback)(() => setCompare(false), []); 36578 const convert = (0,external_wp_element_namespaceObject.useMemo)(() => ({ 36579 toClassic() { 36580 const classicBlock = (0,external_wp_blocks_namespaceObject.createBlock)('core/freeform', { 36581 content: block.originalContent 36582 }); 36583 return replaceBlock(block.clientId, classicBlock); 36584 }, 36585 toHTML() { 36586 const htmlBlock = (0,external_wp_blocks_namespaceObject.createBlock)('core/html', { 36587 content: block.originalContent 36588 }); 36589 return replaceBlock(block.clientId, htmlBlock); 36590 }, 36591 toBlocks() { 36592 const newBlocks = blockToBlocks(block); 36593 return replaceBlock(block.clientId, newBlocks); 36594 }, 36595 toRecoveredBlock() { 36596 const recoveredBlock = (0,external_wp_blocks_namespaceObject.createBlock)(block.name, block.attributes, block.innerBlocks); 36597 return replaceBlock(block.clientId, recoveredBlock); 36598 } 36599 }), [block, replaceBlock]); 36600 const secondaryActions = (0,external_wp_element_namespaceObject.useMemo)(() => [{ 36601 // translators: Button to fix block content 36602 title: (0,external_wp_i18n_namespaceObject._x)('Resolve', 'imperative verb'), 36603 onClick: () => setCompare(true) 36604 }, canInsertHTMLBlock && { 36605 title: (0,external_wp_i18n_namespaceObject.__)('Convert to HTML'), 36606 onClick: convert.toHTML 36607 }, canInsertClassicBlock && { 36608 title: (0,external_wp_i18n_namespaceObject.__)('Convert to Classic Block'), 36609 onClick: convert.toClassic 36610 }].filter(Boolean), [canInsertHTMLBlock, canInsertClassicBlock, convert]); 36611 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(warning, { 36612 actions: [(0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 36613 key: "recover", 36614 onClick: convert.toRecoveredBlock, 36615 variant: "primary" 36616 }, (0,external_wp_i18n_namespaceObject.__)('Attempt Block Recovery'))], 36617 secondaryActions: secondaryActions 36618 }, (0,external_wp_i18n_namespaceObject.__)('This block contains unexpected or invalid content.')), compare && (0,external_React_.createElement)(external_wp_components_namespaceObject.Modal, { 36619 title: 36620 // translators: Dialog title to fix block content 36621 (0,external_wp_i18n_namespaceObject.__)('Resolve Block'), 36622 onRequestClose: onCompareClose, 36623 className: "block-editor-block-compare" 36624 }, (0,external_React_.createElement)(block_compare, { 36625 block: block, 36626 onKeep: convert.toHTML, 36627 onConvert: convert.toBlocks, 36628 convertor: blockToBlocks, 36629 convertButtonText: (0,external_wp_i18n_namespaceObject.__)('Convert to Blocks') 36630 }))); 36631 } 36632 36633 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/block-crash-warning.js 36634 36635 /** 36636 * WordPress dependencies 36637 */ 36638 36639 36640 /** 36641 * Internal dependencies 36642 */ 36643 36644 const block_crash_warning_warning = (0,external_React_.createElement)(warning, { 36645 className: "block-editor-block-list__block-crash-warning" 36646 }, (0,external_wp_i18n_namespaceObject.__)('This block has encountered an error and cannot be previewed.')); 36647 /* harmony default export */ const block_crash_warning = (() => block_crash_warning_warning); 36648 36649 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/block-crash-boundary.js 36650 /** 36651 * WordPress dependencies 36652 */ 36653 36654 class BlockCrashBoundary extends external_wp_element_namespaceObject.Component { 36655 constructor() { 36656 super(...arguments); 36657 this.state = { 36658 hasError: false 36659 }; 36660 } 36661 componentDidCatch() { 36662 this.setState({ 36663 hasError: true 36664 }); 36665 } 36666 render() { 36667 if (this.state.hasError) { 36668 return this.props.fallback; 36669 } 36670 return this.props.children; 36671 } 36672 } 36673 /* harmony default export */ const block_crash_boundary = (BlockCrashBoundary); 36674 36675 // EXTERNAL MODULE: ./node_modules/react-autosize-textarea/lib/index.js 36676 var react_autosize_textarea_lib = __webpack_require__(4132); 36677 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/block-html.js 36678 36679 /** 36680 * External dependencies 36681 */ 36682 36683 36684 /** 36685 * WordPress dependencies 36686 */ 36687 36688 36689 36690 36691 /** 36692 * Internal dependencies 36693 */ 36694 36695 function BlockHTML({ 36696 clientId 36697 }) { 36698 const [html, setHtml] = (0,external_wp_element_namespaceObject.useState)(''); 36699 const block = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getBlock(clientId), [clientId]); 36700 const { 36701 updateBlock 36702 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 36703 const onChange = () => { 36704 const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(block.name); 36705 if (!blockType) { 36706 return; 36707 } 36708 const attributes = (0,external_wp_blocks_namespaceObject.getBlockAttributes)(blockType, html, block.attributes); 36709 36710 // If html is empty we reset the block to the default HTML and mark it as valid to avoid triggering an error 36711 const content = html ? html : (0,external_wp_blocks_namespaceObject.getSaveContent)(blockType, attributes); 36712 const [isValid] = html ? (0,external_wp_blocks_namespaceObject.validateBlock)({ 36713 ...block, 36714 attributes, 36715 originalContent: content 36716 }) : [true]; 36717 updateBlock(clientId, { 36718 attributes, 36719 originalContent: content, 36720 isValid 36721 }); 36722 36723 // Ensure the state is updated if we reset so it displays the default content. 36724 if (!html) { 36725 setHtml(content); 36726 } 36727 }; 36728 (0,external_wp_element_namespaceObject.useEffect)(() => { 36729 setHtml((0,external_wp_blocks_namespaceObject.getBlockContent)(block)); 36730 }, [block]); 36731 return (0,external_React_.createElement)(react_autosize_textarea_lib/* default */.A, { 36732 className: "block-editor-block-list__block-html-textarea", 36733 value: html, 36734 onBlur: onChange, 36735 onChange: event => setHtml(event.target.value) 36736 }); 36737 } 36738 /* harmony default export */ const block_html = (BlockHTML); 36739 36740 ;// CONCATENATED MODULE: ./node_modules/@react-spring/rafz/dist/esm/index.js 36741 var esm_f=esm_l(),esm_n=e=>esm_c(e,esm_f),esm_m=esm_l();esm_n.write=e=>esm_c(e,esm_m);var esm_d=esm_l();esm_n.onStart=e=>esm_c(e,esm_d);var esm_h=esm_l();esm_n.onFrame=e=>esm_c(e,esm_h);var esm_p=esm_l();esm_n.onFinish=e=>esm_c(e,esm_p);var esm_i=[];esm_n.setTimeout=(e,t)=>{let a=esm_n.now()+t,o=()=>{let F=esm_i.findIndex(z=>z.cancel==o);~F&&esm_i.splice(F,1),esm_u-=~F?1:0},s={time:a,handler:e,cancel:o};return esm_i.splice(esm_w(a),0,s),esm_u+=1,esm_v(),s};var esm_w=e=>~(~esm_i.findIndex(t=>t.time>e)||~esm_i.length);esm_n.cancel=e=>{esm_d.delete(e),esm_h.delete(e),esm_p.delete(e),esm_f.delete(e),esm_m.delete(e)};esm_n.sync=e=>{T=!0,esm_n.batchedUpdates(e),T=!1};esm_n.throttle=e=>{let t;function a(){try{e(...t)}finally{t=null}}function o(...s){t=s,esm_n.onStart(a)}return o.handler=e,o.cancel=()=>{esm_d.delete(a),t=null},o};var esm_y=typeof window<"u"?window.requestAnimationFrame:()=>{};esm_n.use=e=>esm_y=e;esm_n.now=typeof performance<"u"?()=>performance.now():Date.now;esm_n.batchedUpdates=e=>e();esm_n.catch=console.error;esm_n.frameLoop="always";esm_n.advance=()=>{esm_n.frameLoop!=="demand"?console.warn("Cannot call the manual advancement of rafz whilst frameLoop is not set as demand"):esm_x()};var esm_r=-1,esm_u=0,T=!1;function esm_c(e,t){T?(t.delete(e),e(0)):(t.add(e),esm_v())}function esm_v(){esm_r<0&&(esm_r=0,esm_n.frameLoop!=="demand"&&esm_y(esm_b))}function esm_R(){esm_r=-1}function esm_b(){~esm_r&&(esm_y(esm_b),esm_n.batchedUpdates(esm_x))}function esm_x(){let e=esm_r;esm_r=esm_n.now();let t=esm_w(esm_r);if(t&&(Q(esm_i.splice(0,t),a=>a.handler()),esm_u-=t),!esm_u){esm_R();return}esm_d.flush(),esm_f.flush(e?Math.min(64,esm_r-e):16.667),esm_h.flush(),esm_m.flush(),esm_p.flush()}function esm_l(){let e=new Set,t=e;return{add(a){esm_u+=t==e&&!e.has(a)?1:0,e.add(a)},delete(a){return esm_u-=t==e&&e.has(a)?1:0,e.delete(a)},flush(a){t.size&&(e=new Set,esm_u-=t.size,Q(t,o=>o(a)&&e.add(o)),esm_u+=e.size,t=e)}}}function Q(e,t){e.forEach(a=>{try{t(a)}catch(o){esm_n.catch(o)}})}var esm_S={count(){return esm_u},isRunning(){return esm_r>=0},clear(){esm_r=-1,esm_i=[],esm_d=esm_l(),esm_f=esm_l(),esm_h=esm_l(),esm_m=esm_l(),esm_p=esm_l(),esm_u=0}}; 36742 36743 ;// CONCATENATED MODULE: ./node_modules/@react-spring/shared/dist/esm/index.js 36744 var ze=Object.defineProperty;var Le=(e,t)=>{for(var r in t)ze(e,r,{get:t[r],enumerable:!0})};var dist_esm_p={};Le(dist_esm_p,{assign:()=>U,colors:()=>dist_esm_c,createStringInterpolator:()=>esm_k,skipAnimation:()=>ee,to:()=>J,willAdvance:()=>dist_esm_S});function Y(){}var mt=(e,t,r)=>Object.defineProperty(e,t,{value:r,writable:!0,configurable:!0}),dist_esm_l={arr:Array.isArray,obj:e=>!!e&&e.constructor.name==="Object",fun:e=>typeof e=="function",str:e=>typeof e=="string",num:e=>typeof e=="number",und:e=>e===void 0};function bt(e,t){if(dist_esm_l.arr(e)){if(!dist_esm_l.arr(t)||e.length!==t.length)return!1;for(let r=0;r<e.length;r++)if(e[r]!==t[r])return!1;return!0}return e===t}var esm_Ve=(e,t)=>e.forEach(t);function xt(e,t,r){if(dist_esm_l.arr(e)){for(let n=0;n<e.length;n++)t.call(r,e[n],`$n}`);return}for(let n in e)e.hasOwnProperty(n)&&t.call(r,e[n],n)}var ht=e=>dist_esm_l.und(e)?[]:dist_esm_l.arr(e)?e:[e];function Pe(e,t){if(e.size){let r=Array.from(e);e.clear(),esm_Ve(r,t)}}var yt=(e,...t)=>Pe(e,r=>r(...t)),dist_esm_h=()=>typeof window>"u"||!window.navigator||/ServerSideRendering|^Deno\//.test(window.navigator.userAgent);var esm_k,J,dist_esm_c=null,ee=!1,dist_esm_S=Y,U=e=>{e.to&&(J=e.to),e.now&&(esm_n.now=e.now),e.colors!==void 0&&(dist_esm_c=e.colors),e.skipAnimation!=null&&(ee=e.skipAnimation),e.createStringInterpolator&&(esm_k=e.createStringInterpolator),e.requestAnimationFrame&&esm_n.use(e.requestAnimationFrame),e.batchedUpdates&&(esm_n.batchedUpdates=e.batchedUpdates),e.willAdvance&&(dist_esm_S=e.willAdvance),e.frameLoop&&(esm_n.frameLoop=e.frameLoop)};var esm_E=new Set,dist_esm_u=[],esm_H=[],A=0,qe={get idle(){return!esm_E.size&&!dist_esm_u.length},start(e){A>e.priority?(esm_E.add(e),esm_n.onStart($e)):(te(e),esm_n(B))},advance:B,sort(e){if(A)esm_n.onFrame(()=>qe.sort(e));else{let t=dist_esm_u.indexOf(e);~t&&(dist_esm_u.splice(t,1),re(e))}},clear(){dist_esm_u=[],esm_E.clear()}};function $e(){esm_E.forEach(te),esm_E.clear(),esm_n(B)}function te(e){dist_esm_u.includes(e)||re(e)}function re(e){dist_esm_u.splice(Ge(dist_esm_u,t=>t.priority>e.priority),0,e)}function B(e){let t=esm_H;for(let r=0;r<dist_esm_u.length;r++){let n=dist_esm_u[r];A=n.priority,n.idle||(dist_esm_S(n),n.advance(e),n.idle||t.push(n))}return A=0,esm_H=dist_esm_u,esm_H.length=0,dist_esm_u=t,dist_esm_u.length>0}function Ge(e,t){let r=e.findIndex(t);return r<0?e.length:r}var ne=(e,t,r)=>Math.min(Math.max(r,e),t);var It={transparent:0,aliceblue:4042850303,antiquewhite:4209760255,aqua:16777215,aquamarine:2147472639,azure:4043309055,beige:4126530815,bisque:4293182719,black:255,blanchedalmond:4293643775,blue:65535,blueviolet:2318131967,brown:2771004159,burlywood:3736635391,burntsienna:3934150143,cadetblue:1604231423,chartreuse:2147418367,chocolate:3530104575,coral:4286533887,cornflowerblue:1687547391,cornsilk:4294499583,crimson:3692313855,cyan:16777215,darkblue:35839,darkcyan:9145343,darkgoldenrod:3095792639,darkgray:2846468607,darkgreen:6553855,darkgrey:2846468607,darkkhaki:3182914559,darkmagenta:2332068863,darkolivegreen:1433087999,darkorange:4287365375,darkorchid:2570243327,darkred:2332033279,darksalmon:3918953215,darkseagreen:2411499519,darkslateblue:1211993087,darkslategray:793726975,darkslategrey:793726975,darkturquoise:13554175,darkviolet:2483082239,deeppink:4279538687,deepskyblue:12582911,dimgray:1768516095,dimgrey:1768516095,dodgerblue:512819199,firebrick:2988581631,floralwhite:4294635775,forestgreen:579543807,fuchsia:4278255615,gainsboro:3705462015,ghostwhite:4177068031,gold:4292280575,goldenrod:3668254975,gray:2155905279,green:8388863,greenyellow:2919182335,grey:2155905279,honeydew:4043305215,hotpink:4285117695,indianred:3445382399,indigo:1258324735,ivory:4294963455,khaki:4041641215,lavender:3873897215,lavenderblush:4293981695,lawngreen:2096890111,lemonchiffon:4294626815,lightblue:2916673279,lightcoral:4034953471,lightcyan:3774873599,lightgoldenrodyellow:4210742015,lightgray:3553874943,lightgreen:2431553791,lightgrey:3553874943,lightpink:4290167295,lightsalmon:4288707327,lightseagreen:548580095,lightskyblue:2278488831,lightslategray:2005441023,lightslategrey:2005441023,lightsteelblue:2965692159,lightyellow:4294959359,lime:16711935,limegreen:852308735,linen:4210091775,magenta:4278255615,maroon:2147483903,mediumaquamarine:1724754687,mediumblue:52735,mediumorchid:3126187007,mediumpurple:2473647103,mediumseagreen:1018393087,mediumslateblue:2070474495,mediumspringgreen:16423679,mediumturquoise:1221709055,mediumvioletred:3340076543,midnightblue:421097727,mintcream:4127193855,mistyrose:4293190143,moccasin:4293178879,navajowhite:4292783615,navy:33023,oldlace:4260751103,olive:2155872511,olivedrab:1804477439,orange:4289003775,orangered:4282712319,orchid:3664828159,palegoldenrod:4008225535,palegreen:2566625535,paleturquoise:2951671551,palevioletred:3681588223,papayawhip:4293907967,peachpuff:4292524543,peru:3448061951,pink:4290825215,plum:3718307327,powderblue:2967529215,purple:2147516671,rebeccapurple:1714657791,red:4278190335,rosybrown:3163525119,royalblue:1097458175,saddlebrown:2336560127,salmon:4202722047,sandybrown:4104413439,seagreen:780883967,seashell:4294307583,sienna:2689740287,silver:3233857791,skyblue:2278484991,slateblue:1784335871,slategray:1887473919,slategrey:1887473919,snow:4294638335,springgreen:16744447,steelblue:1182971135,tan:3535047935,teal:8421631,thistle:3636451583,tomato:4284696575,turquoise:1088475391,violet:4001558271,wheat:4125012991,white:4294967295,whitesmoke:4126537215,yellow:4294902015,yellowgreen:2597139199};var dist_esm_d="[-+]?\\d*\\.?\\d+",esm_M=dist_esm_d+"%";function C(...e){return"\\(\\s*("+e.join(")\\s*,\\s*(")+")\\s*\\)"}var oe=new RegExp("rgb"+C(dist_esm_d,dist_esm_d,dist_esm_d)),fe=new RegExp("rgba"+C(dist_esm_d,dist_esm_d,dist_esm_d,dist_esm_d)),ae=new RegExp("hsl"+C(dist_esm_d,esm_M,esm_M)),ie=new RegExp("hsla"+C(dist_esm_d,esm_M,esm_M,dist_esm_d)),se=/^#([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,ue=/^#([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,le=/^#([0-9a-fA-F]{6})$/,esm_ce=/^#([0-9a-fA-F]{8})$/;function be(e){let t;return typeof e=="number"?e>>>0===e&&e>=0&&e<=4294967295?e:null:(t=le.exec(e))?parseInt(t[1]+"ff",16)>>>0:dist_esm_c&&dist_esm_c[e]!==void 0?dist_esm_c[e]:(t=oe.exec(e))?(dist_esm_y(t[1])<<24|dist_esm_y(t[2])<<16|dist_esm_y(t[3])<<8|255)>>>0:(t=fe.exec(e))?(dist_esm_y(t[1])<<24|dist_esm_y(t[2])<<16|dist_esm_y(t[3])<<8|me(t[4]))>>>0:(t=se.exec(e))?parseInt(t[1]+t[1]+t[2]+t[2]+t[3]+t[3]+"ff",16)>>>0:(t=esm_ce.exec(e))?parseInt(t[1],16)>>>0:(t=ue.exec(e))?parseInt(t[1]+t[1]+t[2]+t[2]+t[3]+t[3]+t[4]+t[4],16)>>>0:(t=ae.exec(e))?(de(esm_pe(t[1]),esm_z(t[2]),esm_z(t[3]))|255)>>>0:(t=ie.exec(e))?(de(esm_pe(t[1]),esm_z(t[2]),esm_z(t[3]))|me(t[4]))>>>0:null}function esm_j(e,t,r){return r<0&&(r+=1),r>1&&(r-=1),r<1/6?e+(t-e)*6*r:r<1/2?t:r<2/3?e+(t-e)*(2/3-r)*6:e}function de(e,t,r){let n=r<.5?r*(1+t):r+t-r*t,f=2*r-n,o=esm_j(f,n,e+1/3),i=esm_j(f,n,e),s=esm_j(f,n,e-1/3);return Math.round(o*255)<<24|Math.round(i*255)<<16|Math.round(s*255)<<8}function dist_esm_y(e){let t=parseInt(e,10);return t<0?0:t>255?255:t}function esm_pe(e){return(parseFloat(e)%360+360)%360/360}function me(e){let t=parseFloat(e);return t<0?0:t>1?255:Math.round(t*255)}function esm_z(e){let t=parseFloat(e);return t<0?0:t>100?1:t/100}function D(e){let t=be(e);if(t===null)return e;t=t||0;let r=(t&4278190080)>>>24,n=(t&16711680)>>>16,f=(t&65280)>>>8,o=(t&255)/255;return`rgba($r}, $n}, $f}, $o})`}var W=(e,t,r)=>{if(dist_esm_l.fun(e))return e;if(dist_esm_l.arr(e))return W({range:e,output:t,extrapolate:r});if(dist_esm_l.str(e.output[0]))return esm_k(e);let n=e,f=n.output,o=n.range||[0,1],i=n.extrapolateLeft||n.extrapolate||"extend",s=n.extrapolateRight||n.extrapolate||"extend",x=n.easing||(a=>a);return a=>{let F=He(a,o);return Ue(a,o[F],o[F+1],f[F],f[F+1],x,i,s,n.map)}};function Ue(e,t,r,n,f,o,i,s,x){let a=x?x(e):e;if(a<t){if(i==="identity")return a;i==="clamp"&&(a=t)}if(a>r){if(s==="identity")return a;s==="clamp"&&(a=r)}return n===f?n:t===r?e<=t?n:f:(t===-1/0?a=-a:r===1/0?a=a-t:a=(a-t)/(r-t),a=o(a),n===-1/0?a=-a:f===1/0?a=a+n:a=a*(f-n)+n,a)}function He(e,t){for(var r=1;r<t.length-1&&!(t[r]>=e);++r);return r-1}var Be=(e,t="end")=>r=>{r=t==="end"?Math.min(r,.999):Math.max(r,.001);let n=r*e,f=t==="end"?Math.floor(n):Math.ceil(n);return ne(0,1,f/e)},P=1.70158,L=P*1.525,xe=P+1,he=2*Math.PI/3,ye=2*Math.PI/4.5,V=e=>e<1/2.75?7.5625*e*e:e<2/2.75?7.5625*(e-=1.5/2.75)*e+.75:e<2.5/2.75?7.5625*(e-=2.25/2.75)*e+.9375:7.5625*(e-=2.625/2.75)*e+.984375,Lt={linear:e=>e,easeInQuad:e=>e*e,easeOutQuad:e=>1-(1-e)*(1-e),easeInOutQuad:e=>e<.5?2*e*e:1-Math.pow(-2*e+2,2)/2,easeInCubic:e=>e*e*e,easeOutCubic:e=>1-Math.pow(1-e,3),easeInOutCubic:e=>e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,easeInQuart:e=>e*e*e*e,easeOutQuart:e=>1-Math.pow(1-e,4),easeInOutQuart:e=>e<.5?8*e*e*e*e:1-Math.pow(-2*e+2,4)/2,easeInQuint:e=>e*e*e*e*e,easeOutQuint:e=>1-Math.pow(1-e,5),easeInOutQuint:e=>e<.5?16*e*e*e*e*e:1-Math.pow(-2*e+2,5)/2,easeInSine:e=>1-Math.cos(e*Math.PI/2),easeOutSine:e=>Math.sin(e*Math.PI/2),easeInOutSine:e=>-(Math.cos(Math.PI*e)-1)/2,easeInExpo:e=>e===0?0:Math.pow(2,10*e-10),easeOutExpo:e=>e===1?1:1-Math.pow(2,-10*e),easeInOutExpo:e=>e===0?0:e===1?1:e<.5?Math.pow(2,20*e-10)/2:(2-Math.pow(2,-20*e+10))/2,easeInCirc:e=>1-Math.sqrt(1-Math.pow(e,2)),easeOutCirc:e=>Math.sqrt(1-Math.pow(e-1,2)),easeInOutCirc:e=>e<.5?(1-Math.sqrt(1-Math.pow(2*e,2)))/2:(Math.sqrt(1-Math.pow(-2*e+2,2))+1)/2,easeInBack:e=>xe*e*e*e-P*e*e,easeOutBack:e=>1+xe*Math.pow(e-1,3)+P*Math.pow(e-1,2),easeInOutBack:e=>e<.5?Math.pow(2*e,2)*((L+1)*2*e-L)/2:(Math.pow(2*e-2,2)*((L+1)*(e*2-2)+L)+2)/2,easeInElastic:e=>e===0?0:e===1?1:-Math.pow(2,10*e-10)*Math.sin((e*10-10.75)*he),easeOutElastic:e=>e===0?0:e===1?1:Math.pow(2,-10*e)*Math.sin((e*10-.75)*he)+1,easeInOutElastic:e=>e===0?0:e===1?1:e<.5?-(Math.pow(2,20*e-10)*Math.sin((20*e-11.125)*ye))/2:Math.pow(2,-20*e+10)*Math.sin((20*e-11.125)*ye)/2+1,easeInBounce:e=>1-V(1-e),easeOutBounce:V,easeInOutBounce:e=>e<.5?(1-V(1-2*e))/2:(1+V(2*e-1))/2,steps:Be};var esm_g=Symbol.for("FluidValue.get"),dist_esm_m=Symbol.for("FluidValue.observers");var Pt=e=>Boolean(e&&e[esm_g]),ve=e=>e&&e[esm_g]?e[esm_g]():e,esm_qt=e=>e[dist_esm_m]||null;function je(e,t){e.eventObserved?e.eventObserved(t):e(t)}function $t(e,t){let r=e[dist_esm_m];r&&r.forEach(n=>{je(n,t)})}var esm_ge=class{[esm_g];[dist_esm_m];constructor(t){if(!t&&!(t=this.get))throw Error("Unknown getter");De(this,t)}},De=(e,t)=>Ee(e,esm_g,t);function Gt(e,t){if(e[esm_g]){let r=e[dist_esm_m];r||Ee(e,dist_esm_m,r=new Set),r.has(t)||(r.add(t),e.observerAdded&&e.observerAdded(r.size,t))}return t}function Qt(e,t){let r=e[dist_esm_m];if(r&&r.has(t)){let n=r.size-1;n?r.delete(t):e[dist_esm_m]=null,e.observerRemoved&&e.observerRemoved(n,t)}}var Ee=(e,t,r)=>Object.defineProperty(e,t,{value:r,writable:!0,configurable:!0});var O=/[+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,esm_Oe=/(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d\.]+%?\))/gi,K=new RegExp(`($O.source})(%|[a-z]+)`,"i"),we=/rgba\(([0-9\.-]+), ([0-9\.-]+), ([0-9\.-]+), ([0-9\.-]+)\)/gi,dist_esm_b=/var\((--[a-zA-Z0-9-_]+),? ?([a-zA-Z0-9 ()%#.,-]+)?\)/;var esm_N=e=>{let[t,r]=We(e);if(!t||dist_esm_h())return e;let n=window.getComputedStyle(document.documentElement).getPropertyValue(t);if(n)return n.trim();if(r&&r.startsWith("--")){let f=window.getComputedStyle(document.documentElement).getPropertyValue(r);return f||e}else{if(r&&dist_esm_b.test(r))return esm_N(r);if(r)return r}return e},We=e=>{let t=dist_esm_b.exec(e);if(!t)return[,];let[,r,n]=t;return[r,n]};var _,esm_Ke=(e,t,r,n,f)=>`rgba($Math.round(t)}, $Math.round(r)}, $Math.round(n)}, $f})`,Xt=e=>{_||(_=dist_esm_c?new RegExp(`($Object.keys(dist_esm_c).join("|")})(?!\\w)`,"g"):/^\b$/);let t=e.output.map(o=>ve(o).replace(dist_esm_b,esm_N).replace(esm_Oe,D).replace(_,D)),r=t.map(o=>o.match(O).map(Number)),f=r[0].map((o,i)=>r.map(s=>{if(!(i in s))throw Error('The arity of each "output" value must be equal');return s[i]})).map(o=>W({...e,output:o}));return o=>{let i=!K.test(t[0])&&t.find(x=>K.test(x))?.replace(O,""),s=0;return t[0].replace(O,()=>`$f[s++](o)}$i||""}`).replace(we,esm_Ke)}};var Z="react-spring: ",Te=e=>{let t=e,r=!1;if(typeof t!="function")throw new TypeError(`$Z}once requires a function parameter`);return(...n)=>{r||(t(...n),r=!0)}},Ne=Te(console.warn);function Jt(){Ne(`$Z}The "interpolate" function is deprecated in v9 (use "to" instead)`)}var _e=Te(console.warn);function er(){_e(`$Z}Directly calling start instead of using the api object is deprecated in v9 (use ".start" instead), this will be removed in later 0.X.0 versions`)}function esm_or(e){return dist_esm_l.str(e)&&(e[0]=="#"||/\d/.test(e)||!dist_esm_h()&&dist_esm_b.test(e)||e in(dist_esm_c||{}))}var dist_esm_v,q=new WeakMap,Ze=e=>e.forEach(({target:t,contentRect:r})=>q.get(t)?.forEach(n=>n(r)));function Fe(e,t){dist_esm_v||typeof ResizeObserver<"u"&&(dist_esm_v=new ResizeObserver(Ze));let r=q.get(t);return r||(r=new Set,q.set(t,r)),r.add(e),dist_esm_v&&dist_esm_v.observe(t),()=>{let n=q.get(t);!n||(n.delete(e),!n.size&&dist_esm_v&&dist_esm_v.unobserve(t))}}var esm_$=new Set,dist_esm_w,esm_Xe=()=>{let e=()=>{esm_$.forEach(t=>t({width:window.innerWidth,height:window.innerHeight}))};return window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e)}},Ie=e=>(esm_$.add(e),dist_esm_w||(dist_esm_w=esm_Xe()),()=>{esm_$.delete(e),!esm_$.size&&dist_esm_w&&(dist_esm_w(),dist_esm_w=void 0)});var ke=(e,{container:t=document.documentElement}={})=>t===document.documentElement?Ie(e):Fe(e,t);var Se=(e,t,r)=>t-e===0?1:(r-e)/(t-e);var esm_Ye={x:{length:"Width",position:"Left"},y:{length:"Height",position:"Top"}},esm_G=class{callback;container;info;constructor(t,r){this.callback=t,this.container=r,this.info={time:0,x:this.createAxis(),y:this.createAxis()}}createAxis=()=>({current:0,progress:0,scrollLength:0});updateAxis=t=>{let r=this.info[t],{length:n,position:f}=esm_Ye[t];r.current=this.container[`scroll$f}`],r.scrollLength=this.container["scroll"+n]-this.container["client"+n],r.progress=Se(0,r.scrollLength,r.current)};update=()=>{this.updateAxis("x"),this.updateAxis("y")};sendEvent=()=>{this.callback(this.info)};advance=()=>{this.update(),this.sendEvent()}};var esm_T=new WeakMap,Ae=new WeakMap,X=new WeakMap,Me=e=>e===document.documentElement?window:e,yr=(e,{container:t=document.documentElement}={})=>{let r=X.get(t);r||(r=new Set,X.set(t,r));let n=new esm_G(e,t);if(r.add(n),!esm_T.has(t)){let o=()=>(r?.forEach(s=>s.advance()),!0);esm_T.set(t,o);let i=Me(t);window.addEventListener("resize",o,{passive:!0}),t!==document.documentElement&&Ae.set(t,ke(o,{container:t})),i.addEventListener("scroll",o,{passive:!0})}let f=esm_T.get(t);return Re(f),()=>{Re.cancel(f);let o=X.get(t);if(!o||(o.delete(n),o.size))return;let i=esm_T.get(t);esm_T.delete(t),i&&(Me(t).removeEventListener("scroll",i),window.removeEventListener("resize",i),Ae.get(t)?.())}};function Er(e){let t=Je(null);return t.current===null&&(t.current=e()),t.current}var esm_Q=dist_esm_h()?external_React_.useEffect:external_React_.useLayoutEffect;var Ce=()=>{let e=(0,external_React_.useRef)(!1);return esm_Q(()=>(e.current=!0,()=>{e.current=!1}),[]),e};function Mr(){let e=(0,external_React_.useState)()[1],t=Ce();return()=>{t.current&&e(Math.random())}}function Lr(e,t){let[r]=(0,external_React_.useState)(()=>({inputs:t,result:e()})),n=(0,external_React_.useRef)(),f=n.current,o=f;return o?Boolean(t&&o.inputs&&it(t,o.inputs))||(o={inputs:t,result:e()}):o=r,(0,external_React_.useEffect)(()=>{n.current=o,f==r&&(r.inputs=r.result=void 0)},[o]),o.result}function it(e,t){if(e.length!==t.length)return!1;for(let r=0;r<e.length;r++)if(e[r]!==t[r])return!1;return!0}var $r=e=>(0,external_React_.useEffect)(e,ut),ut=[];function Ur(e){let t=ct();return lt(()=>{t.current=e}),t.current}var Wr=()=>{let[e,t]=dt(null);return esm_Q(()=>{let r=window.matchMedia("(prefers-reduced-motion)"),n=f=>{t(f.matches),U({skipAnimation:f.matches})};return n(r),r.addEventListener("change",n),()=>{r.removeEventListener("change",n)}},[]),e}; 36745 36746 ;// CONCATENATED MODULE: ./node_modules/@react-spring/animated/dist/esm/index.js 36747 var animated_dist_esm_h=Symbol.for("Animated:node"),animated_dist_esm_v=e=>!!e&&e[animated_dist_esm_h]===e,dist_esm_k=e=>e&&e[animated_dist_esm_h],esm_D=(e,t)=>mt(e,animated_dist_esm_h,t),F=e=>e&&e[animated_dist_esm_h]&&e[animated_dist_esm_h].getPayload(),animated_dist_esm_c=class{payload;constructor(){esm_D(this,this)}getPayload(){return this.payload||[]}};var animated_dist_esm_l=class extends animated_dist_esm_c{constructor(r){super();this._value=r;dist_esm_l.num(this._value)&&(this.lastPosition=this._value)}done=!0;elapsedTime;lastPosition;lastVelocity;v0;durationProgress=0;static create(r){return new animated_dist_esm_l(r)}getPayload(){return[this]}getValue(){return this._value}setValue(r,n){return dist_esm_l.num(r)&&(this.lastPosition=r,n&&(r=Math.round(r/n)*n,this.done&&(this.lastPosition=r))),this._value===r?!1:(this._value=r,!0)}reset(){let{done:r}=this;this.done=!1,dist_esm_l.num(this._value)&&(this.elapsedTime=0,this.durationProgress=0,this.lastPosition=this._value,r&&(this.lastVelocity=null),this.v0=null)}};var animated_dist_esm_d=class extends animated_dist_esm_l{_string=null;_toString;constructor(t){super(0),this._toString=W({output:[t,t]})}static create(t){return new animated_dist_esm_d(t)}getValue(){let t=this._string;return t??(this._string=this._toString(this._value))}setValue(t){if(dist_esm_l.str(t)){if(t==this._string)return!1;this._string=t,this._value=1}else if(super.setValue(t))this._string=null;else return!1;return!0}reset(t){t&&(this._toString=W({output:[this.getValue(),t]})),this._value=0,super.reset()}};var dist_esm_f={dependencies:null};var animated_dist_esm_u=class extends animated_dist_esm_c{constructor(r){super();this.source=r;this.setValue(r)}getValue(r){let n={};return xt(this.source,(a,i)=>{animated_dist_esm_v(a)?n[i]=a.getValue(r):Pt(a)?n[i]=ve(a):r||(n[i]=a)}),n}setValue(r){this.source=r,this.payload=this._makePayload(r)}reset(){this.payload&&esm_Ve(this.payload,r=>r.reset())}_makePayload(r){if(r){let n=new Set;return xt(r,this._addToPayload,n),Array.from(n)}}_addToPayload(r){dist_esm_f.dependencies&&Pt(r)&&dist_esm_f.dependencies.add(r);let n=F(r);n&&esm_Ve(n,a=>this.add(a))}};var animated_dist_esm_y=class extends animated_dist_esm_u{constructor(t){super(t)}static create(t){return new animated_dist_esm_y(t)}getValue(){return this.source.map(t=>t.getValue())}setValue(t){let r=this.getPayload();return t.length==r.length?r.map((n,a)=>n.setValue(t[a])).some(Boolean):(super.setValue(t.map(dist_esm_z)),!0)}};function dist_esm_z(e){return(esm_or(e)?animated_dist_esm_d:animated_dist_esm_l).create(e)}function esm_Le(e){let t=dist_esm_k(e);return t?t.constructor:dist_esm_l.arr(e)?animated_dist_esm_y:esm_or(e)?animated_dist_esm_d:animated_dist_esm_l}var dist_esm_x=(e,t)=>{let r=!dist_esm_l.fun(e)||e.prototype&&e.prototype.isReactComponent;return (0,external_React_.forwardRef)((n,a)=>{let i=(0,external_React_.useRef)(null),o=r&&(0,external_React_.useCallback)(s=>{i.current=esm_ae(a,s)},[a]),[m,T]=esm_ne(n,t),W=Mr(),P=()=>{let s=i.current;if(r&&!s)return;(s?t.applyAnimatedValues(s,m.getValue(!0)):!1)===!1&&W()},_=new animated_dist_esm_b(P,T),p=(0,external_React_.useRef)();esm_Q(()=>(p.current=_,esm_Ve(T,s=>Gt(s,_)),()=>{p.current&&(esm_Ve(p.current.deps,s=>Qt(s,p.current)),esm_n.cancel(p.current.update))})),(0,external_React_.useEffect)(P,[]),$r(()=>()=>{let s=p.current;esm_Ve(s.deps,S=>Qt(S,s))});let $=t.getComponentProps(m.getValue());return external_React_.createElement(e,{...$,ref:o})})},animated_dist_esm_b=class{constructor(t,r){this.update=t;this.deps=r}eventObserved(t){t.type=="change"&&esm_n.write(this.update)}};function esm_ne(e,t){let r=new Set;return dist_esm_f.dependencies=r,e.style&&(e={...e,style:t.createAnimatedStyle(e.style)}),e=new animated_dist_esm_u(e),dist_esm_f.dependencies=null,[e,r]}function esm_ae(e,t){return e&&(dist_esm_l.fun(e)?e(t):e.current=t),t}var dist_esm_j=Symbol.for("AnimatedComponent"),dist_esm_Ke=(e,{applyAnimatedValues:t=()=>!1,createAnimatedStyle:r=a=>new animated_dist_esm_u(a),getComponentProps:n=a=>a}={})=>{let a={applyAnimatedValues:t,createAnimatedStyle:r,getComponentProps:n},i=o=>{let m=esm_I(o)||"Anonymous";return dist_esm_l.str(o)?o=i[o]||(i[o]=dist_esm_x(o,a)):o=o[dist_esm_j]||(o[dist_esm_j]=dist_esm_x(o,a)),o.displayName=`Animated($m})`,o};return xt(e,(o,m)=>{dist_esm_l.arr(e)&&(m=esm_I(o)),i[m]=i(o)}),{animated:i}},esm_I=e=>dist_esm_l.str(e)?e:e&&dist_esm_l.str(e.displayName)?e.displayName:dist_esm_l.fun(e)&&e.name||null; 36748 36749 ;// CONCATENATED MODULE: ./node_modules/@react-spring/core/dist/esm/index.js 36750 function dist_esm_I(t,...e){return dist_esm_l.fun(t)?t(...e):t}var esm_te=(t,e)=>t===!0||!!(e&&t&&(dist_esm_l.fun(t)?t(e):ht(t).includes(e))),et=(t,e)=>dist_esm_l.obj(t)?e&&t[e]:t;var esm_ke=(t,e)=>t.default===!0?t[e]:t.default?t.default[e]:void 0,nn=t=>t,dist_esm_ne=(t,e=nn)=>{let n=rn;t.default&&t.default!==!0&&(t=t.default,n=Object.keys(t));let r={};for(let o of n){let s=e(t[o],o);dist_esm_l.und(s)||(r[o]=s)}return r},rn=["config","onProps","onStart","onChange","onPause","onResume","onRest"],on={config:1,from:1,to:1,ref:1,loop:1,reset:1,pause:1,cancel:1,reverse:1,immediate:1,default:1,delay:1,onProps:1,onStart:1,onChange:1,onPause:1,onResume:1,onRest:1,onResolve:1,items:1,trail:1,sort:1,expires:1,initial:1,enter:1,update:1,leave:1,children:1,onDestroyed:1,keys:1,callId:1,parentId:1};function sn(t){let e={},n=0;if(xt(t,(r,o)=>{on[o]||(e[o]=r,n++)}),n)return e}function esm_de(t){let e=sn(t);if(e){let n={to:e};return xt(t,(r,o)=>o in e||(n[o]=r)),n}return{...t}}function esm_me(t){return t=ve(t),dist_esm_l.arr(t)?t.map(esm_me):esm_or(t)?dist_esm_p.createStringInterpolator({range:[0,1],output:[t,t]})(1):t}function esm_Ue(t){for(let e in t)return!0;return!1}function esm_Ee(t){return dist_esm_l.fun(t)||dist_esm_l.arr(t)&&dist_esm_l.obj(t[0])}function esm_xe(t,e){t.ref?.delete(t),e?.delete(t)}function esm_he(t,e){e&&t.ref!==e&&(t.ref?.delete(t),e.add(t),t.ref=e)}function wr(t,e,n=1e3){an(()=>{if(e){let r=0;ge(t,(o,s)=>{let a=o.current;if(a.length){let i=n*e[s];isNaN(i)?i=r:r=i,ge(a,u=>{ge(u.queue,p=>{let f=p.delay;p.delay=d=>i+dist_esm_I(f||0,d)})}),o.start()}})}else{let r=Promise.resolve();ge(t,o=>{let s=o.current;if(s.length){let a=s.map(i=>{let u=i.queue;return i.queue=[],u});r=r.then(()=>(ge(s,(i,u)=>ge(a[u]||[],p=>i.queue.push(p))),Promise.all(o.start())))}})}})}var esm_mt={default:{tension:170,friction:26},gentle:{tension:120,friction:14},wobbly:{tension:180,friction:12},stiff:{tension:210,friction:20},slow:{tension:280,friction:60},molasses:{tension:280,friction:120}};var tt={...esm_mt.default,mass:1,damping:1,easing:Lt.linear,clamp:!1},esm_we=class{tension;friction;frequency;damping;mass;velocity=0;restVelocity;precision;progress;duration;easing;clamp;bounce;decay;round;constructor(){Object.assign(this,tt)}};function gt(t,e,n){n&&(n={...n},esm_ht(n,e),e={...n,...e}),esm_ht(t,e),Object.assign(t,e);for(let a in tt)t[a]==null&&(t[a]=tt[a]);let{mass:r,frequency:o,damping:s}=t;return dist_esm_l.und(o)||(o<.01&&(o=.01),s<0&&(s=0),t.tension=Math.pow(2*Math.PI/o,2)*r,t.friction=4*Math.PI*s*r/o),t}function esm_ht(t,e){if(!dist_esm_l.und(e.decay))t.duration=void 0;else{let n=!dist_esm_l.und(e.tension)||!dist_esm_l.und(e.friction);(n||!dist_esm_l.und(e.frequency)||!dist_esm_l.und(e.damping)||!dist_esm_l.und(e.mass))&&(t.duration=void 0,t.decay=void 0),n&&(t.frequency=void 0)}}var esm_yt=[],dist_esm_Le=class{changed=!1;values=esm_yt;toValues=null;fromValues=esm_yt;to;from;config=new esm_we;immediate=!1};function esm_Me(t,{key:e,props:n,defaultProps:r,state:o,actions:s}){return new Promise((a,i)=>{let u,p,f=esm_te(n.cancel??r?.cancel,e);if(f)b();else{dist_esm_l.und(n.pause)||(o.paused=esm_te(n.pause,e));let c=r?.pause;c!==!0&&(c=o.paused||esm_te(c,e)),u=dist_esm_I(n.delay||0,e),c?(o.resumeQueue.add(m),s.pause()):(s.resume(),m())}function d(){o.resumeQueue.add(m),o.timeouts.delete(p),p.cancel(),u=p.time-esm_n.now()}function m(){u>0&&!dist_esm_p.skipAnimation?(o.delayed=!0,p=esm_n.setTimeout(b,u),o.pauseQueue.add(d),o.timeouts.add(p)):b()}function b(){o.delayed&&(o.delayed=!1),o.pauseQueue.delete(d),o.timeouts.delete(p),t<=(o.cancelId||0)&&(f=!0);try{s.start({...n,callId:t,cancel:f},a)}catch(c){i(c)}}})}var esm_be=(t,e)=>e.length==1?e[0]:e.some(n=>n.cancelled)?esm_q(t.get()):e.every(n=>n.noop)?nt(t.get()):dist_esm_E(t.get(),e.every(n=>n.finished)),nt=t=>({value:t,noop:!0,finished:!0,cancelled:!1}),dist_esm_E=(t,e,n=!1)=>({value:t,finished:e,cancelled:n}),esm_q=t=>({value:t,cancelled:!0,finished:!1});function esm_De(t,e,n,r){let{callId:o,parentId:s,onRest:a}=e,{asyncTo:i,promise:u}=n;return!s&&t===i&&!e.reset?u:n.promise=(async()=>{n.asyncId=o,n.asyncTo=t;let p=dist_esm_ne(e,(l,h)=>h==="onRest"?void 0:l),f,d,m=new Promise((l,h)=>(f=l,d=h)),b=l=>{let h=o<=(n.cancelId||0)&&esm_q(r)||o!==n.asyncId&&dist_esm_E(r,!1);if(h)throw l.result=h,d(l),l},c=(l,h)=>{let g=new esm_Ae,x=new esm_Ne;return(async()=>{if(dist_esm_p.skipAnimation)throw esm_oe(n),x.result=dist_esm_E(r,!1),d(x),x;b(g);let S=dist_esm_l.obj(l)?{...l}:{...h,to:l};S.parentId=o,xt(p,(V,_)=>{dist_esm_l.und(S[_])&&(S[_]=V)});let A=await r.start(S);return b(g),n.paused&&await new Promise(V=>{n.resumeQueue.add(V)}),A})()},P;if(dist_esm_p.skipAnimation)return esm_oe(n),dist_esm_E(r,!1);try{let l;dist_esm_l.arr(t)?l=(async h=>{for(let g of h)await c(g)})(t):l=Promise.resolve(t(c,r.stop.bind(r))),await Promise.all([l.then(f),m]),P=dist_esm_E(r.get(),!0,!1)}catch(l){if(l instanceof esm_Ae)P=l.result;else if(l instanceof esm_Ne)P=l.result;else throw l}finally{o==n.asyncId&&(n.asyncId=s,n.asyncTo=s?i:void 0,n.promise=s?u:void 0)}return dist_esm_l.fun(a)&&esm_n.batchedUpdates(()=>{a(P,r,r.item)}),P})()}function esm_oe(t,e){Pe(t.timeouts,n=>n.cancel()),t.pauseQueue.clear(),t.resumeQueue.clear(),t.asyncId=t.asyncTo=t.promise=void 0,e&&(t.cancelId=e)}var esm_Ae=class extends Error{result;constructor(){super("An async animation has been interrupted. You see this error because you forgot to use `await` or `.catch(...)` on its returned promise.")}},esm_Ne=class extends Error{result;constructor(){super("SkipAnimationSignal")}};var esm_Re=t=>t instanceof esm_X,Sn=1,esm_X=class extends esm_ge{id=Sn++;_priority=0;get priority(){return this._priority}set priority(e){this._priority!=e&&(this._priority=e,this._onPriorityChange(e))}get(){let e=dist_esm_k(this);return e&&e.getValue()}to(...e){return dist_esm_p.to(this,e)}interpolate(...e){return Jt(),dist_esm_p.to(this,e)}toJSON(){return this.get()}observerAdded(e){e==1&&this._attach()}observerRemoved(e){e==0&&this._detach()}_attach(){}_detach(){}_onChange(e,n=!1){$t(this,{type:"change",parent:this,value:e,idle:n})}_onPriorityChange(e){this.idle||qe.sort(this),$t(this,{type:"priority",parent:this,priority:e})}};var esm_se=Symbol.for("SpringPhase"),esm_bt=1,rt=2,ot=4,esm_qe=t=>(t[esm_se]&esm_bt)>0,dist_esm_Q=t=>(t[esm_se]&rt)>0,esm_ye=t=>(t[esm_se]&ot)>0,st=(t,e)=>e?t[esm_se]|=rt|esm_bt:t[esm_se]&=~rt,esm_it=(t,e)=>e?t[esm_se]|=ot:t[esm_se]&=~ot;var esm_ue=class extends esm_X{key;animation=new dist_esm_Le;queue;defaultProps={};_state={paused:!1,delayed:!1,pauseQueue:new Set,resumeQueue:new Set,timeouts:new Set};_pendingCalls=new Set;_lastCallId=0;_lastToId=0;_memoizedDuration=0;constructor(e,n){if(super(),!dist_esm_l.und(e)||!dist_esm_l.und(n)){let r=dist_esm_l.obj(e)?{...e}:{...n,from:e};dist_esm_l.und(r.default)&&(r.default=!0),this.start(r)}}get idle(){return!(dist_esm_Q(this)||this._state.asyncTo)||esm_ye(this)}get goal(){return ve(this.animation.to)}get velocity(){let e=dist_esm_k(this);return e instanceof animated_dist_esm_l?e.lastVelocity||0:e.getPayload().map(n=>n.lastVelocity||0)}get hasAnimated(){return esm_qe(this)}get isAnimating(){return dist_esm_Q(this)}get isPaused(){return esm_ye(this)}get isDelayed(){return this._state.delayed}advance(e){let n=!0,r=!1,o=this.animation,{config:s,toValues:a}=o,i=F(o.to);!i&&Pt(o.to)&&(a=ht(ve(o.to))),o.values.forEach((f,d)=>{if(f.done)return;let m=f.constructor==animated_dist_esm_d?1:i?i[d].lastPosition:a[d],b=o.immediate,c=m;if(!b){if(c=f.lastPosition,s.tension<=0){f.done=!0;return}let P=f.elapsedTime+=e,l=o.fromValues[d],h=f.v0!=null?f.v0:f.v0=dist_esm_l.arr(s.velocity)?s.velocity[d]:s.velocity,g,x=s.precision||(l==m?.005:Math.min(1,Math.abs(m-l)*.001));if(dist_esm_l.und(s.duration))if(s.decay){let S=s.decay===!0?.998:s.decay,A=Math.exp(-(1-S)*P);c=l+h/(1-S)*(1-A),b=Math.abs(f.lastPosition-c)<=x,g=h*A}else{g=f.lastVelocity==null?h:f.lastVelocity;let S=s.restVelocity||x/10,A=s.clamp?0:s.bounce,V=!dist_esm_l.und(A),_=l==m?f.v0>0:l<m,v,w=!1,C=1,$=Math.ceil(e/C);for(let L=0;L<$&&(v=Math.abs(g)>S,!(!v&&(b=Math.abs(m-c)<=x,b)));++L){V&&(w=c==m||c>m==_,w&&(g=-g*A,c=m));let N=-s.tension*1e-6*(c-m),y=-s.friction*.001*g,T=(N+y)/s.mass;g=g+T*C,c=c+g*C}}else{let S=1;s.duration>0&&(this._memoizedDuration!==s.duration&&(this._memoizedDuration=s.duration,f.durationProgress>0&&(f.elapsedTime=s.duration*f.durationProgress,P=f.elapsedTime+=e)),S=(s.progress||0)+P/this._memoizedDuration,S=S>1?1:S<0?0:S,f.durationProgress=S),c=l+s.easing(S)*(m-l),g=(c-f.lastPosition)/e,b=S==1}f.lastVelocity=g,Number.isNaN(c)&&(console.warn("Got NaN while animating:",this),b=!0)}i&&!i[d].done&&(b=!1),b?f.done=!0:n=!1,f.setValue(c,s.round)&&(r=!0)});let u=dist_esm_k(this),p=u.getValue();if(n){let f=ve(o.to);(p!==f||r)&&!s.decay?(u.setValue(f),this._onChange(f)):r&&s.decay&&this._onChange(p),this._stop()}else r&&this._onChange(p)}set(e){return esm_n.batchedUpdates(()=>{this._stop(),this._focus(e),this._set(e)}),this}pause(){this._update({pause:!0})}resume(){this._update({pause:!1})}finish(){if(dist_esm_Q(this)){let{to:e,config:n}=this.animation;esm_n.batchedUpdates(()=>{this._onStart(),n.decay||this._set(e,!1),this._stop()})}return this}update(e){return(this.queue||(this.queue=[])).push(e),this}start(e,n){let r;return dist_esm_l.und(e)?(r=this.queue||[],this.queue=[]):r=[dist_esm_l.obj(e)?e:{...n,to:e}],Promise.all(r.map(o=>this._update(o))).then(o=>esm_be(this,o))}stop(e){let{to:n}=this.animation;return this._focus(this.get()),esm_oe(this._state,e&&this._lastCallId),esm_n.batchedUpdates(()=>this._stop(n,e)),this}reset(){this._update({reset:!0})}eventObserved(e){e.type=="change"?this._start():e.type=="priority"&&(this.priority=e.priority+1)}_prepareNode(e){let n=this.key||"",{to:r,from:o}=e;r=dist_esm_l.obj(r)?r[n]:r,(r==null||esm_Ee(r))&&(r=void 0),o=dist_esm_l.obj(o)?o[n]:o,o==null&&(o=void 0);let s={to:r,from:o};return esm_qe(this)||(e.reverse&&([r,o]=[o,r]),o=ve(o),dist_esm_l.und(o)?dist_esm_k(this)||this._set(r):this._set(o)),s}_update({...e},n){let{key:r,defaultProps:o}=this;e.default&&Object.assign(o,dist_esm_ne(e,(i,u)=>/^on/.test(u)?et(i,r):i)),_t(this,e,"onProps"),esm_Ie(this,"onProps",e,this);let s=this._prepareNode(e);if(Object.isFrozen(this))throw Error("Cannot animate a `SpringValue` object that is frozen. Did you forget to pass your component to `animated(...)` before animating its props?");let a=this._state;return esm_Me(++this._lastCallId,{key:r,props:e,defaultProps:o,state:a,actions:{pause:()=>{esm_ye(this)||(esm_it(this,!0),yt(a.pauseQueue),esm_Ie(this,"onPause",dist_esm_E(this,esm_Ce(this,this.animation.to)),this))},resume:()=>{esm_ye(this)&&(esm_it(this,!1),dist_esm_Q(this)&&this._resume(),yt(a.resumeQueue),esm_Ie(this,"onResume",dist_esm_E(this,esm_Ce(this,this.animation.to)),this))},start:this._merge.bind(this,s)}}).then(i=>{if(e.loop&&i.finished&&!(n&&i.noop)){let u=at(e);if(u)return this._update(u,!0)}return i})}_merge(e,n,r){if(n.cancel)return this.stop(!0),r(esm_q(this));let o=!dist_esm_l.und(e.to),s=!dist_esm_l.und(e.from);if(o||s)if(n.callId>this._lastToId)this._lastToId=n.callId;else return r(esm_q(this));let{key:a,defaultProps:i,animation:u}=this,{to:p,from:f}=u,{to:d=p,from:m=f}=e;s&&!o&&(!n.default||dist_esm_l.und(d))&&(d=m),n.reverse&&([d,m]=[m,d]);let b=!bt(m,f);b&&(u.from=m),m=ve(m);let c=!bt(d,p);c&&this._focus(d);let P=esm_Ee(n.to),{config:l}=u,{decay:h,velocity:g}=l;(o||s)&&(l.velocity=0),n.config&&!P&>(l,dist_esm_I(n.config,a),n.config!==i.config?dist_esm_I(i.config,a):void 0);let x=dist_esm_k(this);if(!x||dist_esm_l.und(d))return r(dist_esm_E(this,!0));let S=dist_esm_l.und(n.reset)?s&&!n.default:!dist_esm_l.und(m)&&esm_te(n.reset,a),A=S?m:this.get(),V=esm_me(d),_=dist_esm_l.num(V)||dist_esm_l.arr(V)||esm_or(V),v=!P&&(!_||esm_te(i.immediate||n.immediate,a));if(c){let L=esm_Le(d);if(L!==x.constructor)if(v)x=this._set(V);else throw Error(`Cannot animate between $x.constructor.name} and $L.name}, as the "to" prop suggests`)}let w=x.constructor,C=Pt(d),$=!1;if(!C){let L=S||!esm_qe(this)&&b;(c||L)&&($=bt(esm_me(A),V),C=!$),(!bt(u.immediate,v)&&!v||!bt(l.decay,h)||!bt(l.velocity,g))&&(C=!0)}if($&&dist_esm_Q(this)&&(u.changed&&!S?C=!0:C||this._stop(p)),!P&&((C||Pt(p))&&(u.values=x.getPayload(),u.toValues=Pt(d)?null:w==animated_dist_esm_d?[1]:ht(V)),u.immediate!=v&&(u.immediate=v,!v&&!S&&this._set(p)),C)){let{onRest:L}=u;esm_Ve(_n,y=>_t(this,n,y));let N=dist_esm_E(this,esm_Ce(this,p));yt(this._pendingCalls,N),this._pendingCalls.add(r),u.changed&&esm_n.batchedUpdates(()=>{u.changed=!S,L?.(N,this),S?dist_esm_I(i.onRest,N):u.onStart?.(N,this)})}S&&this._set(A),P?r(esm_De(n.to,n,this._state,this)):C?this._start():dist_esm_Q(this)&&!c?this._pendingCalls.add(r):r(nt(A))}_focus(e){let n=this.animation;e!==n.to&&(esm_qt(this)&&this._detach(),n.to=e,esm_qt(this)&&this._attach())}_attach(){let e=0,{to:n}=this.animation;Pt(n)&&(Gt(n,this),esm_Re(n)&&(e=n.priority+1)),this.priority=e}_detach(){let{to:e}=this.animation;Pt(e)&&Qt(e,this)}_set(e,n=!0){let r=ve(e);if(!dist_esm_l.und(r)){let o=dist_esm_k(this);if(!o||!bt(r,o.getValue())){let s=esm_Le(r);!o||o.constructor!=s?esm_D(this,s.create(r)):o.setValue(r),o&&esm_n.batchedUpdates(()=>{this._onChange(r,n)})}}return dist_esm_k(this)}_onStart(){let e=this.animation;e.changed||(e.changed=!0,esm_Ie(this,"onStart",dist_esm_E(this,esm_Ce(this,e.to)),this))}_onChange(e,n){n||(this._onStart(),dist_esm_I(this.animation.onChange,e,this)),dist_esm_I(this.defaultProps.onChange,e,this),super._onChange(e,n)}_start(){let e=this.animation;dist_esm_k(this).reset(ve(e.to)),e.immediate||(e.fromValues=e.values.map(n=>n.lastPosition)),dist_esm_Q(this)||(st(this,!0),esm_ye(this)||this._resume())}_resume(){dist_esm_p.skipAnimation?this.finish():qe.start(this)}_stop(e,n){if(dist_esm_Q(this)){st(this,!1);let r=this.animation;esm_Ve(r.values,s=>{s.done=!0}),r.toValues&&(r.onChange=r.onPause=r.onResume=void 0),$t(this,{type:"idle",parent:this});let o=n?esm_q(this.get()):dist_esm_E(this.get(),esm_Ce(this,e??r.to));yt(this._pendingCalls,o),r.changed&&(r.changed=!1,esm_Ie(this,"onRest",o,this))}}};function esm_Ce(t,e){let n=esm_me(e),r=esm_me(t.get());return bt(r,n)}function at(t,e=t.loop,n=t.to){let r=dist_esm_I(e);if(r){let o=r!==!0&&esm_de(r),s=(o||t).reverse,a=!o||o.reset;return esm_Pe({...t,loop:e,default:!1,pause:void 0,to:!s||esm_Ee(n)?n:void 0,from:a?t.from:void 0,reset:a,...o})}}function esm_Pe(t){let{to:e,from:n}=t=esm_de(t),r=new Set;return dist_esm_l.obj(e)&&Vt(e,r),dist_esm_l.obj(n)&&Vt(n,r),t.keys=r.size?Array.from(r):null,t}function Ot(t){let e=esm_Pe(t);return R.und(e.default)&&(e.default=dist_esm_ne(e)),e}function Vt(t,e){xt(t,(n,r)=>n!=null&&e.add(r))}var _n=["onStart","onRest","onChange","onPause","onResume"];function _t(t,e,n){t.animation[n]=e[n]!==esm_ke(e,n)?et(e[n],t.key):void 0}function esm_Ie(t,e,...n){t.animation[e]?.(...n),t.defaultProps[e]?.(...n)}var Fn=["onStart","onChange","onRest"],kn=1,esm_le=class{id=kn++;springs={};queue=[];ref;_flush;_initialProps;_lastAsyncId=0;_active=new Set;_changed=new Set;_started=!1;_item;_state={paused:!1,pauseQueue:new Set,resumeQueue:new Set,timeouts:new Set};_events={onStart:new Map,onChange:new Map,onRest:new Map};constructor(e,n){this._onFrame=this._onFrame.bind(this),n&&(this._flush=n),e&&this.start({default:!0,...e})}get idle(){return!this._state.asyncTo&&Object.values(this.springs).every(e=>e.idle&&!e.isDelayed&&!e.isPaused)}get item(){return this._item}set item(e){this._item=e}get(){let e={};return this.each((n,r)=>e[r]=n.get()),e}set(e){for(let n in e){let r=e[n];dist_esm_l.und(r)||this.springs[n].set(r)}}update(e){return e&&this.queue.push(esm_Pe(e)),this}start(e){let{queue:n}=this;return e?n=ht(e).map(esm_Pe):this.queue=[],this._flush?this._flush(this,n):(jt(this,n),esm_ze(this,n))}stop(e,n){if(e!==!!e&&(n=e),n){let r=this.springs;esm_Ve(ht(n),o=>r[o].stop(!!e))}else esm_oe(this._state,this._lastAsyncId),this.each(r=>r.stop(!!e));return this}pause(e){if(dist_esm_l.und(e))this.start({pause:!0});else{let n=this.springs;esm_Ve(ht(e),r=>n[r].pause())}return this}resume(e){if(dist_esm_l.und(e))this.start({pause:!1});else{let n=this.springs;esm_Ve(ht(e),r=>n[r].resume())}return this}each(e){xt(this.springs,e)}_onFrame(){let{onStart:e,onChange:n,onRest:r}=this._events,o=this._active.size>0,s=this._changed.size>0;(o&&!this._started||s&&!this._started)&&(this._started=!0,Pe(e,([u,p])=>{p.value=this.get(),u(p,this,this._item)}));let a=!o&&this._started,i=s||a&&r.size?this.get():null;s&&n.size&&Pe(n,([u,p])=>{p.value=i,u(p,this,this._item)}),a&&(this._started=!1,Pe(r,([u,p])=>{p.value=i,u(p,this,this._item)}))}eventObserved(e){if(e.type=="change")this._changed.add(e.parent),e.idle||this._active.add(e.parent);else if(e.type=="idle")this._active.delete(e.parent);else return;esm_n.onFrame(this._onFrame)}};function esm_ze(t,e){return Promise.all(e.map(n=>wt(t,n))).then(n=>esm_be(t,n))}async function wt(t,e,n){let{keys:r,to:o,from:s,loop:a,onRest:i,onResolve:u}=e,p=dist_esm_l.obj(e.default)&&e.default;a&&(e.loop=!1),o===!1&&(e.to=null),s===!1&&(e.from=null);let f=dist_esm_l.arr(o)||dist_esm_l.fun(o)?o:void 0;f?(e.to=void 0,e.onRest=void 0,p&&(p.onRest=void 0)):esm_Ve(Fn,P=>{let l=e[P];if(dist_esm_l.fun(l)){let h=t._events[P];e[P]=({finished:g,cancelled:x})=>{let S=h.get(l);S?(g||(S.finished=!1),x&&(S.cancelled=!0)):h.set(l,{value:null,finished:g||!1,cancelled:x||!1})},p&&(p[P]=e[P])}});let d=t._state;e.pause===!d.paused?(d.paused=e.pause,yt(e.pause?d.pauseQueue:d.resumeQueue)):d.paused&&(e.pause=!0);let m=(r||Object.keys(t.springs)).map(P=>t.springs[P].start(e)),b=e.cancel===!0||esm_ke(e,"cancel")===!0;(f||b&&d.asyncId)&&m.push(esm_Me(++t._lastAsyncId,{props:e,state:d,actions:{pause:Y,resume:Y,start(P,l){b?(esm_oe(d,t._lastAsyncId),l(esm_q(t))):(P.onRest=i,l(esm_De(f,P,d,t)))}}})),d.paused&&await new Promise(P=>{d.resumeQueue.add(P)});let c=esm_be(t,await Promise.all(m));if(a&&c.finished&&!(n&&c.noop)){let P=at(e,a,o);if(P)return jt(t,[P]),wt(t,P,!0)}return u&&esm_n.batchedUpdates(()=>u(c,t,t.item)),c}function esm_e(t,e){let n={...t.springs};return e&&pe(Ve(e),r=>{z.und(r.keys)&&(r=esm_Pe(r)),z.obj(r.to)||(r={...r,to:void 0}),Mt(n,r,o=>esm_Lt(o))}),pt(t,n),n}function pt(t,e){Ut(e,(n,r)=>{t.springs[r]||(t.springs[r]=n,Et(n,t))})}function esm_Lt(t,e){let n=new esm_ue;return n.key=t,e&&Gt(n,e),n}function Mt(t,e,n){e.keys&&esm_Ve(e.keys,r=>{(t[r]||(t[r]=n(r)))._prepareNode(e)})}function jt(t,e){esm_Ve(e,n=>{Mt(t.springs,n,r=>esm_Lt(r,t))})}var dist_esm_H=({children:t,...e})=>{let n=(0,external_React_.useContext)(esm_Ge),r=e.pause||!!n.pause,o=e.immediate||!!n.immediate;e=Lr(()=>({pause:r,immediate:o}),[r,o]);let{Provider:s}=esm_Ge;return external_React_.createElement(s,{value:e},t)},esm_Ge=wn(dist_esm_H,{});dist_esm_H.Provider=esm_Ge.Provider;dist_esm_H.Consumer=esm_Ge.Consumer;function wn(t,e){return Object.assign(t,external_React_.createContext(e)),t.Provider._context=t,t.Consumer._context=t,t}var esm_fe=()=>{let t=[],e=function(r){Ln();let o=[];return ce(t,(s,a)=>{if(Ke.und(r))o.push(s.start());else{let i=n(r,s,a);i&&o.push(s.start(i))}}),o};e.current=t,e.add=function(r){t.includes(r)||t.push(r)},e.delete=function(r){let o=t.indexOf(r);~o&&t.splice(o,1)},e.pause=function(){return ce(t,r=>r.pause(...arguments)),this},e.resume=function(){return ce(t,r=>r.resume(...arguments)),this},e.set=function(r){ce(t,(o,s)=>{let a=Ke.fun(r)?r(s,o):r;a&&o.set(a)})},e.start=function(r){let o=[];return ce(t,(s,a)=>{if(Ke.und(r))o.push(s.start());else{let i=this._getProps(r,s,a);i&&o.push(s.start(i))}}),o},e.stop=function(){return ce(t,r=>r.stop(...arguments)),this},e.update=function(r){return ce(t,(o,s)=>o.update(this._getProps(r,o,s))),this};let n=function(r,o,s){return Ke.fun(r)?r(s,o):r};return e._getProps=n,e};function esm_He(t,e,n){let r=jn.fun(e)&&e;r&&!n&&(n=[]);let o=Xe(()=>r||arguments.length==3?esm_fe():void 0,[]),s=Nt(0),a=Dn(),i=Xe(()=>({ctrls:[],queue:[],flush(h,g){let x=esm_e(h,g);return s.current>0&&!i.queue.length&&!Object.keys(x).some(A=>!h.springs[A])?esm_ze(h,g):new Promise(A=>{pt(h,x),i.queue.push(()=>{A(esm_ze(h,g))}),a()})}}),[]),u=Nt([...i.ctrls]),p=[],f=Dt(t)||0;Xe(()=>{Ye(u.current.slice(t,f),h=>{esm_xe(h,o),h.stop(!0)}),u.current.length=t,d(f,t)},[t]),Xe(()=>{d(0,Math.min(f,t))},n);function d(h,g){for(let x=h;x<g;x++){let S=u.current[x]||(u.current[x]=new esm_le(null,i.flush)),A=r?r(x,S):e[x];A&&(p[x]=Ot(A))}}let m=u.current.map((h,g)=>esm_e(h,p[g])),b=Mn(dist_esm_H),c=Dt(b),P=b!==c&&esm_Ue(b);qn(()=>{s.current++,i.ctrls=u.current;let{queue:h}=i;h.length&&(i.queue=[],Ye(h,g=>g())),Ye(u.current,(g,x)=>{o?.add(g),P&&g.start({default:b});let S=p[x];S&&(esm_he(g,S.ref),g.ref?g.queue.push(S):g.start(S))})}),Nn(()=>()=>{Ye(i.ctrls,h=>h.stop(!0))});let l=m.map(h=>({...h}));return o?[l,o]:l}function esm_J(t,e){let n=Qn.fun(t),[[r],o]=esm_He(1,n?t:[t],n?e||[]:e);return n||arguments.length==2?[r,o]:r}var Gn=()=>esm_fe(),Xo=()=>zn(Gn)[0];var Wo=(t,e)=>{let n=Bn(()=>new esm_ue(t,e));return Kn(()=>()=>{n.stop()}),n};function esm_Qt(t,e,n){let r=qt.fun(e)&&e;r&&!n&&(n=[]);let o=!0,s,a=esm_He(t,(i,u)=>{let p=r?r(i,u):e;return s=p.ref,o=o&&p.reverse,p},n||[{}]);if(Yn(()=>{Xn(a[1].current,(i,u)=>{let p=a[1].current[u+(o?1:-1)];if(esm_he(i,s),i.ref){p&&i.update({to:p.springs});return}p?i.start({to:p.springs}):i.start()})},n),r||arguments.length==3){let i=s??a[1];return i._getProps=(u,p,f)=>{let d=qt.fun(u)?u(f,p):u;if(d){let m=i.current[f+(d.reverse?1:-1)];return m&&(d.to=m.springs),d}},a}return a[0]}function esm_Gt(t,e,n){let r=G.fun(e)&&e,{reset:o,sort:s,trail:a=0,expires:i=!0,exitBeforeEnter:u=!1,onDestroyed:p,ref:f,config:d}=r?r():e,m=Jn(()=>r||arguments.length==3?esm_fe():void 0,[]),b=zt(t),c=[],P=lt(null),l=o?null:P.current;Je(()=>{P.current=c}),$n(()=>(j(c,y=>{m?.add(y.ctrl),y.ctrl.ref=m}),()=>{j(P.current,y=>{y.expired&&clearTimeout(y.expirationId),esm_xe(y.ctrl,m),y.ctrl.stop(!0)})}));let h=tr(b,r?r():e,l),g=o&&P.current||[];Je(()=>j(g,({ctrl:y,item:T,key:F})=>{esm_xe(y,m),dist_esm_I(p,T,F)}));let x=[];if(l&&j(l,(y,T)=>{y.expired?(clearTimeout(y.expirationId),g.push(y)):(T=x[T]=h.indexOf(y.key),~T&&(c[T]=y))}),j(b,(y,T)=>{c[T]||(c[T]={key:h[T],item:y,phase:"mount",ctrl:new esm_le},c[T].ctrl.item=y)}),x.length){let y=-1,{leave:T}=r?r():e;j(x,(F,k)=>{let O=l[k];~F?(y=c.indexOf(O),c[y]={...O,item:b[F]}):T&&c.splice(++y,0,O)})}G.fun(s)&&c.sort((y,T)=>s(y.item,T.item));let S=-a,A=Wn(),V=dist_esm_ne(e),_=new Map,v=lt(new Map),w=lt(!1);j(c,(y,T)=>{let F=y.key,k=y.phase,O=r?r():e,U,D,Jt=dist_esm_I(O.delay||0,F);if(k=="mount")U=O.enter,D="enter";else{let M=h.indexOf(F)<0;if(k!="leave")if(M)U=O.leave,D="leave";else if(U=O.update)D="update";else return;else if(!M)U=O.enter,D="enter";else return}if(U=dist_esm_I(U,y.item,T),U=G.obj(U)?esm_de(U):{to:U},!U.config){let M=d||V.config;U.config=dist_esm_I(M,y.item,T,D)}S+=a;let Z={...V,delay:Jt+S,ref:f,immediate:O.immediate,reset:!1,...U};if(D=="enter"&&G.und(Z.from)){let M=r?r():e,Te=G.und(M.initial)||l?M.from:M.initial;Z.from=dist_esm_I(Te,y.item,T)}let{onResolve:Wt}=Z;Z.onResolve=M=>{dist_esm_I(Wt,M);let Te=P.current,B=Te.find(Fe=>Fe.key===F);if(!!B&&!(M.cancelled&&B.phase!="update")&&B.ctrl.idle){let Fe=Te.every(ee=>ee.ctrl.idle);if(B.phase=="leave"){let ee=dist_esm_I(i,B.item);if(ee!==!1){let Ze=ee===!0?0:ee;if(B.expired=!0,!Fe&&Ze>0){Ze<=2147483647&&(B.expirationId=setTimeout(A,Ze));return}}}Fe&&Te.some(ee=>ee.expired)&&(v.current.delete(B),u&&(w.current=!0),A())}};let ft=esm_e(y.ctrl,Z);D==="leave"&&u?v.current.set(y,{phase:D,springs:ft,payload:Z}):_.set(y,{phase:D,springs:ft,payload:Z})});let C=Hn(dist_esm_H),$=Zn(C),L=C!==$&&esm_Ue(C);Je(()=>{L&&j(c,y=>{y.ctrl.start({default:C})})},[C]),j(_,(y,T)=>{if(v.current.size){let F=c.findIndex(k=>k.key===T.key);c.splice(F,1)}}),Je(()=>{j(v.current.size?v.current:_,({phase:y,payload:T},F)=>{let{ctrl:k}=F;F.phase=y,m?.add(k),L&&y=="enter"&&k.start({default:C}),T&&(esm_he(k,T.ref),(k.ref||m)&&!w.current?k.update(T):(k.start(T),w.current&&(w.current=!1)))})},o?void 0:n);let N=y=>Oe.createElement(Oe.Fragment,null,c.map((T,F)=>{let{springs:k}=_.get(T)||T.ctrl,O=y({...k},T.item,T,F);return O&&O.type?Oe.createElement(O.type,{...O.props,key:G.str(T.key)||G.num(T.key)?T.key:T.ctrl.id,ref:O.ref}):O}));return m?[N,m]:N}var esm_er=1;function tr(t,{key:e,keys:n=e},r){if(n===null){let o=new Set;return t.map(s=>{let a=r&&r.find(i=>i.item===s&&i.phase!=="leave"&&!o.has(i));return a?(o.add(a),a.key):esm_er++})}return G.und(n)?t:G.fun(n)?t.map(n):zt(n)}var hs=({container:t,...e}={})=>{let[n,r]=esm_J(()=>({scrollX:0,scrollY:0,scrollXProgress:0,scrollYProgress:0,...e}),[]);return or(()=>{let o=rr(({x:s,y:a})=>{r.start({scrollX:s.current,scrollXProgress:s.progress,scrollY:a.current,scrollYProgress:a.progress})},{container:t?.current||void 0});return()=>{nr(Object.values(n),s=>s.stop()),o()}},[]),n};var Ps=({container:t,...e})=>{let[n,r]=esm_J(()=>({width:0,height:0,...e}),[]);return ar(()=>{let o=sr(({width:s,height:a})=>{r.start({width:s,height:a,immediate:n.width.get()===0||n.height.get()===0})},{container:t?.current||void 0});return()=>{ir(Object.values(n),s=>s.stop()),o()}},[]),n};var cr={any:0,all:1};function Cs(t,e){let[n,r]=pr(!1),o=ur(),s=Bt.fun(t)&&t,a=s?s():{},{to:i={},from:u={},...p}=a,f=s?e:t,[d,m]=esm_J(()=>({from:u,...p}),[]);return lr(()=>{let b=o.current,{root:c,once:P,amount:l="any",...h}=f??{};if(!b||P&&n||typeof IntersectionObserver>"u")return;let g=new WeakMap,x=()=>(i&&m.start(i),r(!0),P?void 0:()=>{u&&m.start(u),r(!1)}),S=V=>{V.forEach(_=>{let v=g.get(_.target);if(_.isIntersecting!==Boolean(v))if(_.isIntersecting){let w=x();Bt.fun(w)?g.set(_.target,w):A.unobserve(_.target)}else v&&(v(),g.delete(_.target))})},A=new IntersectionObserver(S,{root:c&&c.current||void 0,threshold:typeof l=="number"||Array.isArray(l)?l:cr[l],...h});return A.observe(b),()=>A.unobserve(b)},[f]),s?[o,d]:[o,n]}function qs({children:t,...e}){return t(esm_J(e))}function Bs({items:t,children:e,...n}){let r=esm_Qt(t.length,n);return t.map((o,s)=>{let a=e(o,s);return fr.fun(a)?a(r[s]):a})}function Ys({items:t,children:e,...n}){return esm_Gt(t,n)(e)}var esm_W=class extends esm_X{constructor(n,r){super();this.source=n;this.calc=W(...r);let o=this._get(),s=esm_Le(o);esm_D(this,s.create(o))}key;idle=!0;calc;_active=new Set;advance(n){let r=this._get(),o=this.get();bt(r,o)||(dist_esm_k(this).setValue(r),this._onChange(r,this.idle)),!this.idle&&Yt(this._active)&&esm_ct(this)}_get(){let n=dist_esm_l.arr(this.source)?this.source.map(ve):ht(ve(this.source));return this.calc(...n)}_start(){this.idle&&!Yt(this._active)&&(this.idle=!1,esm_Ve(F(this),n=>{n.done=!1}),dist_esm_p.skipAnimation?(esm_n.batchedUpdates(()=>this.advance()),esm_ct(this)):qe.start(this))}_attach(){let n=1;esm_Ve(ht(this.source),r=>{Pt(r)&&Gt(r,this),esm_Re(r)&&(r.idle||this._active.add(r),n=Math.max(n,r.priority+1))}),this.priority=n,this._start()}_detach(){esm_Ve(ht(this.source),n=>{Pt(n)&&Qt(n,this)}),this._active.clear(),esm_ct(this)}eventObserved(n){n.type=="change"?n.idle?this.advance():(this._active.add(n.parent),this._start()):n.type=="idle"?this._active.delete(n.parent):n.type=="priority"&&(this.priority=ht(this.source).reduce((r,o)=>Math.max(r,(esm_Re(o)?o.priority:0)+1),0))}};function vr(t){return t.idle!==!1}function Yt(t){return!t.size||Array.from(t).every(vr)}function esm_ct(t){t.idle||(t.idle=!0,esm_Ve(F(t),e=>{e.done=!0}),$t(t,{type:"idle",parent:t}))}var esm_ui=(t,...e)=>new esm_W(t,e),pi=(t,...e)=>(Cr(),new esm_W(t,e));dist_esm_p.assign({createStringInterpolator:Xt,to:(t,e)=>new esm_W(t,e)});var di=qe.advance; 36751 36752 ;// CONCATENATED MODULE: external "ReactDOM" 36753 const external_ReactDOM_namespaceObject = window["ReactDOM"]; 36754 ;// CONCATENATED MODULE: ./node_modules/@react-spring/web/dist/esm/index.js 36755 var web_dist_esm_k=/^--/;function web_dist_esm_I(t,e){return e==null||typeof e=="boolean"||e===""?"":typeof e=="number"&&e!==0&&!web_dist_esm_k.test(t)&&!(web_dist_esm_c.hasOwnProperty(t)&&web_dist_esm_c[t])?e+"px":(""+e).trim()}var web_dist_esm_v={};function esm_V(t,e){if(!t.nodeType||!t.setAttribute)return!1;let r=t.nodeName==="filter"||t.parentNode&&t.parentNode.nodeName==="filter",{style:i,children:s,scrollTop:u,scrollLeft:l,viewBox:a,...n}=e,d=Object.values(n),m=Object.keys(n).map(o=>r||t.hasAttribute(o)?o:web_dist_esm_v[o]||(web_dist_esm_v[o]=o.replace(/([A-Z])/g,p=>"-"+p.toLowerCase())));s!==void 0&&(t.textContent=s);for(let o in i)if(i.hasOwnProperty(o)){let p=web_dist_esm_I(o,i[o]);web_dist_esm_k.test(o)?t.style.setProperty(o,p):t.style[o]=p}m.forEach((o,p)=>{t.setAttribute(o,d[p])}),u!==void 0&&(t.scrollTop=u),l!==void 0&&(t.scrollLeft=l),a!==void 0&&t.setAttribute("viewBox",a)}var web_dist_esm_c={animationIterationCount:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},esm_F=(t,e)=>t+e.charAt(0).toUpperCase()+e.substring(1),esm_L=["Webkit","Ms","Moz","O"];web_dist_esm_c=Object.keys(web_dist_esm_c).reduce((t,e)=>(esm_L.forEach(r=>t[esm_F(r,e)]=t[e]),t),web_dist_esm_c);var esm_=/^(matrix|translate|scale|rotate|skew)/,dist_esm_$=/^(translate)/,dist_esm_G=/^(rotate|skew)/,web_dist_esm_y=(t,e)=>dist_esm_l.num(t)&&t!==0?t+e:t,web_dist_esm_h=(t,e)=>dist_esm_l.arr(t)?t.every(r=>web_dist_esm_h(r,e)):dist_esm_l.num(t)?t===e:parseFloat(t)===e,dist_esm_g=class extends animated_dist_esm_u{constructor({x:e,y:r,z:i,...s}){let u=[],l=[];(e||r||i)&&(u.push([e||0,r||0,i||0]),l.push(a=>[`translate3d($a.map(n=>web_dist_esm_y(n,"px")).join(",")})`,web_dist_esm_h(a,0)])),xt(s,(a,n)=>{if(n==="transform")u.push([a||""]),l.push(d=>[d,d===""]);else if(esm_.test(n)){if(delete s[n],dist_esm_l.und(a))return;let d=dist_esm_$.test(n)?"px":dist_esm_G.test(n)?"deg":"";u.push(ht(a)),l.push(n==="rotate3d"?([m,o,p,O])=>[`rotate3d($m},$o},$p},$web_dist_esm_y(O,d)})`,web_dist_esm_h(O,0)]:m=>[`$n}($m.map(o=>web_dist_esm_y(o,d)).join(",")})`,web_dist_esm_h(m,n.startsWith("scale")?1:0)])}}),u.length&&(s.transform=new web_dist_esm_x(u,l)),super(s)}},web_dist_esm_x=class extends esm_ge{constructor(r,i){super();this.inputs=r;this.transforms=i}_value=null;get(){return this._value||(this._value=this._get())}_get(){let r="",i=!0;return esm_Ve(this.inputs,(s,u)=>{let l=ve(s[0]),[a,n]=this.transforms[u](dist_esm_l.arr(l)?l:s.map(ve));r+=" "+a,i=i&&n}),i?"none":r}observerAdded(r){r==1&&esm_Ve(this.inputs,i=>esm_Ve(i,s=>Pt(s)&&Gt(s,this)))}observerRemoved(r){r==0&&esm_Ve(this.inputs,i=>esm_Ve(i,s=>Pt(s)&&Qt(s,this)))}eventObserved(r){r.type=="change"&&(this._value=null),$t(this,r)}};var esm_C=["a","abbr","address","area","article","aside","audio","b","base","bdi","bdo","big","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","data","datalist","dd","del","details","dfn","dialog","div","dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","kbd","keygen","label","legend","li","link","main","map","mark","menu","menuitem","meta","meter","nav","noscript","object","ol","optgroup","option","output","p","param","picture","pre","progress","q","rp","rt","ruby","s","samp","script","section","select","small","source","span","strong","style","sub","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","title","tr","track","u","ul","var","video","wbr","circle","clipPath","defs","ellipse","foreignObject","g","image","line","linearGradient","mask","path","pattern","polygon","polyline","radialGradient","rect","stop","svg","text","tspan"];dist_esm_p.assign({batchedUpdates:external_ReactDOM_namespaceObject.unstable_batchedUpdates,createStringInterpolator:Xt,colors:It});var dist_esm_q=dist_esm_Ke(esm_C,{applyAnimatedValues:esm_V,createAnimatedStyle:t=>new dist_esm_g(t),getComponentProps:({scrollTop:t,scrollLeft:e,...r})=>r}),dist_esm_it=dist_esm_q.animated; 36756 36757 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/use-moving-animation/index.js 36758 /** 36759 * External dependencies 36760 */ 36761 36762 36763 /** 36764 * WordPress dependencies 36765 */ 36766 36767 36768 36769 36770 /** 36771 * Internal dependencies 36772 */ 36773 36774 36775 /** 36776 * If the block count exceeds the threshold, we disable the reordering animation 36777 * to avoid laginess. 36778 */ 36779 const BLOCK_ANIMATION_THRESHOLD = 200; 36780 function getAbsolutePosition(element) { 36781 return { 36782 top: element.offsetTop, 36783 left: element.offsetLeft 36784 }; 36785 } 36786 36787 /** 36788 * Hook used to compute the styles required to move a div into a new position. 36789 * 36790 * The way this animation works is the following: 36791 * - It first renders the element as if there was no animation. 36792 * - It takes a snapshot of the position of the block to use it 36793 * as a destination point for the animation. 36794 * - It restores the element to the previous position using a CSS transform 36795 * - It uses the "resetAnimation" flag to reset the animation 36796 * from the beginning in order to animate to the new destination point. 36797 * 36798 * @param {Object} $1 Options 36799 * @param {*} $1.triggerAnimationOnChange Variable used to trigger the animation if it changes. 36800 * @param {string} $1.clientId 36801 */ 36802 function useMovingAnimation({ 36803 triggerAnimationOnChange, 36804 clientId 36805 }) { 36806 const ref = (0,external_wp_element_namespaceObject.useRef)(); 36807 const { 36808 isTyping, 36809 getGlobalBlockCount, 36810 isBlockSelected, 36811 isFirstMultiSelectedBlock, 36812 isBlockMultiSelected, 36813 isAncestorMultiSelected 36814 } = (0,external_wp_data_namespaceObject.useSelect)(store); 36815 36816 // Whenever the trigger changes, we need to take a snapshot of the current 36817 // position of the block to use it as a destination point for the animation. 36818 const { 36819 previous, 36820 prevRect 36821 } = (0,external_wp_element_namespaceObject.useMemo)(() => ({ 36822 previous: ref.current && getAbsolutePosition(ref.current), 36823 prevRect: ref.current && ref.current.getBoundingClientRect() 36824 }), 36825 // eslint-disable-next-line react-hooks/exhaustive-deps 36826 [triggerAnimationOnChange]); 36827 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 36828 if (!previous || !ref.current) { 36829 return; 36830 } 36831 const scrollContainer = (0,external_wp_dom_namespaceObject.getScrollContainer)(ref.current); 36832 const isSelected = isBlockSelected(clientId); 36833 const adjustScrolling = isSelected || isFirstMultiSelectedBlock(clientId); 36834 function preserveScrollPosition() { 36835 if (adjustScrolling && prevRect) { 36836 const blockRect = ref.current.getBoundingClientRect(); 36837 const diff = blockRect.top - prevRect.top; 36838 if (diff) { 36839 scrollContainer.scrollTop += diff; 36840 } 36841 } 36842 } 36843 36844 // We disable the animation if the user has a preference for reduced 36845 // motion, if the user is typing (insertion by Enter), or if the block 36846 // count exceeds the threshold (insertion caused all the blocks that 36847 // follow to animate). 36848 // To do: consider enableing the _moving_ animation even for large 36849 // posts, while only disabling the _insertion_ animation? 36850 const disableAnimation = window.matchMedia('(prefers-reduced-motion: reduce)').matches || isTyping() || getGlobalBlockCount() > BLOCK_ANIMATION_THRESHOLD; 36851 if (disableAnimation) { 36852 // If the animation is disabled and the scroll needs to be adjusted, 36853 // just move directly to the final scroll position. 36854 preserveScrollPosition(); 36855 return; 36856 } 36857 const isPartOfSelection = isSelected || isBlockMultiSelected(clientId) || isAncestorMultiSelected(clientId); 36858 // Make sure the other blocks move under the selected block(s). 36859 const zIndex = isPartOfSelection ? '1' : ''; 36860 const controller = new esm_le({ 36861 x: 0, 36862 y: 0, 36863 config: { 36864 mass: 5, 36865 tension: 2000, 36866 friction: 200 36867 }, 36868 onChange({ 36869 value 36870 }) { 36871 if (!ref.current) { 36872 return; 36873 } 36874 let { 36875 x, 36876 y 36877 } = value; 36878 x = Math.round(x); 36879 y = Math.round(y); 36880 const finishedMoving = x === 0 && y === 0; 36881 ref.current.style.transformOrigin = 'center center'; 36882 ref.current.style.transform = finishedMoving ? null // Set to `null` to explicitly remove the transform. 36883 : `translate3d($x}px,$y}px,0)`; 36884 ref.current.style.zIndex = zIndex; 36885 preserveScrollPosition(); 36886 } 36887 }); 36888 ref.current.style.transform = undefined; 36889 const destination = getAbsolutePosition(ref.current); 36890 const x = Math.round(previous.left - destination.left); 36891 const y = Math.round(previous.top - destination.top); 36892 controller.start({ 36893 x: 0, 36894 y: 0, 36895 from: { 36896 x, 36897 y 36898 } 36899 }); 36900 return () => { 36901 controller.stop(); 36902 controller.set({ 36903 x: 0, 36904 y: 0 36905 }); 36906 }; 36907 }, [previous, prevRect, clientId, isTyping, getGlobalBlockCount, isBlockSelected, isFirstMultiSelectedBlock, isBlockMultiSelected, isAncestorMultiSelected]); 36908 return ref; 36909 } 36910 /* harmony default export */ const use_moving_animation = (useMovingAnimation); 36911 36912 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/private-block-context.js 36913 /** 36914 * WordPress dependencies 36915 */ 36916 36917 const PrivateBlockContext = (0,external_wp_element_namespaceObject.createContext)({}); 36918 36919 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/dom.js 36920 const BLOCK_SELECTOR = '.block-editor-block-list__block'; 36921 const APPENDER_SELECTOR = '.block-list-appender'; 36922 const BLOCK_APPENDER_CLASS = '.block-editor-button-block-appender'; 36923 36924 /** 36925 * Returns true if two elements are contained within the same block. 36926 * 36927 * @param {Element} a First element. 36928 * @param {Element} b Second element. 36929 * 36930 * @return {boolean} Whether elements are in the same block. 36931 */ 36932 function isInSameBlock(a, b) { 36933 return a.closest(BLOCK_SELECTOR) === b.closest(BLOCK_SELECTOR); 36934 } 36935 36936 /** 36937 * Returns true if an element is considered part of the block and not its inner 36938 * blocks or appender. 36939 * 36940 * @param {Element} blockElement Block container element. 36941 * @param {Element} element Element. 36942 * 36943 * @return {boolean} Whether an element is considered part of the block and not 36944 * its inner blocks or appender. 36945 */ 36946 function isInsideRootBlock(blockElement, element) { 36947 const parentBlock = element.closest([BLOCK_SELECTOR, APPENDER_SELECTOR, BLOCK_APPENDER_CLASS].join(',')); 36948 return parentBlock === blockElement; 36949 } 36950 36951 /** 36952 * Finds the block client ID given any DOM node inside the block. 36953 * 36954 * @param {Node?} node DOM node. 36955 * 36956 * @return {string|undefined} Client ID or undefined if the node is not part of 36957 * a block. 36958 */ 36959 function getBlockClientId(node) { 36960 while (node && node.nodeType !== node.ELEMENT_NODE) { 36961 node = node.parentNode; 36962 } 36963 if (!node) { 36964 return; 36965 } 36966 const elementNode = /** @type {Element} */node; 36967 const blockNode = elementNode.closest(BLOCK_SELECTOR); 36968 if (!blockNode) { 36969 return; 36970 } 36971 return blockNode.id.slice('block-'.length); 36972 } 36973 36974 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/use-focus-first-element.js 36975 /** 36976 * WordPress dependencies 36977 */ 36978 36979 36980 36981 36982 /** 36983 * Internal dependencies 36984 */ 36985 36986 36987 36988 /** @typedef {import('@wordpress/element').RefObject} RefObject */ 36989 36990 /** 36991 * Transitions focus to the block or inner tabbable when the block becomes 36992 * selected and an initial position is set. 36993 * 36994 * @param {string} clientId Block client ID. 36995 * 36996 * @return {RefObject} React ref with the block element. 36997 */ 36998 function useFocusFirstElement({ 36999 clientId, 37000 initialPosition 37001 }) { 37002 const ref = (0,external_wp_element_namespaceObject.useRef)(); 37003 const { 37004 isBlockSelected, 37005 isMultiSelecting 37006 } = (0,external_wp_data_namespaceObject.useSelect)(store); 37007 (0,external_wp_element_namespaceObject.useEffect)(() => { 37008 // Check if the block is still selected at the time this effect runs. 37009 if (!isBlockSelected(clientId) || isMultiSelecting()) { 37010 return; 37011 } 37012 if (initialPosition === undefined || initialPosition === null) { 37013 return; 37014 } 37015 if (!ref.current) { 37016 return; 37017 } 37018 const { 37019 ownerDocument 37020 } = ref.current; 37021 37022 // Do not focus the block if it already contains the active element. 37023 if (isInsideRootBlock(ref.current, ownerDocument.activeElement)) { 37024 return; 37025 } 37026 37027 // Find all tabbables within node. 37028 const textInputs = external_wp_dom_namespaceObject.focus.tabbable.find(ref.current).filter(node => (0,external_wp_dom_namespaceObject.isTextField)(node)); 37029 37030 // If reversed (e.g. merge via backspace), use the last in the set of 37031 // tabbables. 37032 const isReverse = -1 === initialPosition; 37033 const target = textInputs[isReverse ? textInputs.length - 1 : 0] || ref.current; 37034 if (!isInsideRootBlock(ref.current, target)) { 37035 ref.current.focus(); 37036 return; 37037 } 37038 37039 // Check to see if element is focussable before a generic caret insert. 37040 if (!ref.current.getAttribute('contenteditable')) { 37041 const focusElement = external_wp_dom_namespaceObject.focus.tabbable.findNext(ref.current); 37042 // Make sure focusElement is valid, contained in the same block, and a form field. 37043 if (focusElement && isInsideRootBlock(ref.current, focusElement) && (0,external_wp_dom_namespaceObject.isFormElement)(focusElement)) { 37044 focusElement.focus(); 37045 return; 37046 } 37047 } 37048 (0,external_wp_dom_namespaceObject.placeCaretAtHorizontalEdge)(target, isReverse); 37049 }, [initialPosition, clientId]); 37050 return ref; 37051 } 37052 37053 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/use-is-hovered.js 37054 /** 37055 * WordPress dependencies 37056 */ 37057 37058 function listener(event) { 37059 if (event.defaultPrevented) { 37060 return; 37061 } 37062 const action = event.type === 'mouseover' ? 'add' : 'remove'; 37063 event.preventDefault(); 37064 event.currentTarget.classList[action]('is-hovered'); 37065 } 37066 37067 /* 37068 * Adds `is-hovered` class when the block is hovered and in navigation or 37069 * outline mode. 37070 */ 37071 function useIsHovered({ 37072 isEnabled 37073 }) { 37074 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 37075 if (isEnabled) { 37076 node.addEventListener('mouseout', listener); 37077 node.addEventListener('mouseover', listener); 37078 return () => { 37079 node.removeEventListener('mouseout', listener); 37080 node.removeEventListener('mouseover', listener); 37081 37082 // Remove class in case it lingers. 37083 node.classList.remove('is-hovered'); 37084 }; 37085 } 37086 }, [isEnabled]); 37087 } 37088 37089 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/use-focus-handler.js 37090 /** 37091 * WordPress dependencies 37092 */ 37093 37094 37095 37096 /** 37097 * Internal dependencies 37098 */ 37099 37100 37101 37102 /** 37103 * Selects the block if it receives focus. 37104 * 37105 * @param {string} clientId Block client ID. 37106 */ 37107 function useFocusHandler(clientId) { 37108 const { 37109 isBlockSelected 37110 } = (0,external_wp_data_namespaceObject.useSelect)(store); 37111 const { 37112 selectBlock, 37113 selectionChange 37114 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 37115 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 37116 /** 37117 * Marks the block as selected when focused and not already 37118 * selected. This specifically handles the case where block does not 37119 * set focus on its own (via `setFocus`), typically if there is no 37120 * focusable input in the block. 37121 * 37122 * @param {FocusEvent} event Focus event. 37123 */ 37124 function onFocus(event) { 37125 // When the whole editor is editable, let writing flow handle 37126 // selection. 37127 if (node.parentElement.closest('[contenteditable="true"]')) { 37128 return; 37129 } 37130 37131 // Check synchronously because a non-selected block might be 37132 // getting data through `useSelect` asynchronously. 37133 if (isBlockSelected(clientId)) { 37134 // Potentially change selection away from rich text. 37135 if (!event.target.isContentEditable) { 37136 selectionChange(clientId); 37137 } 37138 return; 37139 } 37140 37141 // If an inner block is focussed, that block is resposible for 37142 // setting the selected block. 37143 if (!isInsideRootBlock(node, event.target)) { 37144 return; 37145 } 37146 selectBlock(clientId); 37147 } 37148 node.addEventListener('focusin', onFocus); 37149 return () => { 37150 node.removeEventListener('focusin', onFocus); 37151 }; 37152 }, [isBlockSelected, selectBlock]); 37153 } 37154 37155 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/use-selected-block-event-handlers.js 37156 /** 37157 * WordPress dependencies 37158 */ 37159 37160 37161 37162 37163 37164 /** 37165 * Internal dependencies 37166 */ 37167 37168 37169 /** 37170 * Adds block behaviour: 37171 * - Removes the block on BACKSPACE. 37172 * - Inserts a default block on ENTER. 37173 * - Disables dragging of block contents. 37174 * 37175 * @param {string} clientId Block client ID. 37176 */ 37177 function useEventHandlers({ 37178 clientId, 37179 isSelected 37180 }) { 37181 const { 37182 getBlockRootClientId, 37183 getBlockIndex 37184 } = (0,external_wp_data_namespaceObject.useSelect)(store); 37185 const { 37186 insertAfterBlock, 37187 removeBlock 37188 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 37189 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 37190 if (!isSelected) { 37191 return; 37192 } 37193 37194 /** 37195 * Interprets keydown event intent to remove or insert after block if 37196 * key event occurs on wrapper node. This can occur when the block has 37197 * no text fields of its own, particularly after initial insertion, to 37198 * allow for easy deletion and continuous writing flow to add additional 37199 * content. 37200 * 37201 * @param {KeyboardEvent} event Keydown event. 37202 */ 37203 function onKeyDown(event) { 37204 const { 37205 keyCode, 37206 target 37207 } = event; 37208 if (keyCode !== external_wp_keycodes_namespaceObject.ENTER && keyCode !== external_wp_keycodes_namespaceObject.BACKSPACE && keyCode !== external_wp_keycodes_namespaceObject.DELETE) { 37209 return; 37210 } 37211 if (target !== node || (0,external_wp_dom_namespaceObject.isTextField)(target)) { 37212 return; 37213 } 37214 event.preventDefault(); 37215 if (keyCode === external_wp_keycodes_namespaceObject.ENTER) { 37216 insertAfterBlock(clientId); 37217 } else { 37218 removeBlock(clientId); 37219 } 37220 } 37221 37222 /** 37223 * Prevents default dragging behavior within a block. To do: we must 37224 * handle this in the future and clean up the drag target. 37225 * 37226 * @param {DragEvent} event Drag event. 37227 */ 37228 function onDragStart(event) { 37229 event.preventDefault(); 37230 } 37231 node.addEventListener('keydown', onKeyDown); 37232 node.addEventListener('dragstart', onDragStart); 37233 return () => { 37234 node.removeEventListener('keydown', onKeyDown); 37235 node.removeEventListener('dragstart', onDragStart); 37236 }; 37237 }, [clientId, isSelected, getBlockRootClientId, getBlockIndex, insertAfterBlock, removeBlock]); 37238 } 37239 37240 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/use-nav-mode-exit.js 37241 /** 37242 * WordPress dependencies 37243 */ 37244 37245 37246 37247 /** 37248 * Internal dependencies 37249 */ 37250 37251 37252 /** 37253 * Allows navigation mode to be exited by clicking in the selected block. 37254 * 37255 * @param {string} clientId Block client ID. 37256 */ 37257 function useNavModeExit(clientId) { 37258 const { 37259 isNavigationMode, 37260 isBlockSelected 37261 } = (0,external_wp_data_namespaceObject.useSelect)(store); 37262 const { 37263 setNavigationMode, 37264 selectBlock 37265 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 37266 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 37267 function onMouseDown(event) { 37268 // Don't select a block if it's already handled by a child 37269 // block. 37270 if (isNavigationMode() && !event.defaultPrevented) { 37271 // Prevent focus from moving to the block. 37272 event.preventDefault(); 37273 37274 // When clicking on a selected block, exit navigation mode. 37275 if (isBlockSelected(clientId)) { 37276 setNavigationMode(false); 37277 } else { 37278 selectBlock(clientId); 37279 } 37280 } 37281 } 37282 node.addEventListener('mousedown', onMouseDown); 37283 return () => { 37284 node.removeEventListener('mousedown', onMouseDown); 37285 }; 37286 }, [clientId, isNavigationMode, isBlockSelected, setNavigationMode]); 37287 } 37288 37289 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/use-intersection-observer.js 37290 /** 37291 * WordPress dependencies 37292 */ 37293 37294 37295 37296 /** 37297 * Internal dependencies 37298 */ 37299 37300 function useIntersectionObserver() { 37301 const observer = (0,external_wp_element_namespaceObject.useContext)(block_list_IntersectionObserver); 37302 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 37303 if (observer) { 37304 observer.observe(node); 37305 return () => { 37306 observer.unobserve(node); 37307 }; 37308 } 37309 }, [observer]); 37310 } 37311 37312 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/use-flash-editable-blocks/index.js 37313 /** 37314 * WordPress dependencies 37315 */ 37316 37317 37318 37319 /** 37320 * Internal dependencies 37321 */ 37322 37323 37324 function useFlashEditableBlocks({ 37325 clientId = '', 37326 isEnabled = true 37327 } = {}) { 37328 const { 37329 getEnabledClientIdsTree 37330 } = unlock((0,external_wp_data_namespaceObject.useSelect)(store)); 37331 return (0,external_wp_compose_namespaceObject.useRefEffect)(element => { 37332 if (!isEnabled) { 37333 return; 37334 } 37335 const flashEditableBlocks = () => { 37336 getEnabledClientIdsTree(clientId).forEach(({ 37337 clientId: id 37338 }) => { 37339 const block = element.querySelector(`[data-block="$id}"]`); 37340 if (!block) { 37341 return; 37342 } 37343 block.classList.remove('has-editable-outline'); 37344 // Force reflow to trigger the animation. 37345 // eslint-disable-next-line no-unused-expressions 37346 block.offsetWidth; 37347 block.classList.add('has-editable-outline'); 37348 }); 37349 }; 37350 const handleClick = event => { 37351 const shouldFlash = event.target === element || event.target.classList.contains('is-root-container'); 37352 if (!shouldFlash) { 37353 return; 37354 } 37355 if (event.defaultPrevented) { 37356 return; 37357 } 37358 event.preventDefault(); 37359 flashEditableBlocks(); 37360 }; 37361 element.addEventListener('click', handleClick); 37362 return () => element.removeEventListener('click', handleClick); 37363 }, [isEnabled]); 37364 } 37365 37366 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/index.js 37367 /** 37368 * External dependencies 37369 */ 37370 37371 37372 /** 37373 * WordPress dependencies 37374 */ 37375 37376 37377 37378 37379 37380 37381 /** 37382 * Internal dependencies 37383 */ 37384 37385 37386 37387 37388 37389 37390 37391 37392 37393 37394 37395 37396 37397 /** 37398 * This hook is used to lightly mark an element as a block element. The element 37399 * should be the outermost element of a block. Call this hook and pass the 37400 * returned props to the element to mark as a block. If you define a ref for the 37401 * element, it is important to pass the ref to this hook, which the hook in turn 37402 * will pass to the component through the props it returns. Optionally, you can 37403 * also pass any other props through this hook, and they will be merged and 37404 * returned. 37405 * 37406 * Use of this hook on the outermost element of a block is required if using API >= v2. 37407 * 37408 * @example 37409 * ```js 37410 * import { useBlockProps } from '@wordpress/block-editor'; 37411 * 37412 * export default function Edit() { 37413 * 37414 * const blockProps = useBlockProps( 37415 * className: 'my-custom-class', 37416 * style: { 37417 * color: '#222222', 37418 * backgroundColor: '#eeeeee' 37419 * } 37420 * ) 37421 * 37422 * return ( 37423 * <div { ...blockProps }> 37424 * 37425 * </div> 37426 * ) 37427 * } 37428 * 37429 * ``` 37430 * 37431 * 37432 * @param {Object} props Optional. Props to pass to the element. Must contain 37433 * the ref if one is defined. 37434 * @param {Object} options Options for internal use only. 37435 * @param {boolean} options.__unstableIsHtml 37436 * 37437 * @return {Object} Props to pass to the element to mark as a block. 37438 */ 37439 function use_block_props_useBlockProps(props = {}, { 37440 __unstableIsHtml 37441 } = {}) { 37442 const { 37443 clientId, 37444 className, 37445 wrapperProps = {}, 37446 isAligned, 37447 index, 37448 mode, 37449 name, 37450 blockApiVersion, 37451 blockTitle, 37452 isSelected, 37453 isSubtreeDisabled, 37454 isOutlineEnabled, 37455 hasOverlay, 37456 initialPosition, 37457 blockEditingMode, 37458 isHighlighted, 37459 isMultiSelected, 37460 isPartiallySelected, 37461 isReusable, 37462 isDragging, 37463 hasChildSelected, 37464 removeOutline, 37465 isBlockMovingMode, 37466 canInsertMovingBlock, 37467 isEditingDisabled, 37468 hasEditableOutline, 37469 isTemporarilyEditingAsBlocks, 37470 defaultClassName, 37471 templateLock 37472 } = (0,external_wp_element_namespaceObject.useContext)(PrivateBlockContext); 37473 37474 // translators: %s: Type of block (i.e. Text, Image etc) 37475 const blockLabel = (0,external_wp_i18n_namespaceObject.sprintf)((0,external_wp_i18n_namespaceObject.__)('Block: %s'), blockTitle); 37476 const htmlSuffix = mode === 'html' && !__unstableIsHtml ? '-visual' : ''; 37477 const mergedRefs = (0,external_wp_compose_namespaceObject.useMergeRefs)([props.ref, useFocusFirstElement({ 37478 clientId, 37479 initialPosition 37480 }), useBlockRefProvider(clientId), useFocusHandler(clientId), useEventHandlers({ 37481 clientId, 37482 isSelected 37483 }), useNavModeExit(clientId), useIsHovered({ 37484 isEnabled: isOutlineEnabled 37485 }), useIntersectionObserver(), use_moving_animation({ 37486 triggerAnimationOnChange: index, 37487 clientId 37488 }), (0,external_wp_compose_namespaceObject.useDisabled)({ 37489 isDisabled: !hasOverlay 37490 }), useFlashEditableBlocks({ 37491 clientId, 37492 isEnabled: name === 'core/block' || templateLock === 'contentOnly' 37493 })]); 37494 const blockEditContext = useBlockEditContext(); 37495 const hasBlockBindings = !!blockEditContext[blockBindingsKey]; 37496 const bindingsStyle = hasBlockBindings && canBindBlock(name) ? { 37497 '--wp-admin-theme-color': 'var(--wp-bound-block-color)' 37498 } : {}; 37499 37500 // Ensures it warns only inside the `edit` implementation for the block. 37501 if (blockApiVersion < 2 && clientId === blockEditContext.clientId) { 37502 true ? external_wp_warning_default()(`Block type "$name}" must support API version 2 or higher to work correctly with "useBlockProps" method.`) : 0; 37503 } 37504 return { 37505 tabIndex: blockEditingMode === 'disabled' ? -1 : 0, 37506 ...wrapperProps, 37507 ...props, 37508 ref: mergedRefs, 37509 id: `block-$clientId}$htmlSuffix}`, 37510 role: 'document', 37511 'aria-label': blockLabel, 37512 'data-block': clientId, 37513 'data-type': name, 37514 'data-title': blockTitle, 37515 inert: isSubtreeDisabled ? 'true' : undefined, 37516 className: classnames_default()('block-editor-block-list__block', { 37517 // The wp-block className is important for editor styles. 37518 'wp-block': !isAligned, 37519 'has-block-overlay': hasOverlay, 37520 'is-selected': isSelected, 37521 'is-highlighted': isHighlighted, 37522 'is-multi-selected': isMultiSelected, 37523 'is-partially-selected': isPartiallySelected, 37524 'is-reusable': isReusable, 37525 'is-dragging': isDragging, 37526 'has-child-selected': hasChildSelected, 37527 'remove-outline': removeOutline, 37528 'is-block-moving-mode': isBlockMovingMode, 37529 'can-insert-moving-block': canInsertMovingBlock, 37530 'is-editing-disabled': isEditingDisabled, 37531 'has-editable-outline': hasEditableOutline, 37532 'is-content-locked-temporarily-editing-as-blocks': isTemporarilyEditingAsBlocks 37533 }, className, props.className, wrapperProps.className, defaultClassName), 37534 style: { 37535 ...wrapperProps.style, 37536 ...props.style, 37537 ...bindingsStyle 37538 } 37539 }; 37540 } 37541 37542 /** 37543 * Call within a save function to get the props for the block wrapper. 37544 * 37545 * @param {Object} props Optional. Props to pass to the element. 37546 */ 37547 use_block_props_useBlockProps.save = external_wp_blocks_namespaceObject.__unstableGetBlockProps; 37548 37549 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/block.js 37550 37551 /** 37552 * External dependencies 37553 */ 37554 37555 37556 /** 37557 * WordPress dependencies 37558 */ 37559 37560 37561 37562 37563 37564 37565 37566 /** 37567 * Internal dependencies 37568 */ 37569 37570 37571 37572 37573 37574 37575 37576 37577 37578 37579 37580 /** 37581 * Merges wrapper props with special handling for classNames and styles. 37582 * 37583 * @param {Object} propsA 37584 * @param {Object} propsB 37585 * 37586 * @return {Object} Merged props. 37587 */ 37588 function mergeWrapperProps(propsA, propsB) { 37589 const newProps = { 37590 ...propsA, 37591 ...propsB 37592 }; 37593 37594 // May be set to undefined, so check if the property is set! 37595 if (propsA?.hasOwnProperty('className') && propsB?.hasOwnProperty('className')) { 37596 newProps.className = classnames_default()(propsA.className, propsB.className); 37597 } 37598 if (propsA?.hasOwnProperty('style') && propsB?.hasOwnProperty('style')) { 37599 newProps.style = { 37600 ...propsA.style, 37601 ...propsB.style 37602 }; 37603 } 37604 return newProps; 37605 } 37606 function Block({ 37607 children, 37608 isHtml, 37609 ...props 37610 }) { 37611 return (0,external_React_.createElement)("div", { 37612 ...use_block_props_useBlockProps(props, { 37613 __unstableIsHtml: isHtml 37614 }) 37615 }, children); 37616 } 37617 function BlockListBlock({ 37618 block: { 37619 __unstableBlockSource 37620 }, 37621 mode, 37622 isLocked, 37623 canRemove, 37624 clientId, 37625 isSelected, 37626 isSelectionEnabled, 37627 className, 37628 __unstableLayoutClassNames: layoutClassNames, 37629 name, 37630 isValid, 37631 attributes, 37632 wrapperProps, 37633 setAttributes, 37634 onReplace, 37635 onInsertBlocksAfter, 37636 onMerge, 37637 toggleSelection 37638 }) { 37639 var _wrapperProps; 37640 const { 37641 mayDisplayControls, 37642 mayDisplayParentControls, 37643 themeSupportsLayout, 37644 ...context 37645 } = (0,external_wp_element_namespaceObject.useContext)(PrivateBlockContext); 37646 const { 37647 removeBlock 37648 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 37649 const onRemove = (0,external_wp_element_namespaceObject.useCallback)(() => removeBlock(clientId), [clientId]); 37650 const parentLayout = useLayout() || {}; 37651 37652 // We wrap the BlockEdit component in a div that hides it when editing in 37653 // HTML mode. This allows us to render all of the ancillary pieces 37654 // (InspectorControls, etc.) which are inside `BlockEdit` but not 37655 // `BlockHTML`, even in HTML mode. 37656 let blockEdit = (0,external_React_.createElement)(BlockEdit, { 37657 name: name, 37658 isSelected: isSelected, 37659 attributes: attributes, 37660 setAttributes: setAttributes, 37661 insertBlocksAfter: isLocked ? undefined : onInsertBlocksAfter, 37662 onReplace: canRemove ? onReplace : undefined, 37663 onRemove: canRemove ? onRemove : undefined, 37664 mergeBlocks: canRemove ? onMerge : undefined, 37665 clientId: clientId, 37666 isSelectionEnabled: isSelectionEnabled, 37667 toggleSelection: toggleSelection, 37668 __unstableLayoutClassNames: layoutClassNames, 37669 __unstableParentLayout: Object.keys(parentLayout).length ? parentLayout : undefined, 37670 mayDisplayControls: mayDisplayControls, 37671 mayDisplayParentControls: mayDisplayParentControls, 37672 blockEditingMode: context.blockEditingMode 37673 }); 37674 const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(name); 37675 37676 // Determine whether the block has props to apply to the wrapper. 37677 if (blockType?.getEditWrapperProps) { 37678 wrapperProps = mergeWrapperProps(wrapperProps, blockType.getEditWrapperProps(attributes)); 37679 } 37680 const isAligned = wrapperProps && !!wrapperProps['data-align'] && !themeSupportsLayout; 37681 37682 // Support for sticky position in classic themes with alignment wrappers. 37683 37684 const isSticky = className?.includes('is-position-sticky'); 37685 37686 // For aligned blocks, provide a wrapper element so the block can be 37687 // positioned relative to the block column. 37688 // This is only kept for classic themes that don't support layout 37689 // Historically we used to rely on extra divs and data-align to 37690 // provide the alignments styles in the editor. 37691 // Due to the differences between frontend and backend, we migrated 37692 // to the layout feature, and we're now aligning the markup of frontend 37693 // and backend. 37694 if (isAligned) { 37695 blockEdit = (0,external_React_.createElement)("div", { 37696 className: classnames_default()('wp-block', isSticky && className), 37697 "data-align": wrapperProps['data-align'] 37698 }, blockEdit); 37699 } 37700 let block; 37701 if (!isValid) { 37702 const saveContent = __unstableBlockSource ? (0,external_wp_blocks_namespaceObject.serializeRawBlock)(__unstableBlockSource) : (0,external_wp_blocks_namespaceObject.getSaveContent)(blockType, attributes); 37703 block = (0,external_React_.createElement)(Block, { 37704 className: "has-warning" 37705 }, (0,external_React_.createElement)(BlockInvalidWarning, { 37706 clientId: clientId 37707 }), (0,external_React_.createElement)(external_wp_element_namespaceObject.RawHTML, null, (0,external_wp_dom_namespaceObject.safeHTML)(saveContent))); 37708 } else if (mode === 'html') { 37709 // Render blockEdit so the inspector controls don't disappear. 37710 // See #8969. 37711 block = (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)("div", { 37712 style: { 37713 display: 'none' 37714 } 37715 }, blockEdit), (0,external_React_.createElement)(Block, { 37716 isHtml: true 37717 }, (0,external_React_.createElement)(block_html, { 37718 clientId: clientId 37719 }))); 37720 } else if (blockType?.apiVersion > 1) { 37721 block = blockEdit; 37722 } else { 37723 block = (0,external_React_.createElement)(Block, null, blockEdit); 37724 } 37725 const { 37726 'data-align': dataAlign, 37727 ...restWrapperProps 37728 } = (_wrapperProps = wrapperProps) !== null && _wrapperProps !== void 0 ? _wrapperProps : {}; 37729 restWrapperProps.className = classnames_default()(restWrapperProps.className, dataAlign && themeSupportsLayout && `align$dataAlign}`, !(dataAlign && isSticky) && className); 37730 37731 // We set a new context with the adjusted and filtered wrapperProps (through 37732 // `editor.BlockListBlock`), which the `BlockListBlockProvider` did not have 37733 // access to. 37734 return (0,external_React_.createElement)(PrivateBlockContext.Provider, { 37735 value: { 37736 wrapperProps: restWrapperProps, 37737 isAligned, 37738 ...context 37739 } 37740 }, (0,external_React_.createElement)(block_crash_boundary, { 37741 fallback: (0,external_React_.createElement)(Block, { 37742 className: "has-warning" 37743 }, (0,external_React_.createElement)(block_crash_warning, null)) 37744 }, block)); 37745 } 37746 const applyWithDispatch = (0,external_wp_data_namespaceObject.withDispatch)((dispatch, ownProps, registry) => { 37747 const { 37748 updateBlockAttributes, 37749 insertBlocks, 37750 mergeBlocks, 37751 replaceBlocks, 37752 toggleSelection, 37753 __unstableMarkLastChangeAsPersistent, 37754 moveBlocksToPosition, 37755 removeBlock 37756 } = dispatch(store); 37757 37758 // Do not add new properties here, use `useDispatch` instead to avoid 37759 // leaking new props to the public API (editor.BlockListBlock filter). 37760 return { 37761 setAttributes(newAttributes) { 37762 const { 37763 getMultiSelectedBlockClientIds 37764 } = registry.select(store); 37765 const multiSelectedBlockClientIds = getMultiSelectedBlockClientIds(); 37766 const { 37767 clientId 37768 } = ownProps; 37769 const clientIds = multiSelectedBlockClientIds.length ? multiSelectedBlockClientIds : [clientId]; 37770 updateBlockAttributes(clientIds, newAttributes); 37771 }, 37772 onInsertBlocks(blocks, index) { 37773 const { 37774 rootClientId 37775 } = ownProps; 37776 insertBlocks(blocks, index, rootClientId); 37777 }, 37778 onInsertBlocksAfter(blocks) { 37779 const { 37780 clientId, 37781 rootClientId 37782 } = ownProps; 37783 const { 37784 getBlockIndex 37785 } = registry.select(store); 37786 const index = getBlockIndex(clientId); 37787 insertBlocks(blocks, index + 1, rootClientId); 37788 }, 37789 onMerge(forward) { 37790 const { 37791 clientId, 37792 rootClientId 37793 } = ownProps; 37794 const { 37795 getPreviousBlockClientId, 37796 getNextBlockClientId, 37797 getBlock, 37798 getBlockAttributes, 37799 getBlockName, 37800 getBlockOrder, 37801 getBlockIndex, 37802 getBlockRootClientId, 37803 canInsertBlockType 37804 } = registry.select(store); 37805 37806 /** 37807 * Moves the block with clientId up one level. If the block type 37808 * cannot be inserted at the new location, it will be attempted to 37809 * convert to the default block type. 37810 * 37811 * @param {string} _clientId The block to move. 37812 * @param {boolean} changeSelection Whether to change the selection 37813 * to the moved block. 37814 */ 37815 function moveFirstItemUp(_clientId, changeSelection = true) { 37816 const targetRootClientId = getBlockRootClientId(_clientId); 37817 const blockOrder = getBlockOrder(_clientId); 37818 const [firstClientId] = blockOrder; 37819 if (blockOrder.length === 1 && (0,external_wp_blocks_namespaceObject.isUnmodifiedBlock)(getBlock(firstClientId))) { 37820 removeBlock(_clientId); 37821 } else { 37822 registry.batch(() => { 37823 if (canInsertBlockType(getBlockName(firstClientId), targetRootClientId)) { 37824 moveBlocksToPosition([firstClientId], _clientId, targetRootClientId, getBlockIndex(_clientId)); 37825 } else { 37826 const replacement = (0,external_wp_blocks_namespaceObject.switchToBlockType)(getBlock(firstClientId), (0,external_wp_blocks_namespaceObject.getDefaultBlockName)()); 37827 if (replacement && replacement.length) { 37828 insertBlocks(replacement, getBlockIndex(_clientId), targetRootClientId, changeSelection); 37829 removeBlock(firstClientId, false); 37830 } 37831 } 37832 if (!getBlockOrder(_clientId).length && (0,external_wp_blocks_namespaceObject.isUnmodifiedBlock)(getBlock(_clientId))) { 37833 removeBlock(_clientId, false); 37834 } 37835 }); 37836 } 37837 } 37838 37839 // For `Delete` or forward merge, we should do the exact same thing 37840 // as `Backspace`, but from the other block. 37841 if (forward) { 37842 if (rootClientId) { 37843 const nextRootClientId = getNextBlockClientId(rootClientId); 37844 if (nextRootClientId) { 37845 // If there is a block that follows with the same parent 37846 // block name and the same attributes, merge the inner 37847 // blocks. 37848 if (getBlockName(rootClientId) === getBlockName(nextRootClientId)) { 37849 const rootAttributes = getBlockAttributes(rootClientId); 37850 const previousRootAttributes = getBlockAttributes(nextRootClientId); 37851 if (Object.keys(rootAttributes).every(key => rootAttributes[key] === previousRootAttributes[key])) { 37852 registry.batch(() => { 37853 moveBlocksToPosition(getBlockOrder(nextRootClientId), nextRootClientId, rootClientId); 37854 removeBlock(nextRootClientId, false); 37855 }); 37856 return; 37857 } 37858 } else { 37859 mergeBlocks(rootClientId, nextRootClientId); 37860 return; 37861 } 37862 } 37863 } 37864 const nextBlockClientId = getNextBlockClientId(clientId); 37865 if (!nextBlockClientId) { 37866 return; 37867 } 37868 if (getBlockOrder(nextBlockClientId).length) { 37869 moveFirstItemUp(nextBlockClientId, false); 37870 } else { 37871 mergeBlocks(clientId, nextBlockClientId); 37872 } 37873 } else { 37874 const previousBlockClientId = getPreviousBlockClientId(clientId); 37875 if (previousBlockClientId) { 37876 mergeBlocks(previousBlockClientId, clientId); 37877 } else if (rootClientId) { 37878 const previousRootClientId = getPreviousBlockClientId(rootClientId); 37879 37880 // If there is a preceding block with the same parent block 37881 // name and the same attributes, merge the inner blocks. 37882 if (previousRootClientId && getBlockName(rootClientId) === getBlockName(previousRootClientId)) { 37883 const rootAttributes = getBlockAttributes(rootClientId); 37884 const previousRootAttributes = getBlockAttributes(previousRootClientId); 37885 if (Object.keys(rootAttributes).every(key => rootAttributes[key] === previousRootAttributes[key])) { 37886 registry.batch(() => { 37887 moveBlocksToPosition(getBlockOrder(rootClientId), rootClientId, previousRootClientId); 37888 removeBlock(rootClientId, false); 37889 }); 37890 return; 37891 } 37892 } 37893 moveFirstItemUp(rootClientId); 37894 } else { 37895 removeBlock(clientId); 37896 } 37897 } 37898 }, 37899 onReplace(blocks, indexToSelect, initialPosition) { 37900 if (blocks.length && !(0,external_wp_blocks_namespaceObject.isUnmodifiedDefaultBlock)(blocks[blocks.length - 1])) { 37901 __unstableMarkLastChangeAsPersistent(); 37902 } 37903 //Unsynced patterns are nested in an array so we need to flatten them. 37904 const replacementBlocks = blocks?.length === 1 && Array.isArray(blocks[0]) ? blocks[0] : blocks; 37905 replaceBlocks([ownProps.clientId], replacementBlocks, indexToSelect, initialPosition); 37906 }, 37907 toggleSelection(selectionEnabled) { 37908 toggleSelection(selectionEnabled); 37909 } 37910 }; 37911 }); 37912 37913 // This component is used by the BlockListBlockProvider component below. It will 37914 // add the props necessary for the `editor.BlockListBlock` filters. 37915 BlockListBlock = (0,external_wp_compose_namespaceObject.compose)(applyWithDispatch, (0,external_wp_components_namespaceObject.withFilters)('editor.BlockListBlock'))(BlockListBlock); 37916 37917 // This component provides all the information we need through a single store 37918 // subscription (useSelect mapping). Only the necessary props are passed down 37919 // to the BlockListBlock component, which is a filtered component, so these 37920 // props are public API. To avoid adding to the public API, we use a private 37921 // context to pass the rest of the information to the filtered BlockListBlock 37922 // component, and useBlockProps. 37923 function BlockListBlockProvider(props) { 37924 const { 37925 clientId, 37926 rootClientId 37927 } = props; 37928 const selectedProps = (0,external_wp_data_namespaceObject.useSelect)(select => { 37929 const { 37930 isBlockSelected, 37931 getBlockMode, 37932 isSelectionEnabled, 37933 getTemplateLock, 37934 getBlockWithoutAttributes, 37935 getBlockAttributes, 37936 canRemoveBlock, 37937 canMoveBlock, 37938 getSettings, 37939 __unstableGetTemporarilyEditingAsBlocks, 37940 getBlockEditingMode, 37941 getBlockName, 37942 isFirstMultiSelectedBlock, 37943 getMultiSelectedBlockClientIds, 37944 hasSelectedInnerBlock, 37945 getBlockIndex, 37946 isTyping, 37947 isBlockMultiSelected, 37948 isBlockSubtreeDisabled, 37949 isBlockHighlighted, 37950 __unstableIsFullySelected, 37951 __unstableSelectionHasUnmergeableBlock, 37952 isBlockBeingDragged, 37953 isDragging, 37954 hasBlockMovingClientId, 37955 canInsertBlockType, 37956 __unstableHasActiveBlockOverlayActive, 37957 __unstableGetEditorMode, 37958 getSelectedBlocksInitialCaretPosition 37959 } = unlock(select(store)); 37960 const blockWithoutAttributes = getBlockWithoutAttributes(clientId); 37961 37962 // This is a temporary fix. 37963 // This function should never be called when a block is not 37964 // present in the state. It happens now because the order in 37965 // withSelect rendering is not correct. 37966 if (!blockWithoutAttributes) { 37967 return; 37968 } 37969 const { 37970 hasBlockSupport: _hasBlockSupport, 37971 getActiveBlockVariation 37972 } = select(external_wp_blocks_namespaceObject.store); 37973 const _isSelected = isBlockSelected(clientId); 37974 const canRemove = canRemoveBlock(clientId, rootClientId); 37975 const canMove = canMoveBlock(clientId, rootClientId); 37976 const attributes = getBlockAttributes(clientId); 37977 const { 37978 name: blockName, 37979 isValid 37980 } = blockWithoutAttributes; 37981 const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockName); 37982 const match = getActiveBlockVariation(blockName, attributes); 37983 const { 37984 outlineMode, 37985 supportsLayout 37986 } = getSettings(); 37987 const isMultiSelected = isBlockMultiSelected(clientId); 37988 const checkDeep = true; 37989 const isAncestorOfSelectedBlock = hasSelectedInnerBlock(clientId, checkDeep); 37990 const typing = isTyping(); 37991 const hasLightBlockWrapper = blockType?.apiVersion > 1; 37992 const movingClientId = hasBlockMovingClientId(); 37993 const blockEditingMode = getBlockEditingMode(clientId); 37994 return { 37995 mode: getBlockMode(clientId), 37996 isSelectionEnabled: isSelectionEnabled(), 37997 isLocked: !!getTemplateLock(rootClientId), 37998 templateLock: getTemplateLock(clientId), 37999 canRemove, 38000 canMove, 38001 blockWithoutAttributes, 38002 name: blockName, 38003 attributes, 38004 isValid, 38005 isSelected: _isSelected, 38006 themeSupportsLayout: supportsLayout, 38007 isTemporarilyEditingAsBlocks: __unstableGetTemporarilyEditingAsBlocks() === clientId, 38008 blockEditingMode, 38009 mayDisplayControls: _isSelected || isFirstMultiSelectedBlock(clientId) && getMultiSelectedBlockClientIds().every(id => getBlockName(id) === blockName), 38010 mayDisplayParentControls: _hasBlockSupport(getBlockName(clientId), '__experimentalExposeControlsToChildren', false) && hasSelectedInnerBlock(clientId), 38011 index: getBlockIndex(clientId), 38012 blockApiVersion: blockType?.apiVersion || 1, 38013 blockTitle: match?.title || blockType?.title, 38014 isSubtreeDisabled: blockEditingMode === 'disabled' && isBlockSubtreeDisabled(clientId), 38015 isOutlineEnabled: outlineMode, 38016 hasOverlay: __unstableHasActiveBlockOverlayActive(clientId) && !isDragging(), 38017 initialPosition: _isSelected && __unstableGetEditorMode() === 'edit' ? getSelectedBlocksInitialCaretPosition() : undefined, 38018 isHighlighted: isBlockHighlighted(clientId), 38019 isMultiSelected, 38020 isPartiallySelected: isMultiSelected && !__unstableIsFullySelected() && !__unstableSelectionHasUnmergeableBlock(), 38021 isReusable: (0,external_wp_blocks_namespaceObject.isReusableBlock)(blockType), 38022 isDragging: isBlockBeingDragged(clientId), 38023 hasChildSelected: isAncestorOfSelectedBlock, 38024 removeOutline: _isSelected && outlineMode && typing, 38025 isBlockMovingMode: !!movingClientId, 38026 canInsertMovingBlock: movingClientId && canInsertBlockType(getBlockName(movingClientId), rootClientId), 38027 isEditingDisabled: blockEditingMode === 'disabled', 38028 hasEditableOutline: blockEditingMode !== 'disabled' && getBlockEditingMode(rootClientId) === 'disabled', 38029 className: hasLightBlockWrapper ? attributes.className : undefined, 38030 defaultClassName: hasLightBlockWrapper ? (0,external_wp_blocks_namespaceObject.getBlockDefaultClassName)(blockName) : undefined 38031 }; 38032 }, [clientId, rootClientId]); 38033 const { 38034 mode, 38035 isSelectionEnabled, 38036 isLocked, 38037 canRemove, 38038 canMove, 38039 blockWithoutAttributes, 38040 name, 38041 attributes, 38042 isValid, 38043 isSelected, 38044 themeSupportsLayout, 38045 isTemporarilyEditingAsBlocks, 38046 blockEditingMode, 38047 mayDisplayControls, 38048 mayDisplayParentControls, 38049 index, 38050 blockApiVersion, 38051 blockTitle, 38052 isSubtreeDisabled, 38053 isOutlineEnabled, 38054 hasOverlay, 38055 initialPosition, 38056 isHighlighted, 38057 isMultiSelected, 38058 isPartiallySelected, 38059 isReusable, 38060 isDragging, 38061 hasChildSelected, 38062 removeOutline, 38063 isBlockMovingMode, 38064 canInsertMovingBlock, 38065 templateLock, 38066 isEditingDisabled, 38067 hasEditableOutline, 38068 className, 38069 defaultClassName 38070 } = selectedProps; 38071 38072 // Users of the editor.BlockListBlock filter used to be able to 38073 // access the block prop. 38074 // Ideally these blocks would rely on the clientId prop only. 38075 // This is kept for backward compatibility reasons. 38076 const block = (0,external_wp_element_namespaceObject.useMemo)(() => ({ 38077 ...blockWithoutAttributes, 38078 attributes 38079 }), [blockWithoutAttributes, attributes]); 38080 38081 // Block is sometimes not mounted at the right time, causing it be 38082 // undefined see issue for more info 38083 // https://github.com/WordPress/gutenberg/issues/17013 38084 if (!selectedProps) { 38085 return null; 38086 } 38087 const privateContext = { 38088 clientId, 38089 className, 38090 index, 38091 mode, 38092 name, 38093 blockApiVersion, 38094 blockTitle, 38095 isSelected, 38096 isSubtreeDisabled, 38097 isOutlineEnabled, 38098 hasOverlay, 38099 initialPosition, 38100 blockEditingMode, 38101 isHighlighted, 38102 isMultiSelected, 38103 isPartiallySelected, 38104 isReusable, 38105 isDragging, 38106 hasChildSelected, 38107 removeOutline, 38108 isBlockMovingMode, 38109 canInsertMovingBlock, 38110 templateLock, 38111 isEditingDisabled, 38112 hasEditableOutline, 38113 isTemporarilyEditingAsBlocks, 38114 defaultClassName, 38115 mayDisplayControls, 38116 mayDisplayParentControls, 38117 themeSupportsLayout 38118 }; 38119 38120 // Here we separate between the props passed to BlockListBlock and any other 38121 // information we selected for internal use. BlockListBlock is a filtered 38122 // component and thus ALL the props are PUBLIC API. 38123 38124 // Note that the context value doesn't have to be memoized in this case 38125 // because when it changes, this component will be re-rendered anyway, and 38126 // none of the consumers (BlockListBlock and useBlockProps) are memoized or 38127 // "pure". This is different from the public BlockEditContext, where 38128 // consumers might be memoized or "pure". 38129 return (0,external_React_.createElement)(PrivateBlockContext.Provider, { 38130 value: privateContext 38131 }, (0,external_React_.createElement)(BlockListBlock, { 38132 ...props, 38133 mode, 38134 isSelectionEnabled, 38135 isLocked, 38136 canRemove, 38137 canMove, 38138 // Users of the editor.BlockListBlock filter used to be able 38139 // to access the block prop. Ideally these blocks would rely 38140 // on the clientId prop only. This is kept for backward 38141 // compatibility reasons. 38142 block, 38143 name, 38144 attributes, 38145 isValid, 38146 isSelected 38147 })); 38148 } 38149 /* harmony default export */ const block_list_block = ((0,external_wp_element_namespaceObject.memo)(BlockListBlockProvider)); 38150 38151 ;// CONCATENATED MODULE: external ["wp","htmlEntities"] 38152 const external_wp_htmlEntities_namespaceObject = window["wp"]["htmlEntities"]; 38153 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/tips.js 38154 38155 /** 38156 * WordPress dependencies 38157 */ 38158 38159 38160 38161 const globalTips = [(0,external_wp_element_namespaceObject.createInterpolateElement)((0,external_wp_i18n_namespaceObject.__)('While writing, you can press <kbd>/</kbd> to quickly insert new blocks.'), { 38162 kbd: (0,external_React_.createElement)("kbd", null) 38163 }), (0,external_wp_element_namespaceObject.createInterpolateElement)((0,external_wp_i18n_namespaceObject.__)('Indent a list by pressing <kbd>space</kbd> at the beginning of a line.'), { 38164 kbd: (0,external_React_.createElement)("kbd", null) 38165 }), (0,external_wp_element_namespaceObject.createInterpolateElement)((0,external_wp_i18n_namespaceObject.__)('Outdent a list by pressing <kbd>backspace</kbd> at the beginning of a line.'), { 38166 kbd: (0,external_React_.createElement)("kbd", null) 38167 }), (0,external_wp_i18n_namespaceObject.__)('Drag files into the editor to automatically insert media blocks.'), (0,external_wp_i18n_namespaceObject.__)("Change a block's type by pressing the block icon on the toolbar.")]; 38168 function Tips() { 38169 const [randomIndex] = (0,external_wp_element_namespaceObject.useState)( 38170 // Disable Reason: I'm not generating an HTML id. 38171 // eslint-disable-next-line no-restricted-syntax 38172 Math.floor(Math.random() * globalTips.length)); 38173 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Tip, null, globalTips[randomIndex]); 38174 } 38175 /* harmony default export */ const tips = (Tips); 38176 38177 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/chevron-right.js 38178 38179 /** 38180 * WordPress dependencies 38181 */ 38182 38183 const chevronRight = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 38184 xmlns: "http://www.w3.org/2000/svg", 38185 viewBox: "0 0 24 24" 38186 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 38187 d: "M10.6 6L9.4 7l4.6 5-4.6 5 1.2 1 5.4-6z" 38188 })); 38189 /* harmony default export */ const chevron_right = (chevronRight); 38190 38191 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/chevron-left.js 38192 38193 /** 38194 * WordPress dependencies 38195 */ 38196 38197 const chevronLeft = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 38198 xmlns: "http://www.w3.org/2000/svg", 38199 viewBox: "0 0 24 24" 38200 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 38201 d: "M14.6 7l-1.2-1L8 12l5.4 6 1.2-1-4.6-5z" 38202 })); 38203 /* harmony default export */ const chevron_left = (chevronLeft); 38204 38205 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-card/index.js 38206 38207 /** 38208 * External dependencies 38209 */ 38210 38211 38212 /** 38213 * WordPress dependencies 38214 */ 38215 38216 38217 38218 38219 38220 38221 /** 38222 * Internal dependencies 38223 */ 38224 38225 38226 function BlockCard({ 38227 title, 38228 icon, 38229 description, 38230 blockType, 38231 className 38232 }) { 38233 if (blockType) { 38234 external_wp_deprecated_default()('`blockType` property in `BlockCard component`', { 38235 since: '5.7', 38236 alternative: '`title, icon and description` properties' 38237 }); 38238 ({ 38239 title, 38240 icon, 38241 description 38242 } = blockType); 38243 } 38244 const { 38245 parentNavBlockClientId 38246 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 38247 const { 38248 getSelectedBlockClientId, 38249 getBlockParentsByBlockName 38250 } = select(store); 38251 const _selectedBlockClientId = getSelectedBlockClientId(); 38252 return { 38253 parentNavBlockClientId: getBlockParentsByBlockName(_selectedBlockClientId, 'core/navigation', true)[0] 38254 }; 38255 }, []); 38256 const { 38257 selectBlock 38258 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 38259 return (0,external_React_.createElement)("div", { 38260 className: classnames_default()('block-editor-block-card', className) 38261 }, parentNavBlockClientId && 38262 // This is only used by the Navigation block for now. It's not ideal having Navigation block specific code here. 38263 (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 38264 onClick: () => selectBlock(parentNavBlockClientId), 38265 label: (0,external_wp_i18n_namespaceObject.__)('Go to parent Navigation block'), 38266 style: 38267 // TODO: This style override is also used in ToolsPanelHeader. 38268 // It should be supported out-of-the-box by Button. 38269 { 38270 minWidth: 24, 38271 padding: 0 38272 }, 38273 icon: (0,external_wp_i18n_namespaceObject.isRTL)() ? chevron_right : chevron_left, 38274 size: "small" 38275 }), (0,external_React_.createElement)(block_icon, { 38276 icon: icon, 38277 showColors: true 38278 }), (0,external_React_.createElement)("div", { 38279 className: "block-editor-block-card__content" 38280 }, (0,external_React_.createElement)("h2", { 38281 className: "block-editor-block-card__title" 38282 }, title), description && (0,external_React_.createElement)("span", { 38283 className: "block-editor-block-card__description" 38284 }, description))); 38285 } 38286 /* harmony default export */ const block_card = (BlockCard); 38287 38288 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/provider/with-registry-provider.js 38289 38290 /** 38291 * WordPress dependencies 38292 */ 38293 38294 38295 38296 38297 /** 38298 * Internal dependencies 38299 */ 38300 38301 38302 const withRegistryProvider = (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(WrappedComponent => { 38303 return (0,external_wp_data_namespaceObject.withRegistry)(({ 38304 useSubRegistry = true, 38305 registry, 38306 ...props 38307 }) => { 38308 if (!useSubRegistry) { 38309 return (0,external_React_.createElement)(WrappedComponent, { 38310 registry: registry, 38311 ...props 38312 }); 38313 } 38314 const [subRegistry, setSubRegistry] = (0,external_wp_element_namespaceObject.useState)(null); 38315 (0,external_wp_element_namespaceObject.useEffect)(() => { 38316 const newRegistry = (0,external_wp_data_namespaceObject.createRegistry)({}, registry); 38317 newRegistry.registerStore(STORE_NAME, storeConfig); 38318 setSubRegistry(newRegistry); 38319 }, [registry]); 38320 if (!subRegistry) { 38321 return null; 38322 } 38323 return (0,external_React_.createElement)(external_wp_data_namespaceObject.RegistryProvider, { 38324 value: subRegistry 38325 }, (0,external_React_.createElement)(WrappedComponent, { 38326 registry: subRegistry, 38327 ...props 38328 })); 38329 }); 38330 }, 'withRegistryProvider'); 38331 /* harmony default export */ const with_registry_provider = (withRegistryProvider); 38332 38333 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/provider/use-block-sync.js 38334 /** 38335 * WordPress dependencies 38336 */ 38337 38338 38339 38340 38341 /** 38342 * Internal dependencies 38343 */ 38344 38345 38346 const use_block_sync_noop = () => {}; 38347 38348 /** 38349 * A function to call when the block value has been updated in the block-editor 38350 * store. 38351 * 38352 * @callback onBlockUpdate 38353 * @param {Object[]} blocks The updated blocks. 38354 * @param {Object} options The updated block options, such as selectionStart 38355 * and selectionEnd. 38356 */ 38357 38358 /** 38359 * useBlockSync is a side effect which handles bidirectional sync between the 38360 * block-editor store and a controlling data source which provides blocks. This 38361 * is most commonly used by the BlockEditorProvider to synchronize the contents 38362 * of the block-editor store with the root entity, like a post. 38363 * 38364 * Another example would be the template part block, which provides blocks from 38365 * a separate entity data source than a root entity. This hook syncs edits to 38366 * the template part in the block editor back to the entity and vice-versa. 38367 * 38368 * Here are some of its basic functions: 38369 * - Initalizes the block-editor store for the given clientID to the blocks 38370 * given via props. 38371 * - Adds incoming changes (like undo) to the block-editor store. 38372 * - Adds outgoing changes (like editing content) to the controlling entity, 38373 * determining if a change should be considered persistent or not. 38374 * - Handles edge cases and race conditions which occur in those operations. 38375 * - Ignores changes which happen to other entities (like nested inner block 38376 * controllers. 38377 * - Passes selection state from the block-editor store to the controlling entity. 38378 * 38379 * @param {Object} props Props for the block sync hook 38380 * @param {string} props.clientId The client ID of the inner block controller. 38381 * If none is passed, then it is assumed to be a 38382 * root controller rather than an inner block 38383 * controller. 38384 * @param {Object[]} props.value The control value for the blocks. This value 38385 * is used to initalize the block-editor store 38386 * and for resetting the blocks to incoming 38387 * changes like undo. 38388 * @param {Object} props.selection The selection state responsible to restore the selection on undo/redo. 38389 * @param {onBlockUpdate} props.onChange Function to call when a persistent 38390 * change has been made in the block-editor blocks 38391 * for the given clientId. For example, after 38392 * this function is called, an entity is marked 38393 * dirty because it has changes to save. 38394 * @param {onBlockUpdate} props.onInput Function to call when a non-persistent 38395 * change has been made in the block-editor blocks 38396 * for the given clientId. When this is called, 38397 * controlling sources do not become dirty. 38398 */ 38399 function useBlockSync({ 38400 clientId = null, 38401 value: controlledBlocks, 38402 selection: controlledSelection, 38403 onChange = use_block_sync_noop, 38404 onInput = use_block_sync_noop 38405 }) { 38406 const registry = (0,external_wp_data_namespaceObject.useRegistry)(); 38407 const { 38408 resetBlocks, 38409 resetSelection, 38410 replaceInnerBlocks, 38411 setHasControlledInnerBlocks, 38412 __unstableMarkNextChangeAsNotPersistent 38413 } = registry.dispatch(store); 38414 const { 38415 getBlockName, 38416 getBlocks, 38417 getSelectionStart, 38418 getSelectionEnd 38419 } = registry.select(store); 38420 const isControlled = (0,external_wp_data_namespaceObject.useSelect)(select => { 38421 return !clientId || select(store).areInnerBlocksControlled(clientId); 38422 }, [clientId]); 38423 const pendingChanges = (0,external_wp_element_namespaceObject.useRef)({ 38424 incoming: null, 38425 outgoing: [] 38426 }); 38427 const subscribed = (0,external_wp_element_namespaceObject.useRef)(false); 38428 const setControlledBlocks = () => { 38429 if (!controlledBlocks) { 38430 return; 38431 } 38432 38433 // We don't need to persist this change because we only replace 38434 // controlled inner blocks when the change was caused by an entity, 38435 // and so it would already be persisted. 38436 __unstableMarkNextChangeAsNotPersistent(); 38437 if (clientId) { 38438 // It is important to batch here because otherwise, 38439 // as soon as `setHasControlledInnerBlocks` is called 38440 // the effect to restore might be triggered 38441 // before the actual blocks get set properly in state. 38442 registry.batch(() => { 38443 setHasControlledInnerBlocks(clientId, true); 38444 const storeBlocks = controlledBlocks.map(block => (0,external_wp_blocks_namespaceObject.cloneBlock)(block)); 38445 if (subscribed.current) { 38446 pendingChanges.current.incoming = storeBlocks; 38447 } 38448 __unstableMarkNextChangeAsNotPersistent(); 38449 replaceInnerBlocks(clientId, storeBlocks); 38450 }); 38451 } else { 38452 if (subscribed.current) { 38453 pendingChanges.current.incoming = controlledBlocks; 38454 } 38455 resetBlocks(controlledBlocks); 38456 } 38457 }; 38458 38459 // Clean up the changes made by setControlledBlocks() when the component 38460 // containing useBlockSync() unmounts. 38461 const unsetControlledBlocks = () => { 38462 __unstableMarkNextChangeAsNotPersistent(); 38463 if (clientId) { 38464 setHasControlledInnerBlocks(clientId, false); 38465 __unstableMarkNextChangeAsNotPersistent(); 38466 replaceInnerBlocks(clientId, []); 38467 } else { 38468 resetBlocks([]); 38469 } 38470 }; 38471 38472 // Add a subscription to the block-editor registry to detect when changes 38473 // have been made. This lets us inform the data source of changes. This 38474 // is an effect so that the subscriber can run synchronously without 38475 // waiting for React renders for changes. 38476 const onInputRef = (0,external_wp_element_namespaceObject.useRef)(onInput); 38477 const onChangeRef = (0,external_wp_element_namespaceObject.useRef)(onChange); 38478 (0,external_wp_element_namespaceObject.useEffect)(() => { 38479 onInputRef.current = onInput; 38480 onChangeRef.current = onChange; 38481 }, [onInput, onChange]); 38482 38483 // Determine if blocks need to be reset when they change. 38484 (0,external_wp_element_namespaceObject.useEffect)(() => { 38485 if (pendingChanges.current.outgoing.includes(controlledBlocks)) { 38486 // Skip block reset if the value matches expected outbound sync 38487 // triggered by this component by a preceding change detection. 38488 // Only skip if the value matches expectation, since a reset should 38489 // still occur if the value is modified (not equal by reference), 38490 // to allow that the consumer may apply modifications to reflect 38491 // back on the editor. 38492 if (pendingChanges.current.outgoing[pendingChanges.current.outgoing.length - 1] === controlledBlocks) { 38493 pendingChanges.current.outgoing = []; 38494 } 38495 } else if (getBlocks(clientId) !== controlledBlocks) { 38496 // Reset changing value in all other cases than the sync described 38497 // above. Since this can be reached in an update following an out- 38498 // bound sync, unset the outbound value to avoid considering it in 38499 // subsequent renders. 38500 pendingChanges.current.outgoing = []; 38501 setControlledBlocks(); 38502 if (controlledSelection) { 38503 resetSelection(controlledSelection.selectionStart, controlledSelection.selectionEnd, controlledSelection.initialPosition); 38504 } 38505 } 38506 }, [controlledBlocks, clientId]); 38507 (0,external_wp_element_namespaceObject.useEffect)(() => { 38508 // When the block becomes uncontrolled, it means its inner state has been reset 38509 // we need to take the blocks again from the external value property. 38510 if (!isControlled) { 38511 pendingChanges.current.outgoing = []; 38512 setControlledBlocks(); 38513 } 38514 }, [isControlled]); 38515 (0,external_wp_element_namespaceObject.useEffect)(() => { 38516 const { 38517 getSelectedBlocksInitialCaretPosition, 38518 isLastBlockChangePersistent, 38519 __unstableIsLastBlockChangeIgnored, 38520 areInnerBlocksControlled 38521 } = registry.select(store); 38522 let blocks = getBlocks(clientId); 38523 let isPersistent = isLastBlockChangePersistent(); 38524 let previousAreBlocksDifferent = false; 38525 subscribed.current = true; 38526 const unsubscribe = registry.subscribe(() => { 38527 // Sometimes, when changing block lists, lingering subscriptions 38528 // might trigger before they are cleaned up. If the block for which 38529 // the subscription runs is no longer in the store, this would clear 38530 // its parent entity's block list. To avoid this, we bail out if 38531 // the subscription is triggering for a block (`clientId !== null`) 38532 // and its block name can't be found because it's not on the list. 38533 // (`getBlockName( clientId ) === null`). 38534 if (clientId !== null && getBlockName(clientId) === null) return; 38535 38536 // When RESET_BLOCKS on parent blocks get called, the controlled blocks 38537 // can reset to uncontrolled, in these situations, it means we need to populate 38538 // the blocks again from the external blocks (the value property here) 38539 // and we should stop triggering onChange 38540 const isStillControlled = !clientId || areInnerBlocksControlled(clientId); 38541 if (!isStillControlled) { 38542 return; 38543 } 38544 const newIsPersistent = isLastBlockChangePersistent(); 38545 const newBlocks = getBlocks(clientId); 38546 const areBlocksDifferent = newBlocks !== blocks; 38547 blocks = newBlocks; 38548 if (areBlocksDifferent && (pendingChanges.current.incoming || __unstableIsLastBlockChangeIgnored())) { 38549 pendingChanges.current.incoming = null; 38550 isPersistent = newIsPersistent; 38551 return; 38552 } 38553 38554 // Since we often dispatch an action to mark the previous action as 38555 // persistent, we need to make sure that the blocks changed on the 38556 // previous action before committing the change. 38557 const didPersistenceChange = previousAreBlocksDifferent && !areBlocksDifferent && newIsPersistent && !isPersistent; 38558 if (areBlocksDifferent || didPersistenceChange) { 38559 isPersistent = newIsPersistent; 38560 // We know that onChange/onInput will update controlledBlocks. 38561 // We need to be aware that it was caused by an outgoing change 38562 // so that we do not treat it as an incoming change later on, 38563 // which would cause a block reset. 38564 pendingChanges.current.outgoing.push(blocks); 38565 38566 // Inform the controlling entity that changes have been made to 38567 // the block-editor store they should be aware about. 38568 const updateParent = isPersistent ? onChangeRef.current : onInputRef.current; 38569 const undoIgnore = undoIgnoreBlocks.has(blocks); 38570 if (undoIgnore) { 38571 undoIgnoreBlocks.delete(blocks); 38572 } 38573 updateParent(blocks, { 38574 selection: { 38575 selectionStart: getSelectionStart(), 38576 selectionEnd: getSelectionEnd(), 38577 initialPosition: getSelectedBlocksInitialCaretPosition() 38578 }, 38579 undoIgnore 38580 }); 38581 } 38582 previousAreBlocksDifferent = areBlocksDifferent; 38583 }, store); 38584 return () => { 38585 subscribed.current = false; 38586 unsubscribe(); 38587 }; 38588 }, [registry, clientId]); 38589 (0,external_wp_element_namespaceObject.useEffect)(() => { 38590 return () => { 38591 unsetControlledBlocks(); 38592 }; 38593 }, []); 38594 } 38595 38596 ;// CONCATENATED MODULE: external ["wp","keyboardShortcuts"] 38597 const external_wp_keyboardShortcuts_namespaceObject = window["wp"]["keyboardShortcuts"]; 38598 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/keyboard-shortcuts/index.js 38599 /** 38600 * WordPress dependencies 38601 */ 38602 38603 38604 38605 38606 function KeyboardShortcuts() { 38607 return null; 38608 } 38609 function KeyboardShortcutsRegister() { 38610 // Registering the shortcuts. 38611 const { 38612 registerShortcut 38613 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_keyboardShortcuts_namespaceObject.store); 38614 (0,external_wp_element_namespaceObject.useEffect)(() => { 38615 registerShortcut({ 38616 name: 'core/block-editor/duplicate', 38617 category: 'block', 38618 description: (0,external_wp_i18n_namespaceObject.__)('Duplicate the selected block(s).'), 38619 keyCombination: { 38620 modifier: 'primaryShift', 38621 character: 'd' 38622 } 38623 }); 38624 registerShortcut({ 38625 name: 'core/block-editor/remove', 38626 category: 'block', 38627 description: (0,external_wp_i18n_namespaceObject.__)('Remove the selected block(s).'), 38628 keyCombination: { 38629 modifier: 'access', 38630 character: 'z' 38631 } 38632 }); 38633 registerShortcut({ 38634 name: 'core/block-editor/insert-before', 38635 category: 'block', 38636 description: (0,external_wp_i18n_namespaceObject.__)('Insert a new block before the selected block(s).'), 38637 keyCombination: { 38638 modifier: 'primaryAlt', 38639 character: 't' 38640 } 38641 }); 38642 registerShortcut({ 38643 name: 'core/block-editor/insert-after', 38644 category: 'block', 38645 description: (0,external_wp_i18n_namespaceObject.__)('Insert a new block after the selected block(s).'), 38646 keyCombination: { 38647 modifier: 'primaryAlt', 38648 character: 'y' 38649 } 38650 }); 38651 registerShortcut({ 38652 name: 'core/block-editor/delete-multi-selection', 38653 category: 'block', 38654 description: (0,external_wp_i18n_namespaceObject.__)('Delete selection.'), 38655 keyCombination: { 38656 character: 'del' 38657 }, 38658 aliases: [{ 38659 character: 'backspace' 38660 }] 38661 }); 38662 registerShortcut({ 38663 name: 'core/block-editor/select-all', 38664 category: 'selection', 38665 description: (0,external_wp_i18n_namespaceObject.__)('Select all text when typing. Press again to select all blocks.'), 38666 keyCombination: { 38667 modifier: 'primary', 38668 character: 'a' 38669 } 38670 }); 38671 registerShortcut({ 38672 name: 'core/block-editor/unselect', 38673 category: 'selection', 38674 description: (0,external_wp_i18n_namespaceObject.__)('Clear selection.'), 38675 keyCombination: { 38676 character: 'escape' 38677 } 38678 }); 38679 registerShortcut({ 38680 name: 'core/block-editor/multi-text-selection', 38681 category: 'selection', 38682 description: (0,external_wp_i18n_namespaceObject.__)('Select text across multiple blocks.'), 38683 keyCombination: { 38684 modifier: 'shift', 38685 character: 'arrow' 38686 } 38687 }); 38688 registerShortcut({ 38689 name: 'core/block-editor/focus-toolbar', 38690 category: 'global', 38691 description: (0,external_wp_i18n_namespaceObject.__)('Navigate to the nearest toolbar.'), 38692 keyCombination: { 38693 modifier: 'alt', 38694 character: 'F10' 38695 } 38696 }); 38697 registerShortcut({ 38698 name: 'core/block-editor/move-up', 38699 category: 'block', 38700 description: (0,external_wp_i18n_namespaceObject.__)('Move the selected block(s) up.'), 38701 keyCombination: { 38702 modifier: 'secondary', 38703 character: 't' 38704 } 38705 }); 38706 registerShortcut({ 38707 name: 'core/block-editor/move-down', 38708 category: 'block', 38709 description: (0,external_wp_i18n_namespaceObject.__)('Move the selected block(s) down.'), 38710 keyCombination: { 38711 modifier: 'secondary', 38712 character: 'y' 38713 } 38714 }); 38715 }, [registerShortcut]); 38716 return null; 38717 } 38718 KeyboardShortcuts.Register = KeyboardShortcutsRegister; 38719 /* harmony default export */ const keyboard_shortcuts = (KeyboardShortcuts); 38720 38721 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/provider/index.js 38722 38723 /** 38724 * WordPress dependencies 38725 */ 38726 38727 38728 38729 38730 /** 38731 * Internal dependencies 38732 */ 38733 38734 38735 38736 38737 38738 38739 38740 /** @typedef {import('@wordpress/data').WPDataRegistry} WPDataRegistry */ 38741 38742 const ExperimentalBlockEditorProvider = with_registry_provider(props => { 38743 const { 38744 children, 38745 settings, 38746 stripExperimentalSettings = false 38747 } = props; 38748 const { 38749 __experimentalUpdateSettings 38750 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store)); 38751 (0,external_wp_element_namespaceObject.useEffect)(() => { 38752 __experimentalUpdateSettings({ 38753 ...settings, 38754 __internalIsInitialized: true 38755 }, { 38756 stripExperimentalSettings, 38757 reset: true 38758 }); 38759 }, [settings, stripExperimentalSettings, __experimentalUpdateSettings]); 38760 38761 // Syncs the entity provider with changes in the block-editor store. 38762 useBlockSync(props); 38763 return (0,external_React_.createElement)(external_wp_components_namespaceObject.SlotFillProvider, { 38764 passthrough: true 38765 }, !settings?.__unstableIsPreviewMode && (0,external_React_.createElement)(keyboard_shortcuts.Register, null), (0,external_React_.createElement)(BlockRefsProvider, null, children)); 38766 }); 38767 const BlockEditorProvider = props => { 38768 return (0,external_React_.createElement)(ExperimentalBlockEditorProvider, { 38769 ...props, 38770 stripExperimentalSettings: true 38771 }, props.children); 38772 }; 38773 /* harmony default export */ const provider = (BlockEditorProvider); 38774 38775 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-selection-clearer/index.js 38776 38777 /** 38778 * WordPress dependencies 38779 */ 38780 38781 38782 38783 /** 38784 * Internal dependencies 38785 */ 38786 38787 38788 /** 38789 * Pass the returned ref callback to an element that should clear block 38790 * selection. Selection will only be cleared if the element is clicked directly, 38791 * not if a child element is clicked. 38792 * 38793 * @return {import('react').RefCallback} Ref callback. 38794 */ 38795 function useBlockSelectionClearer() { 38796 const { 38797 getSettings, 38798 hasSelectedBlock, 38799 hasMultiSelection 38800 } = (0,external_wp_data_namespaceObject.useSelect)(store); 38801 const { 38802 clearSelectedBlock 38803 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 38804 const { 38805 clearBlockSelection: isEnabled 38806 } = getSettings(); 38807 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 38808 if (!isEnabled) { 38809 return; 38810 } 38811 function onMouseDown(event) { 38812 if (!hasSelectedBlock() && !hasMultiSelection()) { 38813 return; 38814 } 38815 38816 // Only handle clicks on the element, not the children. 38817 if (event.target !== node) { 38818 return; 38819 } 38820 clearSelectedBlock(); 38821 } 38822 node.addEventListener('mousedown', onMouseDown); 38823 return () => { 38824 node.removeEventListener('mousedown', onMouseDown); 38825 }; 38826 }, [hasSelectedBlock, hasMultiSelection, clearSelectedBlock, isEnabled]); 38827 } 38828 function BlockSelectionClearer(props) { 38829 return (0,external_React_.createElement)("div", { 38830 ref: useBlockSelectionClearer(), 38831 ...props 38832 }); 38833 } 38834 38835 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/use-multi-selection.js 38836 /** 38837 * WordPress dependencies 38838 */ 38839 38840 38841 38842 /** 38843 * Internal dependencies 38844 */ 38845 38846 function selector(select) { 38847 const { 38848 isMultiSelecting, 38849 getMultiSelectedBlockClientIds, 38850 hasMultiSelection, 38851 getSelectedBlockClientId, 38852 getSelectedBlocksInitialCaretPosition, 38853 __unstableIsFullySelected 38854 } = select(store); 38855 return { 38856 isMultiSelecting: isMultiSelecting(), 38857 multiSelectedBlockClientIds: getMultiSelectedBlockClientIds(), 38858 hasMultiSelection: hasMultiSelection(), 38859 selectedBlockClientId: getSelectedBlockClientId(), 38860 initialPosition: getSelectedBlocksInitialCaretPosition(), 38861 isFullSelection: __unstableIsFullySelected() 38862 }; 38863 } 38864 function useMultiSelection() { 38865 const { 38866 initialPosition, 38867 isMultiSelecting, 38868 multiSelectedBlockClientIds, 38869 hasMultiSelection, 38870 selectedBlockClientId, 38871 isFullSelection 38872 } = (0,external_wp_data_namespaceObject.useSelect)(selector, []); 38873 38874 /** 38875 * When the component updates, and there is multi selection, we need to 38876 * select the entire block contents. 38877 */ 38878 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 38879 const { 38880 ownerDocument 38881 } = node; 38882 const { 38883 defaultView 38884 } = ownerDocument; 38885 38886 // Allow initialPosition to bypass focus behavior. This is useful 38887 // for the list view or other areas where we don't want to transfer 38888 // focus to the editor canvas. 38889 if (initialPosition === undefined || initialPosition === null) { 38890 return; 38891 } 38892 if (!hasMultiSelection || isMultiSelecting) { 38893 return; 38894 } 38895 const { 38896 length 38897 } = multiSelectedBlockClientIds; 38898 if (length < 2) { 38899 return; 38900 } 38901 if (!isFullSelection) { 38902 return; 38903 } 38904 38905 // Allow cross contentEditable selection by temporarily making 38906 // all content editable. We can't rely on using the store and 38907 // React because re-rending happens too slowly. We need to be 38908 // able to select across instances immediately. 38909 node.contentEditable = true; 38910 38911 // For some browsers, like Safari, it is important that focus 38912 // happens BEFORE selection removal. 38913 node.focus(); 38914 defaultView.getSelection().removeAllRanges(); 38915 }, [hasMultiSelection, isMultiSelecting, multiSelectedBlockClientIds, selectedBlockClientId, initialPosition, isFullSelection]); 38916 } 38917 38918 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/use-tab-nav.js 38919 38920 /** 38921 * WordPress dependencies 38922 */ 38923 38924 38925 38926 38927 38928 38929 /** 38930 * Internal dependencies 38931 */ 38932 38933 38934 38935 function useTabNav() { 38936 const container = (0,external_wp_element_namespaceObject.useRef)(); 38937 const focusCaptureBeforeRef = (0,external_wp_element_namespaceObject.useRef)(); 38938 const focusCaptureAfterRef = (0,external_wp_element_namespaceObject.useRef)(); 38939 const { 38940 hasMultiSelection, 38941 getSelectedBlockClientId, 38942 getBlockCount 38943 } = (0,external_wp_data_namespaceObject.useSelect)(store); 38944 const { 38945 setNavigationMode, 38946 setLastFocus 38947 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store)); 38948 const isNavigationMode = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).isNavigationMode(), []); 38949 const { 38950 getLastFocus 38951 } = unlock((0,external_wp_data_namespaceObject.useSelect)(store)); 38952 38953 // Don't allow tabbing to this element in Navigation mode. 38954 const focusCaptureTabIndex = !isNavigationMode ? '0' : undefined; 38955 38956 // Reference that holds the a flag for enabling or disabling 38957 // capturing on the focus capture elements. 38958 const noCapture = (0,external_wp_element_namespaceObject.useRef)(); 38959 function onFocusCapture(event) { 38960 // Do not capture incoming focus if set by us in WritingFlow. 38961 if (noCapture.current) { 38962 noCapture.current = null; 38963 } else if (hasMultiSelection()) { 38964 container.current.focus(); 38965 } else if (getSelectedBlockClientId()) { 38966 getLastFocus()?.current.focus(); 38967 } else { 38968 setNavigationMode(true); 38969 const canvasElement = container.current.ownerDocument === event.target.ownerDocument ? container.current : container.current.ownerDocument.defaultView.frameElement; 38970 const isBefore = 38971 // eslint-disable-next-line no-bitwise 38972 event.target.compareDocumentPosition(canvasElement) & event.target.DOCUMENT_POSITION_FOLLOWING; 38973 const tabbables = external_wp_dom_namespaceObject.focus.tabbable.find(container.current); 38974 if (tabbables.length) { 38975 const next = isBefore ? tabbables[0] : tabbables[tabbables.length - 1]; 38976 next.focus(); 38977 } 38978 } 38979 } 38980 const before = (0,external_React_.createElement)("div", { 38981 ref: focusCaptureBeforeRef, 38982 tabIndex: focusCaptureTabIndex, 38983 onFocus: onFocusCapture 38984 }); 38985 const after = (0,external_React_.createElement)("div", { 38986 ref: focusCaptureAfterRef, 38987 tabIndex: focusCaptureTabIndex, 38988 onFocus: onFocusCapture 38989 }); 38990 const ref = (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 38991 function onKeyDown(event) { 38992 if (event.defaultPrevented) { 38993 return; 38994 } 38995 if (event.keyCode === external_wp_keycodes_namespaceObject.ESCAPE && !hasMultiSelection()) { 38996 event.preventDefault(); 38997 setNavigationMode(true); 38998 return; 38999 } 39000 39001 // In Edit mode, Tab should focus the first tabbable element after 39002 // the content, which is normally the sidebar (with block controls) 39003 // and Shift+Tab should focus the first tabbable element before the 39004 // content, which is normally the block toolbar. 39005 // Arrow keys can be used, and Tab and arrow keys can be used in 39006 // Navigation mode (press Esc), to navigate through blocks. 39007 if (event.keyCode !== external_wp_keycodes_namespaceObject.TAB) { 39008 return; 39009 } 39010 const isShift = event.shiftKey; 39011 const direction = isShift ? 'findPrevious' : 'findNext'; 39012 if (!hasMultiSelection() && !getSelectedBlockClientId()) { 39013 // Preserve the behaviour of entering navigation mode when 39014 // tabbing into the content without a block selection. 39015 // `onFocusCapture` already did this previously, but we need to 39016 // do it again here because after clearing block selection, 39017 // focus land on the writing flow container and pressing Tab 39018 // will no longer send focus through the focus capture element. 39019 if (event.target === node) setNavigationMode(true); 39020 return; 39021 } 39022 const nextTabbable = external_wp_dom_namespaceObject.focus.tabbable[direction](event.target); 39023 39024 // We want to constrain the tabbing to the block and its child blocks. 39025 // If the preceding form element is within a different block, 39026 // such as two sibling image blocks in the placeholder state, 39027 // we want shift + tab from the first form element to move to the image 39028 // block toolbar and not the previous image block's form element. 39029 const currentBlock = event.target.closest('[data-block]'); 39030 const isElementPartOfSelectedBlock = currentBlock && nextTabbable && (isInSameBlock(currentBlock, nextTabbable) || isInsideRootBlock(currentBlock, nextTabbable)); 39031 39032 // Allow tabbing from the block wrapper to a form element, 39033 // and between form elements rendered in a block and its child blocks, 39034 // such as inside a placeholder. Form elements are generally 39035 // meant to be UI rather than part of the content. Ideally 39036 // these are not rendered in the content and perhaps in the 39037 // future they can be rendered in an iframe or shadow DOM. 39038 if ((0,external_wp_dom_namespaceObject.isFormElement)(nextTabbable) && isElementPartOfSelectedBlock) { 39039 return; 39040 } 39041 const next = isShift ? focusCaptureBeforeRef : focusCaptureAfterRef; 39042 39043 // Disable focus capturing on the focus capture element, so it 39044 // doesn't refocus this block and so it allows default behaviour 39045 // (moving focus to the next tabbable element). 39046 noCapture.current = true; 39047 39048 // Focusing the focus capture element, which is located above and 39049 // below the editor, should not scroll the page all the way up or 39050 // down. 39051 next.current.focus({ 39052 preventScroll: true 39053 }); 39054 } 39055 function onFocusOut(event) { 39056 setLastFocus({ 39057 ...getLastFocus(), 39058 current: event.target 39059 }); 39060 const { 39061 ownerDocument 39062 } = node; 39063 39064 // If focus disappears due to there being no blocks, move focus to 39065 // the writing flow wrapper. 39066 if (!event.relatedTarget && ownerDocument.activeElement === ownerDocument.body && getBlockCount() === 0) { 39067 node.focus(); 39068 } 39069 } 39070 39071 // When tabbing back to an element in block list, this event handler prevents scrolling if the 39072 // focus capture divs (before/after) are outside of the viewport. (For example shift+tab back to a paragraph 39073 // when focus is on a sidebar element. This prevents the scrollable writing area from jumping either to the 39074 // top or bottom of the document. 39075 // 39076 // Note that it isn't possible to disable scrolling in the onFocus event. We need to intercept this 39077 // earlier in the keypress handler, and call focus( { preventScroll: true } ) instead. 39078 // https://developer.mozilla.org/en-US/docs/Web/API/HTMLOrForeignElement/focus#parameters 39079 function preventScrollOnTab(event) { 39080 if (event.keyCode !== external_wp_keycodes_namespaceObject.TAB) { 39081 return; 39082 } 39083 if (event.target?.getAttribute('role') === 'region') { 39084 return; 39085 } 39086 if (container.current === event.target) { 39087 return; 39088 } 39089 const isShift = event.shiftKey; 39090 const direction = isShift ? 'findPrevious' : 'findNext'; 39091 const target = external_wp_dom_namespaceObject.focus.tabbable[direction](event.target); 39092 // Only do something when the next tabbable is a focus capture div (before/after) 39093 if (target === focusCaptureBeforeRef.current || target === focusCaptureAfterRef.current) { 39094 event.preventDefault(); 39095 target.focus({ 39096 preventScroll: true 39097 }); 39098 } 39099 } 39100 const { 39101 ownerDocument 39102 } = node; 39103 const { 39104 defaultView 39105 } = ownerDocument; 39106 defaultView.addEventListener('keydown', preventScrollOnTab); 39107 node.addEventListener('keydown', onKeyDown); 39108 node.addEventListener('focusout', onFocusOut); 39109 return () => { 39110 defaultView.removeEventListener('keydown', preventScrollOnTab); 39111 node.removeEventListener('keydown', onKeyDown); 39112 node.removeEventListener('focusout', onFocusOut); 39113 }; 39114 }, []); 39115 const mergedRefs = (0,external_wp_compose_namespaceObject.useMergeRefs)([container, ref]); 39116 return [before, mergedRefs, after]; 39117 } 39118 39119 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/use-arrow-nav.js 39120 /** 39121 * WordPress dependencies 39122 */ 39123 39124 39125 39126 39127 39128 /** 39129 * Internal dependencies 39130 */ 39131 39132 39133 39134 /** 39135 * Returns true if the element should consider edge navigation upon a keyboard 39136 * event of the given directional key code, or false otherwise. 39137 * 39138 * @param {Element} element HTML element to test. 39139 * @param {number} keyCode KeyboardEvent keyCode to test. 39140 * @param {boolean} hasModifier Whether a modifier is pressed. 39141 * 39142 * @return {boolean} Whether element should consider edge navigation. 39143 */ 39144 function isNavigationCandidate(element, keyCode, hasModifier) { 39145 const isVertical = keyCode === external_wp_keycodes_namespaceObject.UP || keyCode === external_wp_keycodes_namespaceObject.DOWN; 39146 const { 39147 tagName 39148 } = element; 39149 const elementType = element.getAttribute('type'); 39150 39151 // Native inputs should not navigate vertically, unless they are simple types that don't need up/down arrow keys. 39152 if (isVertical && !hasModifier) { 39153 if (tagName === 'INPUT') { 39154 const verticalInputTypes = ['date', 'datetime-local', 'month', 'number', 'range', 'time', 'week']; 39155 return !verticalInputTypes.includes(elementType); 39156 } 39157 return true; 39158 } 39159 39160 // Native inputs should not navigate horizontally, unless they are simple types that don't need left/right arrow keys. 39161 if (tagName === 'INPUT') { 39162 const simpleInputTypes = ['button', 'checkbox', 'number', 'color', 'file', 'image', 'radio', 'reset', 'submit']; 39163 return simpleInputTypes.includes(elementType); 39164 } 39165 39166 // Native textareas should not navigate horizontally. 39167 return tagName !== 'TEXTAREA'; 39168 } 39169 39170 /** 39171 * Returns the optimal tab target from the given focused element in the desired 39172 * direction. A preference is made toward text fields, falling back to the block 39173 * focus stop if no other candidates exist for the block. 39174 * 39175 * @param {Element} target Currently focused text field. 39176 * @param {boolean} isReverse True if considering as the first field. 39177 * @param {Element} containerElement Element containing all blocks. 39178 * @param {boolean} onlyVertical Whether to only consider tabbable elements 39179 * that are visually above or under the 39180 * target. 39181 * 39182 * @return {?Element} Optimal tab target, if one exists. 39183 */ 39184 function getClosestTabbable(target, isReverse, containerElement, onlyVertical) { 39185 // Since the current focus target is not guaranteed to be a text field, find 39186 // all focusables. Tabbability is considered later. 39187 let focusableNodes = external_wp_dom_namespaceObject.focus.focusable.find(containerElement); 39188 if (isReverse) { 39189 focusableNodes.reverse(); 39190 } 39191 39192 // Consider as candidates those focusables after the current target. It's 39193 // assumed this can only be reached if the target is focusable (on its 39194 // keydown event), so no need to verify it exists in the set. 39195 focusableNodes = focusableNodes.slice(focusableNodes.indexOf(target) + 1); 39196 let targetRect; 39197 if (onlyVertical) { 39198 targetRect = target.getBoundingClientRect(); 39199 } 39200 function isTabCandidate(node) { 39201 if (node.closest('[inert]')) { 39202 return; 39203 } 39204 39205 // Skip if there's only one child that is content editable (and thus a 39206 // better candidate). 39207 if (node.children.length === 1 && isInSameBlock(node, node.firstElementChild) && node.firstElementChild.getAttribute('contenteditable') === 'true') { 39208 return; 39209 } 39210 39211 // Not a candidate if the node is not tabbable. 39212 if (!external_wp_dom_namespaceObject.focus.tabbable.isTabbableIndex(node)) { 39213 return false; 39214 } 39215 39216 // Skip focusable elements such as links within content editable nodes. 39217 if (node.isContentEditable && node.contentEditable !== 'true') { 39218 return false; 39219 } 39220 if (onlyVertical) { 39221 const nodeRect = node.getBoundingClientRect(); 39222 if (nodeRect.left >= targetRect.right || nodeRect.right <= targetRect.left) { 39223 return false; 39224 } 39225 } 39226 return true; 39227 } 39228 return focusableNodes.find(isTabCandidate); 39229 } 39230 function useArrowNav() { 39231 const { 39232 getMultiSelectedBlocksStartClientId, 39233 getMultiSelectedBlocksEndClientId, 39234 getSettings, 39235 hasMultiSelection, 39236 __unstableIsFullySelected 39237 } = (0,external_wp_data_namespaceObject.useSelect)(store); 39238 const { 39239 selectBlock 39240 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 39241 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 39242 // Here a DOMRect is stored while moving the caret vertically so 39243 // vertical position of the start position can be restored. This is to 39244 // recreate browser behaviour across blocks. 39245 let verticalRect; 39246 function onMouseDown() { 39247 verticalRect = null; 39248 } 39249 function isClosestTabbableABlock(target, isReverse) { 39250 const closestTabbable = getClosestTabbable(target, isReverse, node); 39251 return closestTabbable && getBlockClientId(closestTabbable); 39252 } 39253 function onKeyDown(event) { 39254 // Abort if navigation has already been handled (e.g. RichText 39255 // inline boundaries). 39256 if (event.defaultPrevented) { 39257 return; 39258 } 39259 const { 39260 keyCode, 39261 target, 39262 shiftKey, 39263 ctrlKey, 39264 altKey, 39265 metaKey 39266 } = event; 39267 const isUp = keyCode === external_wp_keycodes_namespaceObject.UP; 39268 const isDown = keyCode === external_wp_keycodes_namespaceObject.DOWN; 39269 const isLeft = keyCode === external_wp_keycodes_namespaceObject.LEFT; 39270 const isRight = keyCode === external_wp_keycodes_namespaceObject.RIGHT; 39271 const isReverse = isUp || isLeft; 39272 const isHorizontal = isLeft || isRight; 39273 const isVertical = isUp || isDown; 39274 const isNav = isHorizontal || isVertical; 39275 const hasModifier = shiftKey || ctrlKey || altKey || metaKey; 39276 const isNavEdge = isVertical ? external_wp_dom_namespaceObject.isVerticalEdge : external_wp_dom_namespaceObject.isHorizontalEdge; 39277 const { 39278 ownerDocument 39279 } = node; 39280 const { 39281 defaultView 39282 } = ownerDocument; 39283 if (!isNav) { 39284 return; 39285 } 39286 39287 // If there is a multi-selection, the arrow keys should collapse the 39288 // selection to the start or end of the selection. 39289 if (hasMultiSelection()) { 39290 if (shiftKey) { 39291 return; 39292 } 39293 39294 // Only handle if we have a full selection (not a native partial 39295 // selection). 39296 if (!__unstableIsFullySelected()) { 39297 return; 39298 } 39299 event.preventDefault(); 39300 if (isReverse) { 39301 selectBlock(getMultiSelectedBlocksStartClientId()); 39302 } else { 39303 selectBlock(getMultiSelectedBlocksEndClientId(), -1); 39304 } 39305 return; 39306 } 39307 39308 // Abort if our current target is not a candidate for navigation 39309 // (e.g. preserve native input behaviors). 39310 if (!isNavigationCandidate(target, keyCode, hasModifier)) { 39311 return; 39312 } 39313 39314 // When presing any key other than up or down, the initial vertical 39315 // position must ALWAYS be reset. The vertical position is saved so 39316 // it can be restored as well as possible on sebsequent vertical 39317 // arrow key presses. It may not always be possible to restore the 39318 // exact same position (such as at an empty line), so it wouldn't be 39319 // good to compute the position right before any vertical arrow key 39320 // press. 39321 if (!isVertical) { 39322 verticalRect = null; 39323 } else if (!verticalRect) { 39324 verticalRect = (0,external_wp_dom_namespaceObject.computeCaretRect)(defaultView); 39325 } 39326 39327 // In the case of RTL scripts, right means previous and left means 39328 // next, which is the exact reverse of LTR. 39329 const isReverseDir = (0,external_wp_dom_namespaceObject.isRTL)(target) ? !isReverse : isReverse; 39330 const { 39331 keepCaretInsideBlock 39332 } = getSettings(); 39333 if (shiftKey) { 39334 if (isClosestTabbableABlock(target, isReverse) && isNavEdge(target, isReverse)) { 39335 node.contentEditable = true; 39336 // Firefox doesn't automatically move focus. 39337 node.focus(); 39338 } 39339 } else if (isVertical && (0,external_wp_dom_namespaceObject.isVerticalEdge)(target, isReverse) && ( 39340 // When Alt is pressed, only intercept if the caret is also at 39341 // the horizontal edge. 39342 altKey ? (0,external_wp_dom_namespaceObject.isHorizontalEdge)(target, isReverseDir) : true) && !keepCaretInsideBlock) { 39343 const closestTabbable = getClosestTabbable(target, isReverse, node, true); 39344 if (closestTabbable) { 39345 (0,external_wp_dom_namespaceObject.placeCaretAtVerticalEdge)(closestTabbable, 39346 // When Alt is pressed, place the caret at the furthest 39347 // horizontal edge and the furthest vertical edge. 39348 altKey ? !isReverse : isReverse, altKey ? undefined : verticalRect); 39349 event.preventDefault(); 39350 } 39351 } else if (isHorizontal && defaultView.getSelection().isCollapsed && (0,external_wp_dom_namespaceObject.isHorizontalEdge)(target, isReverseDir) && !keepCaretInsideBlock) { 39352 const closestTabbable = getClosestTabbable(target, isReverseDir, node); 39353 (0,external_wp_dom_namespaceObject.placeCaretAtHorizontalEdge)(closestTabbable, isReverse); 39354 event.preventDefault(); 39355 } 39356 } 39357 node.addEventListener('mousedown', onMouseDown); 39358 node.addEventListener('keydown', onKeyDown); 39359 return () => { 39360 node.removeEventListener('mousedown', onMouseDown); 39361 node.removeEventListener('keydown', onKeyDown); 39362 }; 39363 }, []); 39364 } 39365 39366 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/use-select-all.js 39367 /** 39368 * WordPress dependencies 39369 */ 39370 39371 39372 39373 39374 39375 /** 39376 * Internal dependencies 39377 */ 39378 39379 function useSelectAll() { 39380 const { 39381 getBlockOrder, 39382 getSelectedBlockClientIds, 39383 getBlockRootClientId 39384 } = (0,external_wp_data_namespaceObject.useSelect)(store); 39385 const { 39386 multiSelect, 39387 selectBlock 39388 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 39389 const isMatch = (0,external_wp_keyboardShortcuts_namespaceObject.__unstableUseShortcutEventMatch)(); 39390 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 39391 function onKeyDown(event) { 39392 if (!isMatch('core/block-editor/select-all', event)) { 39393 return; 39394 } 39395 const selectedClientIds = getSelectedBlockClientIds(); 39396 if (selectedClientIds.length < 2 && !(0,external_wp_dom_namespaceObject.isEntirelySelected)(event.target)) { 39397 return; 39398 } 39399 event.preventDefault(); 39400 const [firstSelectedClientId] = selectedClientIds; 39401 const rootClientId = getBlockRootClientId(firstSelectedClientId); 39402 const blockClientIds = getBlockOrder(rootClientId); 39403 39404 // If we have selected all sibling nested blocks, try selecting up a 39405 // level. See: https://github.com/WordPress/gutenberg/pull/31859/ 39406 if (selectedClientIds.length === blockClientIds.length) { 39407 if (rootClientId) { 39408 node.ownerDocument.defaultView.getSelection().removeAllRanges(); 39409 selectBlock(rootClientId); 39410 } 39411 return; 39412 } 39413 multiSelect(blockClientIds[0], blockClientIds[blockClientIds.length - 1]); 39414 } 39415 node.addEventListener('keydown', onKeyDown); 39416 return () => { 39417 node.removeEventListener('keydown', onKeyDown); 39418 }; 39419 }, []); 39420 } 39421 39422 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/use-drag-selection.js 39423 /** 39424 * WordPress dependencies 39425 */ 39426 39427 39428 39429 /** 39430 * Internal dependencies 39431 */ 39432 39433 39434 /** 39435 * Sets the `contenteditable` wrapper element to `value`. 39436 * 39437 * @param {HTMLElement} node Block element. 39438 * @param {boolean} value `contentEditable` value (true or false) 39439 */ 39440 function setContentEditableWrapper(node, value) { 39441 node.contentEditable = value; 39442 // Firefox doesn't automatically move focus. 39443 if (value) node.focus(); 39444 } 39445 39446 /** 39447 * Sets a multi-selection based on the native selection across blocks. 39448 */ 39449 function useDragSelection() { 39450 const { 39451 startMultiSelect, 39452 stopMultiSelect 39453 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 39454 const { 39455 isSelectionEnabled, 39456 hasSelectedBlock, 39457 isDraggingBlocks, 39458 isMultiSelecting 39459 } = (0,external_wp_data_namespaceObject.useSelect)(store); 39460 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 39461 const { 39462 ownerDocument 39463 } = node; 39464 const { 39465 defaultView 39466 } = ownerDocument; 39467 let anchorElement; 39468 let rafId; 39469 function onMouseUp() { 39470 stopMultiSelect(); 39471 // Equivalent to attaching the listener once. 39472 defaultView.removeEventListener('mouseup', onMouseUp); 39473 // The browser selection won't have updated yet at this point, 39474 // so wait until the next animation frame to get the browser 39475 // selection. 39476 rafId = defaultView.requestAnimationFrame(() => { 39477 if (!hasSelectedBlock()) { 39478 return; 39479 } 39480 39481 // If the selection is complete (on mouse up), and no 39482 // multiple blocks have been selected, set focus back to the 39483 // anchor element. if the anchor element contains the 39484 // selection. Additionally, the contentEditable wrapper can 39485 // now be disabled again. 39486 setContentEditableWrapper(node, false); 39487 const selection = defaultView.getSelection(); 39488 if (selection.rangeCount) { 39489 const range = selection.getRangeAt(0); 39490 const { 39491 commonAncestorContainer 39492 } = range; 39493 const clonedRange = range.cloneRange(); 39494 if (anchorElement.contains(commonAncestorContainer)) { 39495 anchorElement.focus(); 39496 selection.removeAllRanges(); 39497 selection.addRange(clonedRange); 39498 } 39499 } 39500 }); 39501 } 39502 function onMouseLeave({ 39503 buttons, 39504 target, 39505 relatedTarget 39506 }) { 39507 // If we're moving into a child element, ignore. We're tracking 39508 // the mouse leaving the element to a parent, no a child. 39509 if (target.contains(relatedTarget)) { 39510 return; 39511 } 39512 39513 // Avoid triggering a multi-selection if the user is already 39514 // dragging blocks. 39515 if (isDraggingBlocks()) { 39516 return; 39517 } 39518 39519 // The primary button must be pressed to initiate selection. 39520 // See https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons 39521 if (buttons !== 1) { 39522 return; 39523 } 39524 39525 // Abort if we are already multi-selecting. 39526 if (isMultiSelecting()) { 39527 return; 39528 } 39529 39530 // Abort if selection is leaving writing flow. 39531 if (node === target) { 39532 return; 39533 } 39534 39535 // Check the attribute, not the contentEditable attribute. All 39536 // child elements of the content editable wrapper are editable 39537 // and return true for this property. We only want to start 39538 // multi selecting when the mouse leaves the wrapper. 39539 if (target.getAttribute('contenteditable') !== 'true') { 39540 return; 39541 } 39542 if (!isSelectionEnabled()) { 39543 return; 39544 } 39545 39546 // Do not rely on the active element because it may change after 39547 // the mouse leaves for the first time. See 39548 // https://github.com/WordPress/gutenberg/issues/48747. 39549 anchorElement = target; 39550 startMultiSelect(); 39551 39552 // `onSelectionStart` is called after `mousedown` and 39553 // `mouseleave` (from a block). The selection ends when 39554 // `mouseup` happens anywhere in the window. 39555 defaultView.addEventListener('mouseup', onMouseUp); 39556 39557 // Allow cross contentEditable selection by temporarily making 39558 // all content editable. We can't rely on using the store and 39559 // React because re-rending happens too slowly. We need to be 39560 // able to select across instances immediately. 39561 setContentEditableWrapper(node, true); 39562 } 39563 node.addEventListener('mouseout', onMouseLeave); 39564 return () => { 39565 node.removeEventListener('mouseout', onMouseLeave); 39566 defaultView.removeEventListener('mouseup', onMouseUp); 39567 defaultView.cancelAnimationFrame(rafId); 39568 }; 39569 }, [startMultiSelect, stopMultiSelect, isSelectionEnabled, hasSelectedBlock]); 39570 } 39571 39572 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/use-selection-observer.js 39573 /** 39574 * WordPress dependencies 39575 */ 39576 39577 39578 39579 39580 /** 39581 * Internal dependencies 39582 */ 39583 39584 39585 39586 /** 39587 * Extract the selection start node from the selection. When the anchor node is 39588 * not a text node, the selection offset is the index of a child node. 39589 * 39590 * @param {Selection} selection The selection. 39591 * 39592 * @return {Element} The selection start node. 39593 */ 39594 function extractSelectionStartNode(selection) { 39595 const { 39596 anchorNode, 39597 anchorOffset 39598 } = selection; 39599 if (anchorNode.nodeType === anchorNode.TEXT_NODE) { 39600 return anchorNode; 39601 } 39602 if (anchorOffset === 0) { 39603 return anchorNode; 39604 } 39605 return anchorNode.childNodes[anchorOffset - 1]; 39606 } 39607 39608 /** 39609 * Extract the selection end node from the selection. When the focus node is not 39610 * a text node, the selection offset is the index of a child node. The selection 39611 * reaches up to but excluding that child node. 39612 * 39613 * @param {Selection} selection The selection. 39614 * 39615 * @return {Element} The selection start node. 39616 */ 39617 function extractSelectionEndNode(selection) { 39618 const { 39619 focusNode, 39620 focusOffset 39621 } = selection; 39622 if (focusNode.nodeType === focusNode.TEXT_NODE) { 39623 return focusNode; 39624 } 39625 if (focusOffset === focusNode.childNodes.length) { 39626 return focusNode; 39627 } 39628 return focusNode.childNodes[focusOffset]; 39629 } 39630 function findDepth(a, b) { 39631 let depth = 0; 39632 while (a[depth] === b[depth]) { 39633 depth++; 39634 } 39635 return depth; 39636 } 39637 39638 /** 39639 * Sets the `contenteditable` wrapper element to `value`. 39640 * 39641 * @param {HTMLElement} node Block element. 39642 * @param {boolean} value `contentEditable` value (true or false) 39643 */ 39644 function use_selection_observer_setContentEditableWrapper(node, value) { 39645 // Since we are calling this on every selection change, check if the value 39646 // needs to be updated first because it trigger the browser to recalculate 39647 // style. 39648 if (node.contentEditable !== String(value)) { 39649 node.contentEditable = value; 39650 39651 // Firefox doesn't automatically move focus. 39652 if (value) { 39653 node.focus(); 39654 } 39655 } 39656 } 39657 function getRichTextElement(node) { 39658 const element = node.nodeType === node.ELEMENT_NODE ? node : node.parentElement; 39659 return element?.closest('[data-wp-block-attribute-key]'); 39660 } 39661 39662 /** 39663 * Sets a multi-selection based on the native selection across blocks. 39664 */ 39665 function useSelectionObserver() { 39666 const { 39667 multiSelect, 39668 selectBlock, 39669 selectionChange 39670 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 39671 const { 39672 getBlockParents, 39673 getBlockSelectionStart, 39674 isMultiSelecting 39675 } = (0,external_wp_data_namespaceObject.useSelect)(store); 39676 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 39677 const { 39678 ownerDocument 39679 } = node; 39680 const { 39681 defaultView 39682 } = ownerDocument; 39683 function onSelectionChange(event) { 39684 const selection = defaultView.getSelection(); 39685 if (!selection.rangeCount) { 39686 return; 39687 } 39688 const startNode = extractSelectionStartNode(selection); 39689 const endNode = extractSelectionEndNode(selection); 39690 if (!node.contains(startNode) || !node.contains(endNode)) { 39691 return; 39692 } 39693 39694 // If selection is collapsed and we haven't used `shift+click`, 39695 // end multi selection and disable the contentEditable wrapper. 39696 // We have to check about `shift+click` case because elements 39697 // that don't support text selection might be involved, and we might 39698 // update the clientIds to multi-select blocks. 39699 // For now we check if the event is a `mouse` event. 39700 const isClickShift = event.shiftKey && event.type === 'mouseup'; 39701 if (selection.isCollapsed && !isClickShift) { 39702 if (node.contentEditable === 'true' && !isMultiSelecting()) { 39703 use_selection_observer_setContentEditableWrapper(node, false); 39704 let element = startNode.nodeType === startNode.ELEMENT_NODE ? startNode : startNode.parentElement; 39705 element = element?.closest('[contenteditable]'); 39706 element?.focus(); 39707 } 39708 return; 39709 } 39710 let startClientId = getBlockClientId(startNode); 39711 let endClientId = getBlockClientId(endNode); 39712 39713 // If the selection has changed and we had pressed `shift+click`, 39714 // we need to check if in an element that doesn't support 39715 // text selection has been clicked. 39716 if (isClickShift) { 39717 const selectedClientId = getBlockSelectionStart(); 39718 const clickedClientId = getBlockClientId(event.target); 39719 // `endClientId` is not defined if we end the selection by clicking a non-selectable block. 39720 // We need to check if there was already a selection with a non-selectable focusNode. 39721 const focusNodeIsNonSelectable = clickedClientId !== endClientId; 39722 if (startClientId === endClientId && selection.isCollapsed || !endClientId || focusNodeIsNonSelectable) { 39723 endClientId = clickedClientId; 39724 } 39725 // Handle the case when we have a non-selectable block 39726 // selected and click another one. 39727 if (startClientId !== selectedClientId) { 39728 startClientId = selectedClientId; 39729 } 39730 } 39731 39732 // If the selection did not involve a block, return. 39733 if (startClientId === undefined && endClientId === undefined) { 39734 use_selection_observer_setContentEditableWrapper(node, false); 39735 return; 39736 } 39737 const isSingularSelection = startClientId === endClientId; 39738 if (isSingularSelection) { 39739 if (!isMultiSelecting()) { 39740 selectBlock(startClientId); 39741 } else { 39742 multiSelect(startClientId, startClientId); 39743 } 39744 } else { 39745 const startPath = [...getBlockParents(startClientId), startClientId]; 39746 const endPath = [...getBlockParents(endClientId), endClientId]; 39747 const depth = findDepth(startPath, endPath); 39748 if (startPath[depth] !== startClientId || endPath[depth] !== endClientId) { 39749 multiSelect(startPath[depth], endPath[depth]); 39750 return; 39751 } 39752 const richTextElementStart = getRichTextElement(startNode); 39753 const richTextElementEnd = getRichTextElement(endNode); 39754 if (richTextElementStart && richTextElementEnd) { 39755 var _richTextDataStart$st, _richTextDataEnd$star; 39756 const range = selection.getRangeAt(0); 39757 const richTextDataStart = (0,external_wp_richText_namespaceObject.create)({ 39758 element: richTextElementStart, 39759 range, 39760 __unstableIsEditableTree: true 39761 }); 39762 const richTextDataEnd = (0,external_wp_richText_namespaceObject.create)({ 39763 element: richTextElementEnd, 39764 range, 39765 __unstableIsEditableTree: true 39766 }); 39767 const startOffset = (_richTextDataStart$st = richTextDataStart.start) !== null && _richTextDataStart$st !== void 0 ? _richTextDataStart$st : richTextDataStart.end; 39768 const endOffset = (_richTextDataEnd$star = richTextDataEnd.start) !== null && _richTextDataEnd$star !== void 0 ? _richTextDataEnd$star : richTextDataEnd.end; 39769 selectionChange({ 39770 start: { 39771 clientId: startClientId, 39772 attributeKey: richTextElementStart.dataset.wpBlockAttributeKey, 39773 offset: startOffset 39774 }, 39775 end: { 39776 clientId: endClientId, 39777 attributeKey: richTextElementEnd.dataset.wpBlockAttributeKey, 39778 offset: endOffset 39779 } 39780 }); 39781 } else { 39782 multiSelect(startClientId, endClientId); 39783 } 39784 } 39785 } 39786 ownerDocument.addEventListener('selectionchange', onSelectionChange); 39787 defaultView.addEventListener('mouseup', onSelectionChange); 39788 return () => { 39789 ownerDocument.removeEventListener('selectionchange', onSelectionChange); 39790 defaultView.removeEventListener('mouseup', onSelectionChange); 39791 }; 39792 }, [multiSelect, selectBlock, selectionChange, getBlockParents]); 39793 } 39794 39795 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/use-click-selection.js 39796 /** 39797 * WordPress dependencies 39798 */ 39799 39800 39801 39802 /** 39803 * Internal dependencies 39804 */ 39805 39806 39807 function useClickSelection() { 39808 const { 39809 selectBlock 39810 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 39811 const { 39812 isSelectionEnabled, 39813 getBlockSelectionStart, 39814 hasMultiSelection 39815 } = (0,external_wp_data_namespaceObject.useSelect)(store); 39816 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 39817 function onMouseDown(event) { 39818 // The main button. 39819 // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button 39820 if (!isSelectionEnabled() || event.button !== 0) { 39821 return; 39822 } 39823 const startClientId = getBlockSelectionStart(); 39824 const clickedClientId = getBlockClientId(event.target); 39825 if (event.shiftKey) { 39826 if (startClientId !== clickedClientId) { 39827 node.contentEditable = true; 39828 // Firefox doesn't automatically move focus. 39829 node.focus(); 39830 } 39831 } else if (hasMultiSelection()) { 39832 // Allow user to escape out of a multi-selection to a 39833 // singular selection of a block via click. This is handled 39834 // here since focus handling excludes blocks when there is 39835 // multiselection, as focus can be incurred by starting a 39836 // multiselection (focus moved to first block's multi- 39837 // controls). 39838 selectBlock(clickedClientId); 39839 } 39840 } 39841 node.addEventListener('mousedown', onMouseDown); 39842 return () => { 39843 node.removeEventListener('mousedown', onMouseDown); 39844 }; 39845 }, [selectBlock, isSelectionEnabled, getBlockSelectionStart, hasMultiSelection]); 39846 } 39847 39848 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/use-input.js 39849 /** 39850 * WordPress dependencies 39851 */ 39852 39853 39854 39855 39856 39857 /** 39858 * Internal dependencies 39859 */ 39860 39861 39862 /** 39863 * Handles input for selections across blocks. 39864 */ 39865 function useInput() { 39866 const { 39867 __unstableIsFullySelected, 39868 getSelectedBlockClientIds, 39869 __unstableIsSelectionMergeable, 39870 hasMultiSelection 39871 } = (0,external_wp_data_namespaceObject.useSelect)(store); 39872 const { 39873 replaceBlocks, 39874 __unstableSplitSelection, 39875 removeBlocks, 39876 __unstableDeleteSelection, 39877 __unstableExpandSelection 39878 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 39879 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 39880 function onBeforeInput(event) { 39881 // If writing flow is editable, NEVER allow the browser to alter the 39882 // DOM. This will cause React errors (and the DOM should only be 39883 // altered in a controlled fashion). 39884 if (node.contentEditable === 'true') { 39885 event.preventDefault(); 39886 } 39887 } 39888 function onKeyDown(event) { 39889 if (event.defaultPrevented) { 39890 return; 39891 } 39892 if (!hasMultiSelection()) { 39893 return; 39894 } 39895 if (event.keyCode === external_wp_keycodes_namespaceObject.ENTER) { 39896 node.contentEditable = false; 39897 event.preventDefault(); 39898 if (__unstableIsFullySelected()) { 39899 replaceBlocks(getSelectedBlockClientIds(), (0,external_wp_blocks_namespaceObject.createBlock)((0,external_wp_blocks_namespaceObject.getDefaultBlockName)())); 39900 } else { 39901 __unstableSplitSelection(); 39902 } 39903 } else if (event.keyCode === external_wp_keycodes_namespaceObject.BACKSPACE || event.keyCode === external_wp_keycodes_namespaceObject.DELETE) { 39904 node.contentEditable = false; 39905 event.preventDefault(); 39906 if (__unstableIsFullySelected()) { 39907 removeBlocks(getSelectedBlockClientIds()); 39908 } else if (__unstableIsSelectionMergeable()) { 39909 __unstableDeleteSelection(event.keyCode === external_wp_keycodes_namespaceObject.DELETE); 39910 } else { 39911 __unstableExpandSelection(); 39912 } 39913 } else if ( 39914 // If key.length is longer than 1, it's a control key that doesn't 39915 // input anything. 39916 event.key.length === 1 && !(event.metaKey || event.ctrlKey)) { 39917 node.contentEditable = false; 39918 if (__unstableIsSelectionMergeable()) { 39919 __unstableDeleteSelection(event.keyCode === external_wp_keycodes_namespaceObject.DELETE); 39920 } else { 39921 event.preventDefault(); 39922 // Safari does not stop default behaviour with either 39923 // event.preventDefault() or node.contentEditable = false, so 39924 // remove the selection to stop browser manipulation. 39925 node.ownerDocument.defaultView.getSelection().removeAllRanges(); 39926 } 39927 } 39928 } 39929 function onCompositionStart(event) { 39930 if (!hasMultiSelection()) { 39931 return; 39932 } 39933 node.contentEditable = false; 39934 if (__unstableIsSelectionMergeable()) { 39935 __unstableDeleteSelection(); 39936 } else { 39937 event.preventDefault(); 39938 // Safari does not stop default behaviour with either 39939 // event.preventDefault() or node.contentEditable = false, so 39940 // remove the selection to stop browser manipulation. 39941 node.ownerDocument.defaultView.getSelection().removeAllRanges(); 39942 } 39943 } 39944 node.addEventListener('beforeinput', onBeforeInput); 39945 node.addEventListener('keydown', onKeyDown); 39946 node.addEventListener('compositionstart', onCompositionStart); 39947 return () => { 39948 node.removeEventListener('beforeinput', onBeforeInput); 39949 node.removeEventListener('keydown', onKeyDown); 39950 node.removeEventListener('compositionstart', onCompositionStart); 39951 }; 39952 }, []); 39953 } 39954 39955 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/use-notify-copy.js 39956 /** 39957 * WordPress dependencies 39958 */ 39959 39960 39961 39962 39963 39964 39965 /** 39966 * Internal dependencies 39967 */ 39968 39969 function useNotifyCopy() { 39970 const { 39971 getBlockName 39972 } = (0,external_wp_data_namespaceObject.useSelect)(store); 39973 const { 39974 getBlockType 39975 } = (0,external_wp_data_namespaceObject.useSelect)(external_wp_blocks_namespaceObject.store); 39976 const { 39977 createSuccessNotice 39978 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_notices_namespaceObject.store); 39979 return (0,external_wp_element_namespaceObject.useCallback)((eventType, selectedBlockClientIds) => { 39980 let notice = ''; 39981 if (selectedBlockClientIds.length === 1) { 39982 const clientId = selectedBlockClientIds[0]; 39983 const title = getBlockType(getBlockName(clientId))?.title; 39984 notice = eventType === 'copy' ? (0,external_wp_i18n_namespaceObject.sprintf)( 39985 // Translators: Name of the block being copied, e.g. "Paragraph". 39986 (0,external_wp_i18n_namespaceObject.__)('Copied "%s" to clipboard.'), title) : (0,external_wp_i18n_namespaceObject.sprintf)( 39987 // Translators: Name of the block being cut, e.g. "Paragraph". 39988 (0,external_wp_i18n_namespaceObject.__)('Moved "%s" to clipboard.'), title); 39989 } else { 39990 notice = eventType === 'copy' ? (0,external_wp_i18n_namespaceObject.sprintf)( 39991 // Translators: %d: Number of blocks being copied. 39992 (0,external_wp_i18n_namespaceObject._n)('Copied %d block to clipboard.', 'Copied %d blocks to clipboard.', selectedBlockClientIds.length), selectedBlockClientIds.length) : (0,external_wp_i18n_namespaceObject.sprintf)( 39993 // Translators: %d: Number of blocks being cut. 39994 (0,external_wp_i18n_namespaceObject._n)('Moved %d block to clipboard.', 'Moved %d blocks to clipboard.', selectedBlockClientIds.length), selectedBlockClientIds.length); 39995 } 39996 createSuccessNotice(notice, { 39997 type: 'snackbar' 39998 }); 39999 }, []); 40000 } 40001 40002 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/pasting.js 40003 /** 40004 * WordPress dependencies 40005 */ 40006 40007 40008 /** 40009 * Normalizes a given string of HTML to remove the Windows-specific "Fragment" 40010 * comments and any preceding and trailing content. 40011 * 40012 * @param {string} html the html to be normalized 40013 * @return {string} the normalized html 40014 */ 40015 function removeWindowsFragments(html) { 40016 const startStr = '<!--StartFragment-->'; 40017 const startIdx = html.indexOf(startStr); 40018 if (startIdx > -1) { 40019 html = html.substring(startIdx + startStr.length); 40020 } else { 40021 // No point looking for EndFragment 40022 return html; 40023 } 40024 const endStr = '<!--EndFragment-->'; 40025 const endIdx = html.indexOf(endStr); 40026 if (endIdx > -1) { 40027 html = html.substring(0, endIdx); 40028 } 40029 return html; 40030 } 40031 40032 /** 40033 * Removes the charset meta tag inserted by Chromium. 40034 * See: 40035 * - https://github.com/WordPress/gutenberg/issues/33585 40036 * - https://bugs.chromium.org/p/chromium/issues/detail?id=1264616#c4 40037 * 40038 * @param {string} html the html to be stripped of the meta tag. 40039 * @return {string} the cleaned html 40040 */ 40041 function removeCharsetMetaTag(html) { 40042 const metaTag = `<meta charset='utf-8'>`; 40043 if (html.startsWith(metaTag)) { 40044 return html.slice(metaTag.length); 40045 } 40046 return html; 40047 } 40048 function getPasteEventData({ 40049 clipboardData 40050 }) { 40051 let plainText = ''; 40052 let html = ''; 40053 40054 // IE11 only supports `Text` as an argument for `getData` and will 40055 // otherwise throw an invalid argument error, so we try the standard 40056 // arguments first, then fallback to `Text` if they fail. 40057 try { 40058 plainText = clipboardData.getData('text/plain'); 40059 html = clipboardData.getData('text/html'); 40060 } catch (error1) { 40061 try { 40062 html = clipboardData.getData('Text'); 40063 } catch (error2) { 40064 // Some browsers like UC Browser paste plain text by default and 40065 // don't support clipboardData at all, so allow default 40066 // behaviour. 40067 return; 40068 } 40069 } 40070 40071 // Remove Windows-specific metadata appended within copied HTML text. 40072 html = removeWindowsFragments(html); 40073 40074 // Strip meta tag. 40075 html = removeCharsetMetaTag(html); 40076 const files = (0,external_wp_dom_namespaceObject.getFilesFromDataTransfer)(clipboardData); 40077 if (files.length && !shouldDismissPastedFiles(files, html)) { 40078 return { 40079 files 40080 }; 40081 } 40082 return { 40083 html, 40084 plainText, 40085 files: [] 40086 }; 40087 } 40088 40089 /** 40090 * Given a collection of DataTransfer files and HTML and plain text strings, 40091 * determine whether the files are to be dismissed in favor of the HTML. 40092 * 40093 * Certain office-type programs, like Microsoft Word or Apple Numbers, 40094 * will, upon copy, generate a screenshot of the content being copied and 40095 * attach it to the clipboard alongside the actual rich text that the user 40096 * sought to copy. In those cases, we should let Gutenberg handle the rich text 40097 * content and not the screenshot, since this allows Gutenberg to insert 40098 * meaningful blocks, like paragraphs, lists or even tables. 40099 * 40100 * @param {File[]} files File objects obtained from a paste event 40101 * @param {string} html HTML content obtained from a paste event 40102 * @return {boolean} True if the files should be dismissed 40103 */ 40104 function shouldDismissPastedFiles(files, html /*, plainText */) { 40105 // The question is only relevant when there is actual HTML content and when 40106 // there is exactly one image file. 40107 if (html && files?.length === 1 && files[0].type.indexOf('image/') === 0) { 40108 // A single <img> tag found in the HTML source suggests that the 40109 // content being pasted revolves around an image. Sometimes there are 40110 // other elements found, like <figure>, but we assume that the user's 40111 // intention is to paste the actual image file. 40112 const IMAGE_TAG = /<\s*img\b/gi; 40113 if (html.match(IMAGE_TAG)?.length !== 1) return true; 40114 40115 // Even when there is exactly one <img> tag in the HTML payload, we 40116 // choose to weed out local images, i.e. those whose source starts with 40117 // "file://". These payloads occur in specific configurations, such as 40118 // when copying an entire document from Microsoft Word, that contains 40119 // text and exactly one image, and pasting that content using Google 40120 // Chrome. 40121 const IMG_WITH_LOCAL_SRC = /<\s*img\b[^>]*\bsrc="file:\/\//i; 40122 if (html.match(IMG_WITH_LOCAL_SRC)) return true; 40123 } 40124 return false; 40125 } 40126 40127 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/utils.js 40128 /** 40129 * WordPress dependencies 40130 */ 40131 40132 40133 40134 /** 40135 * Internal dependencies 40136 */ 40137 40138 40139 const requiresWrapperOnCopy = Symbol('requiresWrapperOnCopy'); 40140 40141 /** 40142 * Sets the clipboard data for the provided blocks, with both HTML and plain 40143 * text representations. 40144 * 40145 * @param {ClipboardEvent} event Clipboard event. 40146 * @param {WPBlock[]} blocks Blocks to set as clipboard data. 40147 * @param {Object} registry The registry to select from. 40148 */ 40149 function setClipboardBlocks(event, blocks, registry) { 40150 let _blocks = blocks; 40151 const [firstBlock] = blocks; 40152 if (firstBlock) { 40153 const firstBlockType = registry.select(external_wp_blocks_namespaceObject.store).getBlockType(firstBlock.name); 40154 if (firstBlockType[requiresWrapperOnCopy]) { 40155 const { 40156 getBlockRootClientId, 40157 getBlockName, 40158 getBlockAttributes 40159 } = registry.select(store); 40160 const wrapperBlockClientId = getBlockRootClientId(firstBlock.clientId); 40161 const wrapperBlockName = getBlockName(wrapperBlockClientId); 40162 if (wrapperBlockName) { 40163 _blocks = (0,external_wp_blocks_namespaceObject.createBlock)(wrapperBlockName, getBlockAttributes(wrapperBlockClientId), _blocks); 40164 } 40165 } 40166 } 40167 const serialized = (0,external_wp_blocks_namespaceObject.serialize)(_blocks); 40168 event.clipboardData.setData('text/plain', toPlainText(serialized)); 40169 event.clipboardData.setData('text/html', serialized); 40170 } 40171 40172 /** 40173 * Returns the blocks to be pasted from the clipboard event. 40174 * 40175 * @param {ClipboardEvent} event The clipboard event. 40176 * @param {boolean} canUserUseUnfilteredHTML Whether the user can or can't post unfiltered HTML. 40177 * @return {Array|string} A list of blocks or a string, depending on `handlerMode`. 40178 */ 40179 function getPasteBlocks(event, canUserUseUnfilteredHTML) { 40180 const { 40181 plainText, 40182 html, 40183 files 40184 } = getPasteEventData(event); 40185 let blocks = []; 40186 if (files.length) { 40187 const fromTransforms = (0,external_wp_blocks_namespaceObject.getBlockTransforms)('from'); 40188 blocks = files.reduce((accumulator, file) => { 40189 const transformation = (0,external_wp_blocks_namespaceObject.findTransform)(fromTransforms, transform => transform.type === 'files' && transform.isMatch([file])); 40190 if (transformation) { 40191 accumulator.push(transformation.transform([file])); 40192 } 40193 return accumulator; 40194 }, []).flat(); 40195 } else { 40196 blocks = (0,external_wp_blocks_namespaceObject.pasteHandler)({ 40197 HTML: html, 40198 plainText, 40199 mode: 'BLOCKS', 40200 canUserUseUnfilteredHTML 40201 }); 40202 } 40203 return blocks; 40204 } 40205 40206 /** 40207 * Given a string of HTML representing serialized blocks, returns the plain 40208 * text extracted after stripping the HTML of any tags and fixing line breaks. 40209 * 40210 * @param {string} html Serialized blocks. 40211 * @return {string} The plain-text content with any html removed. 40212 */ 40213 function toPlainText(html) { 40214 // Manually handle BR tags as line breaks prior to `stripHTML` call 40215 html = html.replace(/<br>/g, '\n'); 40216 const plainText = (0,external_wp_dom_namespaceObject.__unstableStripHTML)(html).trim(); 40217 40218 // Merge any consecutive line breaks 40219 return plainText.replace(/\n\n+/g, '\n\n'); 40220 } 40221 40222 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/use-clipboard-handler.js 40223 /** 40224 * WordPress dependencies 40225 */ 40226 40227 40228 40229 40230 /** 40231 * Internal dependencies 40232 */ 40233 40234 40235 40236 function useClipboardHandler() { 40237 const registry = (0,external_wp_data_namespaceObject.useRegistry)(); 40238 const { 40239 getBlocksByClientId, 40240 getSelectedBlockClientIds, 40241 hasMultiSelection, 40242 getSettings, 40243 __unstableIsFullySelected, 40244 __unstableIsSelectionCollapsed, 40245 __unstableIsSelectionMergeable, 40246 __unstableGetSelectedBlocksWithPartialSelection, 40247 canInsertBlockType 40248 } = (0,external_wp_data_namespaceObject.useSelect)(store); 40249 const { 40250 flashBlock, 40251 removeBlocks, 40252 replaceBlocks, 40253 __unstableDeleteSelection, 40254 __unstableExpandSelection, 40255 insertBlocks 40256 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 40257 const notifyCopy = useNotifyCopy(); 40258 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 40259 function handler(event) { 40260 if (event.defaultPrevented) { 40261 // This was likely already handled in rich-text/use-paste-handler.js. 40262 return; 40263 } 40264 const selectedBlockClientIds = getSelectedBlockClientIds(); 40265 if (selectedBlockClientIds.length === 0) { 40266 return; 40267 } 40268 40269 // Always handle multiple selected blocks. 40270 if (!hasMultiSelection()) { 40271 const { 40272 target 40273 } = event; 40274 const { 40275 ownerDocument 40276 } = target; 40277 // If copying, only consider actual text selection as selection. 40278 // Otherwise, any focus on an input field is considered. 40279 const hasSelection = event.type === 'copy' || event.type === 'cut' ? (0,external_wp_dom_namespaceObject.documentHasUncollapsedSelection)(ownerDocument) : (0,external_wp_dom_namespaceObject.documentHasSelection)(ownerDocument); 40280 40281 // Let native copy behaviour take over in input fields. 40282 if (hasSelection) { 40283 return; 40284 } 40285 } 40286 if (!node.contains(event.target.ownerDocument.activeElement)) { 40287 return; 40288 } 40289 event.preventDefault(); 40290 const isSelectionMergeable = __unstableIsSelectionMergeable(); 40291 const shouldHandleWholeBlocks = __unstableIsSelectionCollapsed() || __unstableIsFullySelected(); 40292 const expandSelectionIsNeeded = !shouldHandleWholeBlocks && !isSelectionMergeable; 40293 if (event.type === 'copy' || event.type === 'cut') { 40294 if (selectedBlockClientIds.length === 1) { 40295 flashBlock(selectedBlockClientIds[0]); 40296 } 40297 // If we have a partial selection that is not mergeable, just 40298 // expand the selection to the whole blocks. 40299 if (expandSelectionIsNeeded) { 40300 __unstableExpandSelection(); 40301 } else { 40302 notifyCopy(event.type, selectedBlockClientIds); 40303 let blocks; 40304 // Check if we have partial selection. 40305 if (shouldHandleWholeBlocks) { 40306 blocks = getBlocksByClientId(selectedBlockClientIds); 40307 } else { 40308 const [head, tail] = __unstableGetSelectedBlocksWithPartialSelection(); 40309 const inBetweenBlocks = getBlocksByClientId(selectedBlockClientIds.slice(1, selectedBlockClientIds.length - 1)); 40310 blocks = [head, ...inBetweenBlocks, tail]; 40311 } 40312 setClipboardBlocks(event, blocks, registry); 40313 } 40314 } 40315 if (event.type === 'cut') { 40316 // We need to also check if at the start we needed to 40317 // expand the selection, as in this point we might have 40318 // programmatically fully selected the blocks above. 40319 if (shouldHandleWholeBlocks && !expandSelectionIsNeeded) { 40320 removeBlocks(selectedBlockClientIds); 40321 } else { 40322 event.target.ownerDocument.activeElement.contentEditable = false; 40323 __unstableDeleteSelection(); 40324 } 40325 } else if (event.type === 'paste') { 40326 const { 40327 __experimentalCanUserUseUnfilteredHTML: canUserUseUnfilteredHTML 40328 } = getSettings(); 40329 const blocks = getPasteBlocks(event, canUserUseUnfilteredHTML); 40330 if (selectedBlockClientIds.length === 1) { 40331 const [selectedBlockClientId] = selectedBlockClientIds; 40332 if (blocks.every(block => canInsertBlockType(block.name, selectedBlockClientId))) { 40333 insertBlocks(blocks, undefined, selectedBlockClientId); 40334 return; 40335 } 40336 } 40337 replaceBlocks(selectedBlockClientIds, blocks, blocks.length - 1, -1); 40338 } 40339 } 40340 node.ownerDocument.addEventListener('copy', handler); 40341 node.ownerDocument.addEventListener('cut', handler); 40342 node.ownerDocument.addEventListener('paste', handler); 40343 return () => { 40344 node.ownerDocument.removeEventListener('copy', handler); 40345 node.ownerDocument.removeEventListener('cut', handler); 40346 node.ownerDocument.removeEventListener('paste', handler); 40347 }; 40348 }, []); 40349 } 40350 40351 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/index.js 40352 40353 /** 40354 * External dependencies 40355 */ 40356 40357 40358 /** 40359 * WordPress dependencies 40360 */ 40361 40362 40363 40364 40365 40366 /** 40367 * Internal dependencies 40368 */ 40369 40370 40371 40372 40373 40374 40375 40376 40377 40378 40379 function useWritingFlow() { 40380 const [before, ref, after] = useTabNav(); 40381 const hasMultiSelection = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).hasMultiSelection(), []); 40382 return [before, (0,external_wp_compose_namespaceObject.useMergeRefs)([ref, useClipboardHandler(), useInput(), useDragSelection(), useSelectionObserver(), useClickSelection(), useMultiSelection(), useSelectAll(), useArrowNav(), (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 40383 node.tabIndex = 0; 40384 if (!hasMultiSelection) { 40385 return; 40386 } 40387 node.classList.add('has-multi-selection'); 40388 node.setAttribute('aria-label', (0,external_wp_i18n_namespaceObject.__)('Multiple selected blocks')); 40389 return () => { 40390 node.classList.remove('has-multi-selection'); 40391 node.removeAttribute('aria-label'); 40392 }; 40393 }, [hasMultiSelection])]), after]; 40394 } 40395 function WritingFlow({ 40396 children, 40397 ...props 40398 }, forwardedRef) { 40399 const [before, ref, after] = useWritingFlow(); 40400 return (0,external_React_.createElement)(external_React_.Fragment, null, before, (0,external_React_.createElement)("div", { 40401 ...props, 40402 ref: (0,external_wp_compose_namespaceObject.useMergeRefs)([ref, forwardedRef]), 40403 className: classnames_default()(props.className, 'block-editor-writing-flow') 40404 }, children), after); 40405 } 40406 40407 /** 40408 * Handles selection and navigation across blocks. This component should be 40409 * wrapped around BlockList. 40410 * 40411 * @param {Object} props Component properties. 40412 * @param {Element} props.children Children to be rendered. 40413 */ 40414 /* harmony default export */ const writing_flow = ((0,external_wp_element_namespaceObject.forwardRef)(WritingFlow)); 40415 40416 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/iframe/get-compatibility-styles.js 40417 let compatibilityStyles = null; 40418 40419 /** 40420 * Returns a list of stylesheets that target the editor canvas. A stylesheet is 40421 * considered targetting the editor a canvas if it contains the 40422 * `editor-styles-wrapper`, `wp-block`, or `wp-block-*` class selectors. 40423 * 40424 * Ideally, this hook should be removed in the future and styles should be added 40425 * explicitly as editor styles. 40426 */ 40427 function getCompatibilityStyles() { 40428 if (compatibilityStyles) { 40429 return compatibilityStyles; 40430 } 40431 40432 // Only memoize the result once on load, since these stylesheets should not 40433 // change. 40434 compatibilityStyles = Array.from(document.styleSheets).reduce((accumulator, styleSheet) => { 40435 try { 40436 // May fail for external styles. 40437 // eslint-disable-next-line no-unused-expressions 40438 styleSheet.cssRules; 40439 } catch (e) { 40440 return accumulator; 40441 } 40442 const { 40443 ownerNode, 40444 cssRules 40445 } = styleSheet; 40446 40447 // Stylesheet is added by another stylesheet. See 40448 // https://developer.mozilla.org/en-US/docs/Web/API/StyleSheet/ownerNode#notes. 40449 if (ownerNode === null) { 40450 return accumulator; 40451 } 40452 if (!cssRules) { 40453 return accumulator; 40454 } 40455 40456 // Don't try to add the reset styles, which were removed as a dependency 40457 // from `edit-blocks` for the iframe since we don't need to reset admin 40458 // styles. 40459 if (ownerNode.id === 'wp-reset-editor-styles-css') { 40460 return accumulator; 40461 } 40462 40463 // Don't try to add styles without ID. Styles enqueued via the WP dependency system will always have IDs. 40464 if (!ownerNode.id) { 40465 return accumulator; 40466 } 40467 function matchFromRules(_cssRules) { 40468 return Array.from(_cssRules).find(({ 40469 selectorText, 40470 conditionText, 40471 cssRules: __cssRules 40472 }) => { 40473 // If the rule is conditional then it will not have selector text. 40474 // Recurse into child CSS ruleset to determine selector eligibility. 40475 if (conditionText) { 40476 return matchFromRules(__cssRules); 40477 } 40478 return selectorText && (selectorText.includes('.editor-styles-wrapper') || selectorText.includes('.wp-block')); 40479 }); 40480 } 40481 if (matchFromRules(cssRules)) { 40482 const isInline = ownerNode.tagName === 'STYLE'; 40483 if (isInline) { 40484 // If the current target is inline, 40485 // it could be a dependency of an existing stylesheet. 40486 // Look for that dependency and add it BEFORE the current target. 40487 const mainStylesCssId = ownerNode.id.replace('-inline-css', '-css'); 40488 const mainStylesElement = document.getElementById(mainStylesCssId); 40489 if (mainStylesElement) { 40490 accumulator.push(mainStylesElement.cloneNode(true)); 40491 } 40492 } 40493 accumulator.push(ownerNode.cloneNode(true)); 40494 if (!isInline) { 40495 // If the current target is not inline, 40496 // we still look for inline styles that could be relevant for the current target. 40497 // If they exist, add them AFTER the current target. 40498 const inlineStylesCssId = ownerNode.id.replace('-css', '-inline-css'); 40499 const inlineStylesElement = document.getElementById(inlineStylesCssId); 40500 if (inlineStylesElement) { 40501 accumulator.push(inlineStylesElement.cloneNode(true)); 40502 } 40503 } 40504 } 40505 return accumulator; 40506 }, []); 40507 return compatibilityStyles; 40508 } 40509 40510 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/iframe/index.js 40511 40512 /** 40513 * External dependencies 40514 */ 40515 40516 40517 /** 40518 * WordPress dependencies 40519 */ 40520 40521 40522 40523 40524 40525 40526 /** 40527 * Internal dependencies 40528 */ 40529 40530 40531 40532 40533 function bubbleEvent(event, Constructor, frame) { 40534 const init = {}; 40535 for (const key in event) { 40536 init[key] = event[key]; 40537 } 40538 40539 // Check if the event is a MouseEvent generated within the iframe. 40540 // If so, adjust the coordinates to be relative to the position of 40541 // the iframe. This ensures that components such as Draggable 40542 // receive coordinates relative to the window, instead of relative 40543 // to the iframe. Without this, the Draggable event handler would 40544 // result in components "jumping" position as soon as the user 40545 // drags over the iframe. 40546 if (event instanceof frame.contentDocument.defaultView.MouseEvent) { 40547 const rect = frame.getBoundingClientRect(); 40548 init.clientX += rect.left; 40549 init.clientY += rect.top; 40550 } 40551 const newEvent = new Constructor(event.type, init); 40552 if (init.defaultPrevented) { 40553 newEvent.preventDefault(); 40554 } 40555 const cancelled = !frame.dispatchEvent(newEvent); 40556 if (cancelled) { 40557 event.preventDefault(); 40558 } 40559 } 40560 40561 /** 40562 * Bubbles some event types (keydown, keypress, and dragover) to parent document 40563 * document to ensure that the keyboard shortcuts and drag and drop work. 40564 * 40565 * Ideally, we should remove event bubbling in the future. Keyboard shortcuts 40566 * should be context dependent, e.g. actions on blocks like Cmd+A should not 40567 * work globally outside the block editor. 40568 * 40569 * @param {Document} iframeDocument Document to attach listeners to. 40570 */ 40571 function useBubbleEvents(iframeDocument) { 40572 return (0,external_wp_compose_namespaceObject.useRefEffect)(() => { 40573 const { 40574 defaultView 40575 } = iframeDocument; 40576 if (!defaultView) { 40577 return; 40578 } 40579 const { 40580 frameElement 40581 } = defaultView; 40582 const html = iframeDocument.documentElement; 40583 const eventTypes = ['dragover', 'mousemove']; 40584 const handlers = {}; 40585 for (const name of eventTypes) { 40586 handlers[name] = event => { 40587 const prototype = Object.getPrototypeOf(event); 40588 const constructorName = prototype.constructor.name; 40589 const Constructor = window[constructorName]; 40590 bubbleEvent(event, Constructor, frameElement); 40591 }; 40592 html.addEventListener(name, handlers[name]); 40593 } 40594 return () => { 40595 for (const name of eventTypes) { 40596 html.removeEventListener(name, handlers[name]); 40597 } 40598 }; 40599 }); 40600 } 40601 function Iframe({ 40602 contentRef, 40603 children, 40604 tabIndex = 0, 40605 scale = 1, 40606 frameSize = 0, 40607 expand = false, 40608 readonly, 40609 forwardedRef: ref, 40610 ...props 40611 }) { 40612 const { 40613 resolvedAssets, 40614 isPreviewMode 40615 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 40616 const settings = select(store).getSettings(); 40617 return { 40618 resolvedAssets: settings.__unstableResolvedAssets, 40619 isPreviewMode: settings.__unstableIsPreviewMode 40620 }; 40621 }, []); 40622 const { 40623 styles = '', 40624 scripts = '' 40625 } = resolvedAssets; 40626 const [iframeDocument, setIframeDocument] = (0,external_wp_element_namespaceObject.useState)(); 40627 const [bodyClasses, setBodyClasses] = (0,external_wp_element_namespaceObject.useState)([]); 40628 const clearerRef = useBlockSelectionClearer(); 40629 const [before, writingFlowRef, after] = useWritingFlow(); 40630 const [contentResizeListener, { 40631 height: contentHeight 40632 }] = (0,external_wp_compose_namespaceObject.useResizeObserver)(); 40633 const setRef = (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 40634 node._load = () => { 40635 setIframeDocument(node.contentDocument); 40636 }; 40637 let iFrameDocument; 40638 // Prevent the default browser action for files dropped outside of dropzones. 40639 function preventFileDropDefault(event) { 40640 event.preventDefault(); 40641 } 40642 function onLoad() { 40643 const { 40644 contentDocument, 40645 ownerDocument 40646 } = node; 40647 const { 40648 documentElement 40649 } = contentDocument; 40650 iFrameDocument = contentDocument; 40651 clearerRef(documentElement); 40652 40653 // Ideally ALL classes that are added through get_body_class should 40654 // be added in the editor too, which we'll somehow have to get from 40655 // the server in the future (which will run the PHP filters). 40656 setBodyClasses(Array.from(ownerDocument.body.classList).filter(name => name.startsWith('admin-color-') || name.startsWith('post-type-') || name === 'wp-embed-responsive')); 40657 contentDocument.dir = ownerDocument.dir; 40658 for (const compatStyle of getCompatibilityStyles()) { 40659 if (contentDocument.getElementById(compatStyle.id)) { 40660 continue; 40661 } 40662 contentDocument.head.appendChild(compatStyle.cloneNode(true)); 40663 if (!isPreviewMode) { 40664 // eslint-disable-next-line no-console 40665 console.warn(`$compatStyle.id} was added to the iframe incorrectly. Please use block.json or enqueue_block_assets to add styles to the iframe.`, compatStyle); 40666 } 40667 } 40668 iFrameDocument.addEventListener('dragover', preventFileDropDefault, false); 40669 iFrameDocument.addEventListener('drop', preventFileDropDefault, false); 40670 } 40671 node.addEventListener('load', onLoad); 40672 return () => { 40673 delete node._load; 40674 node.removeEventListener('load', onLoad); 40675 iFrameDocument?.removeEventListener('dragover', preventFileDropDefault); 40676 iFrameDocument?.removeEventListener('drop', preventFileDropDefault); 40677 }; 40678 }, []); 40679 const disabledRef = (0,external_wp_compose_namespaceObject.useDisabled)({ 40680 isDisabled: !readonly 40681 }); 40682 const bodyRef = (0,external_wp_compose_namespaceObject.useMergeRefs)([useBubbleEvents(iframeDocument), contentRef, clearerRef, writingFlowRef, disabledRef]); 40683 40684 // Correct doctype is required to enable rendering in standards 40685 // mode. Also preload the styles to avoid a flash of unstyled 40686 // content. 40687 const html = `<!doctype html> 40688 <html> 40689 <head> 40690 <meta charset="utf-8"> 40691 <script>window.frameElement._load()</script> 40692 <style>html{height:auto!important;min-height:100%;}body{margin:0}</style> 40693 $styles} 40694 $scripts} 40695 </head> 40696 <body> 40697 <script>document.currentScript.parentElement.remove()</script> 40698 </body> 40699 </html>`; 40700 const [src, cleanup] = (0,external_wp_element_namespaceObject.useMemo)(() => { 40701 const _src = URL.createObjectURL(new window.Blob([html], { 40702 type: 'text/html' 40703 })); 40704 return [_src, () => URL.revokeObjectURL(_src)]; 40705 }, [html]); 40706 (0,external_wp_element_namespaceObject.useEffect)(() => cleanup, [cleanup]); 40707 40708 // We need to counter the margin created by scaling the iframe. If the scale 40709 // is e.g. 0.45, then the top + bottom margin is 0.55 (1 - scale). Just the 40710 // top or bottom margin is 0.55 / 2 ((1 - scale) / 2). 40711 const marginFromScaling = contentHeight * (1 - scale) / 2; 40712 return (0,external_React_.createElement)(external_React_.Fragment, null, tabIndex >= 0 && before, (0,external_React_.createElement)("iframe", { 40713 ...props, 40714 style: { 40715 border: 0, 40716 ...props.style, 40717 height: expand ? contentHeight : props.style?.height, 40718 marginTop: scale !== 1 ? -marginFromScaling + frameSize : props.style?.marginTop, 40719 marginBottom: scale !== 1 ? -marginFromScaling + frameSize : props.style?.marginBottom, 40720 transform: scale !== 1 ? `scale( $scale} )` : props.style?.transform, 40721 transition: 'all .3s' 40722 }, 40723 ref: (0,external_wp_compose_namespaceObject.useMergeRefs)([ref, setRef]), 40724 tabIndex: tabIndex 40725 // Correct doctype is required to enable rendering in standards 40726 // mode. Also preload the styles to avoid a flash of unstyled 40727 // content. 40728 , 40729 src: src, 40730 title: (0,external_wp_i18n_namespaceObject.__)('Editor canvas'), 40731 onKeyDown: event => { 40732 if (props.onKeyDown) { 40733 props.onKeyDown(event); 40734 } 40735 // If the event originates from inside the iframe, it means 40736 // it bubbled through the portal, but only with React 40737 // events. We need to to bubble native events as well, 40738 // though by doing so we also trigger another React event, 40739 // so we need to stop the propagation of this event to avoid 40740 // duplication. 40741 else if (event.currentTarget.ownerDocument !== event.target.ownerDocument) { 40742 event.stopPropagation(); 40743 bubbleEvent(event, window.KeyboardEvent, event.currentTarget); 40744 } 40745 } 40746 }, iframeDocument && (0,external_wp_element_namespaceObject.createPortal)( 40747 // We want to prevent React events from bubbling throught the iframe 40748 // we bubble these manually. 40749 /* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */ 40750 (0,external_React_.createElement)("body", { 40751 ref: bodyRef, 40752 className: classnames_default()('block-editor-iframe__body', 'editor-styles-wrapper', ...bodyClasses) 40753 }, contentResizeListener, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalStyleProvider, { 40754 document: iframeDocument 40755 }, children)), iframeDocument.documentElement)), tabIndex >= 0 && after); 40756 } 40757 function IframeIfReady(props, ref) { 40758 const isInitialised = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getSettings().__internalIsInitialized, []); 40759 40760 // We shouldn't render the iframe until the editor settings are initialised. 40761 // The initial settings are needed to get the styles for the srcDoc, which 40762 // cannot be changed after the iframe is mounted. srcDoc is used to to set 40763 // the initial iframe HTML, which is required to avoid a flash of unstyled 40764 // content. 40765 if (!isInitialised) { 40766 return null; 40767 } 40768 return (0,external_React_.createElement)(Iframe, { 40769 ...props, 40770 forwardedRef: ref 40771 }); 40772 } 40773 /* harmony default export */ const iframe = ((0,external_wp_element_namespaceObject.forwardRef)(IframeIfReady)); 40774 40775 // EXTERNAL MODULE: ./node_modules/postcss/lib/postcss.js 40776 var postcss = __webpack_require__(4529); 40777 ;// CONCATENATED MODULE: ./node_modules/postcss/lib/postcss.mjs 40778 40779 40780 /* harmony default export */ const lib_postcss = (postcss); 40781 40782 const stringify = postcss.stringify 40783 const fromJSON = postcss.fromJSON 40784 const postcss_plugin = postcss.plugin 40785 const parse = postcss.parse 40786 const list = postcss.list 40787 40788 const postcss_document = postcss.document 40789 const comment = postcss.comment 40790 const atRule = postcss.atRule 40791 const rule = postcss.rule 40792 const decl = postcss.decl 40793 const root = postcss.root 40794 40795 const CssSyntaxError = postcss.CssSyntaxError 40796 const Declaration = postcss.Declaration 40797 const Container = postcss.Container 40798 const Processor = postcss.Processor 40799 const Document = postcss.Document 40800 const Comment = postcss.Comment 40801 const postcss_Warning = postcss.Warning 40802 const AtRule = postcss.AtRule 40803 const Result = postcss.Result 40804 const Input = postcss.Input 40805 const Rule = postcss.Rule 40806 const Root = postcss.Root 40807 const Node = postcss.Node 40808 40809 // EXTERNAL MODULE: ./node_modules/postcss-prefixwrap/build/index.js 40810 var build = __webpack_require__(8036); 40811 var build_default = /*#__PURE__*/__webpack_require__.n(build); 40812 // EXTERNAL MODULE: ./node_modules/postcss-urlrebase/index.js 40813 var postcss_urlrebase = __webpack_require__(5404); 40814 var postcss_urlrebase_default = /*#__PURE__*/__webpack_require__.n(postcss_urlrebase); 40815 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/transform-styles/index.js 40816 /** 40817 * External dependencies 40818 */ 40819 40820 40821 40822 const transformStylesCache = new WeakMap(); 40823 function transformStyle({ 40824 css, 40825 ignoredSelectors = [], 40826 baseURL 40827 }, wrapperSelector = '') { 40828 // When there is no wrapper selector or base URL, there is no need 40829 // to transform the CSS. This is most cases because in the default 40830 // iframed editor, no wrapping is needed, and not many styles 40831 // provide a base URL. 40832 if (!wrapperSelector && !baseURL) { 40833 return css; 40834 } 40835 try { 40836 return lib_postcss([wrapperSelector && build_default()(wrapperSelector, { 40837 ignoredSelectors: [...ignoredSelectors, wrapperSelector] 40838 }), baseURL && postcss_urlrebase_default()({ 40839 rootUrl: baseURL 40840 })].filter(Boolean)).process(css, {}).css; // use sync PostCSS API 40841 } catch (error) { 40842 if (error instanceof CssSyntaxError) { 40843 // eslint-disable-next-line no-console 40844 console.warn('wp.blockEditor.transformStyles Failed to transform CSS.', error.message + '\n' + error.showSourceCode(false)); 40845 } else { 40846 // eslint-disable-next-line no-console 40847 console.warn('wp.blockEditor.transformStyles Failed to transform CSS.', error); 40848 } 40849 return null; 40850 } 40851 } 40852 40853 /** 40854 * Applies a series of CSS rule transforms to wrap selectors inside a given class and/or rewrite URLs depending on the parameters passed. 40855 * 40856 * @typedef {Object} EditorStyle 40857 * @property {string} css the CSS block(s), as a single string. 40858 * @property {?string} baseURL the base URL to be used as the reference when rewritting urls. 40859 * @property {?string[]} ignoredSelectors the selectors not to wrap. 40860 * 40861 * @param {EditorStyle[]} styles CSS rules. 40862 * @param {string} wrapperSelector Wrapper selector. 40863 * @return {Array} converted rules. 40864 */ 40865 const transform_styles_transformStyles = (styles, wrapperSelector = '') => { 40866 return styles.map(style => { 40867 if (transformStylesCache.has(style)) { 40868 return transformStylesCache.get(style); 40869 } 40870 const transformedStyle = transformStyle(style, wrapperSelector); 40871 transformStylesCache.set(style, transformedStyle); 40872 return transformedStyle; 40873 }); 40874 }; 40875 /* harmony default export */ const transform_styles = (transform_styles_transformStyles); 40876 40877 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/editor-styles/index.js 40878 40879 /** 40880 * External dependencies 40881 */ 40882 40883 40884 40885 40886 /** 40887 * WordPress dependencies 40888 */ 40889 40890 40891 40892 40893 /** 40894 * Internal dependencies 40895 */ 40896 40897 40898 40899 k([names, a11y]); 40900 function useDarkThemeBodyClassName(styles, scope) { 40901 return (0,external_wp_element_namespaceObject.useCallback)(node => { 40902 if (!node) { 40903 return; 40904 } 40905 const { 40906 ownerDocument 40907 } = node; 40908 const { 40909 defaultView, 40910 body 40911 } = ownerDocument; 40912 const canvas = scope ? ownerDocument.querySelector(scope) : body; 40913 let backgroundColor; 40914 if (!canvas) { 40915 // The real .editor-styles-wrapper element might not exist in the 40916 // DOM, so calculate the background color by creating a fake 40917 // wrapper. 40918 const tempCanvas = ownerDocument.createElement('div'); 40919 tempCanvas.classList.add('editor-styles-wrapper'); 40920 body.appendChild(tempCanvas); 40921 backgroundColor = defaultView?.getComputedStyle(tempCanvas, null).getPropertyValue('background-color'); 40922 body.removeChild(tempCanvas); 40923 } else { 40924 backgroundColor = defaultView?.getComputedStyle(canvas, null).getPropertyValue('background-color'); 40925 } 40926 const colordBackgroundColor = w(backgroundColor); 40927 // If background is transparent, it should be treated as light color. 40928 if (colordBackgroundColor.luminance() > 0.5 || colordBackgroundColor.alpha() === 0) { 40929 body.classList.remove('is-dark-theme'); 40930 } else { 40931 body.classList.add('is-dark-theme'); 40932 } 40933 }, [styles, scope]); 40934 } 40935 function EditorStyles({ 40936 styles, 40937 scope 40938 }) { 40939 const overrides = (0,external_wp_data_namespaceObject.useSelect)(select => unlock(select(store)).getStyleOverrides(), []); 40940 const [transformedStyles, transformedSvgs] = (0,external_wp_element_namespaceObject.useMemo)(() => { 40941 const _styles = Object.values(styles !== null && styles !== void 0 ? styles : []); 40942 for (const [id, override] of overrides) { 40943 const index = _styles.findIndex(({ 40944 id: _id 40945 }) => id === _id); 40946 const overrideWithId = { 40947 ...override, 40948 id 40949 }; 40950 if (index === -1) { 40951 _styles.push(overrideWithId); 40952 } else { 40953 _styles[index] = overrideWithId; 40954 } 40955 } 40956 return [transform_styles(_styles.filter(style => style?.css), scope), _styles.filter(style => style.__unstableType === 'svgs').map(style => style.assets).join('')]; 40957 }, [styles, overrides, scope]); 40958 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)("style", { 40959 ref: useDarkThemeBodyClassName(transformedStyles, scope) 40960 }), transformedStyles.map((css, index) => (0,external_React_.createElement)("style", { 40961 key: index 40962 }, css)), (0,external_React_.createElement)(external_wp_components_namespaceObject.SVG, { 40963 xmlns: "http://www.w3.org/2000/svg", 40964 viewBox: "0 0 0 0", 40965 width: "0", 40966 height: "0", 40967 role: "none", 40968 style: { 40969 visibility: 'hidden', 40970 position: 'absolute', 40971 left: '-9999px', 40972 overflow: 'hidden' 40973 }, 40974 dangerouslySetInnerHTML: { 40975 __html: transformedSvgs 40976 } 40977 })); 40978 } 40979 40980 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-preview/auto.js 40981 40982 /** 40983 * WordPress dependencies 40984 */ 40985 40986 40987 40988 40989 40990 /** 40991 * Internal dependencies 40992 */ 40993 40994 40995 40996 40997 40998 // This is used to avoid rendering the block list if the sizes change. 40999 let MemoizedBlockList; 41000 const MAX_HEIGHT = 2000; 41001 const EMPTY_ADDITIONAL_STYLES = []; 41002 function ScaledBlockPreview({ 41003 viewportWidth, 41004 containerWidth, 41005 minHeight, 41006 additionalStyles = EMPTY_ADDITIONAL_STYLES 41007 }) { 41008 if (!viewportWidth) { 41009 viewportWidth = containerWidth; 41010 } 41011 const [contentResizeListener, { 41012 height: contentHeight 41013 }] = (0,external_wp_compose_namespaceObject.useResizeObserver)(); 41014 const { 41015 styles 41016 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 41017 const settings = select(store).getSettings(); 41018 return { 41019 styles: settings.styles 41020 }; 41021 }, []); 41022 41023 // Avoid scrollbars for pattern previews. 41024 const editorStyles = (0,external_wp_element_namespaceObject.useMemo)(() => { 41025 if (styles) { 41026 return [...styles, { 41027 css: 'body{height:auto;overflow:hidden;border:none;padding:0;}', 41028 __unstableType: 'presets' 41029 }, ...additionalStyles]; 41030 } 41031 return styles; 41032 }, [styles, additionalStyles]); 41033 41034 // Initialize on render instead of module top level, to avoid circular dependency issues. 41035 MemoizedBlockList = MemoizedBlockList || (0,external_wp_element_namespaceObject.memo)(BlockList); 41036 const scale = containerWidth / viewportWidth; 41037 const aspectRatio = contentHeight ? containerWidth / (contentHeight * scale) : 0; 41038 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Disabled, { 41039 className: "block-editor-block-preview__content", 41040 style: { 41041 transform: `scale($scale})`, 41042 // Using width + aspect-ratio instead of height here triggers browsers' native 41043 // handling of scrollbar's visibility. It prevents the flickering issue seen 41044 // in https://github.com/WordPress/gutenberg/issues/52027. 41045 // See https://github.com/WordPress/gutenberg/pull/52921 for more info. 41046 aspectRatio, 41047 maxHeight: contentHeight > MAX_HEIGHT ? MAX_HEIGHT * scale : undefined, 41048 minHeight 41049 } 41050 }, (0,external_React_.createElement)(iframe, { 41051 contentRef: (0,external_wp_compose_namespaceObject.useRefEffect)(bodyElement => { 41052 const { 41053 ownerDocument: { 41054 documentElement 41055 } 41056 } = bodyElement; 41057 documentElement.classList.add('block-editor-block-preview__content-iframe'); 41058 documentElement.style.position = 'absolute'; 41059 documentElement.style.width = '100%'; 41060 41061 // Necessary for contentResizeListener to work. 41062 bodyElement.style.boxSizing = 'border-box'; 41063 bodyElement.style.position = 'absolute'; 41064 bodyElement.style.width = '100%'; 41065 }, []), 41066 "aria-hidden": true, 41067 tabIndex: -1, 41068 style: { 41069 position: 'absolute', 41070 width: viewportWidth, 41071 height: contentHeight, 41072 pointerEvents: 'none', 41073 // This is a catch-all max-height for patterns. 41074 // See: https://github.com/WordPress/gutenberg/pull/38175. 41075 maxHeight: MAX_HEIGHT, 41076 minHeight: scale !== 0 && scale < 1 && minHeight ? minHeight / scale : minHeight 41077 } 41078 }, (0,external_React_.createElement)(EditorStyles, { 41079 styles: editorStyles 41080 }), contentResizeListener, (0,external_React_.createElement)(MemoizedBlockList, { 41081 renderAppender: false 41082 }))); 41083 } 41084 function AutoBlockPreview(props) { 41085 const [containerResizeListener, { 41086 width: containerWidth 41087 }] = (0,external_wp_compose_namespaceObject.useResizeObserver)(); 41088 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)("div", { 41089 style: { 41090 position: 'relative', 41091 width: '100%', 41092 height: 0 41093 } 41094 }, containerResizeListener), (0,external_React_.createElement)("div", { 41095 className: "block-editor-block-preview__container" 41096 }, !!containerWidth && (0,external_React_.createElement)(ScaledBlockPreview, { 41097 ...props, 41098 containerWidth: containerWidth 41099 }))); 41100 } 41101 41102 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-preview/index.js 41103 41104 /** 41105 * External dependencies 41106 */ 41107 41108 41109 /** 41110 * WordPress dependencies 41111 */ 41112 41113 41114 41115 41116 41117 /** 41118 * Internal dependencies 41119 */ 41120 41121 41122 41123 41124 41125 function BlockPreview({ 41126 blocks, 41127 viewportWidth = 1200, 41128 minHeight, 41129 additionalStyles = [], 41130 // Deprecated props: 41131 __experimentalMinHeight, 41132 __experimentalPadding 41133 }) { 41134 if (__experimentalMinHeight) { 41135 minHeight = __experimentalMinHeight; 41136 external_wp_deprecated_default()('The __experimentalMinHeight prop', { 41137 since: '6.2', 41138 version: '6.4', 41139 alternative: 'minHeight' 41140 }); 41141 } 41142 if (__experimentalPadding) { 41143 additionalStyles = [...additionalStyles, { 41144 css: `body { padding: $__experimentalPadding}px; }` 41145 }]; 41146 external_wp_deprecated_default()('The __experimentalPadding prop of BlockPreview', { 41147 since: '6.2', 41148 version: '6.4', 41149 alternative: 'additionalStyles' 41150 }); 41151 } 41152 const originalSettings = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getSettings(), []); 41153 const settings = (0,external_wp_element_namespaceObject.useMemo)(() => ({ 41154 ...originalSettings, 41155 focusMode: false, 41156 // Disable "Spotlight mode". 41157 __unstableIsPreviewMode: true 41158 }), [originalSettings]); 41159 const renderedBlocks = (0,external_wp_element_namespaceObject.useMemo)(() => Array.isArray(blocks) ? blocks : [blocks], [blocks]); 41160 if (!blocks || blocks.length === 0) { 41161 return null; 41162 } 41163 return (0,external_React_.createElement)(ExperimentalBlockEditorProvider, { 41164 value: renderedBlocks, 41165 settings: settings 41166 }, (0,external_React_.createElement)(AutoBlockPreview, { 41167 viewportWidth: viewportWidth, 41168 minHeight: minHeight, 41169 additionalStyles: additionalStyles 41170 })); 41171 } 41172 41173 /** 41174 * BlockPreview renders a preview of a block or array of blocks. 41175 * 41176 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-preview/README.md 41177 * 41178 * @param {Object} preview options for how the preview should be shown 41179 * @param {Array|Object} preview.blocks A block instance (object) or an array of blocks to be previewed. 41180 * @param {number} preview.viewportWidth Width of the preview container in pixels. Controls at what size the blocks will be rendered inside the preview. Default: 700. 41181 * 41182 * @return {Component} The component to be rendered. 41183 */ 41184 /* harmony default export */ const block_preview = ((0,external_wp_element_namespaceObject.memo)(BlockPreview)); 41185 41186 /** 41187 * This hook is used to lightly mark an element as a block preview wrapper 41188 * element. Call this hook and pass the returned props to the element to mark as 41189 * a block preview wrapper, automatically rendering inner blocks as children. If 41190 * you define a ref for the element, it is important to pass the ref to this 41191 * hook, which the hook in turn will pass to the component through the props it 41192 * returns. Optionally, you can also pass any other props through this hook, and 41193 * they will be merged and returned. 41194 * 41195 * @param {Object} options Preview options. 41196 * @param {WPBlock[]} options.blocks Block objects. 41197 * @param {Object} options.props Optional. Props to pass to the element. Must contain 41198 * the ref if one is defined. 41199 * @param {Object} options.layout Layout settings to be used in the preview. 41200 */ 41201 function useBlockPreview({ 41202 blocks, 41203 props = {}, 41204 layout 41205 }) { 41206 const originalSettings = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getSettings(), []); 41207 const settings = (0,external_wp_element_namespaceObject.useMemo)(() => ({ 41208 ...originalSettings, 41209 styles: undefined, 41210 // Clear styles included by the parent settings, as they are already output by the parent's EditorStyles. 41211 focusMode: false, 41212 // Disable "Spotlight mode". 41213 __unstableIsPreviewMode: true 41214 }), [originalSettings]); 41215 const disabledRef = (0,external_wp_compose_namespaceObject.useDisabled)(); 41216 const ref = (0,external_wp_compose_namespaceObject.useMergeRefs)([props.ref, disabledRef]); 41217 const renderedBlocks = (0,external_wp_element_namespaceObject.useMemo)(() => Array.isArray(blocks) ? blocks : [blocks], [blocks]); 41218 const children = (0,external_React_.createElement)(ExperimentalBlockEditorProvider, { 41219 value: renderedBlocks, 41220 settings: settings 41221 }, (0,external_React_.createElement)(EditorStyles, null), (0,external_React_.createElement)(BlockListItems, { 41222 renderAppender: false, 41223 layout: layout 41224 })); 41225 return { 41226 ...props, 41227 ref, 41228 className: classnames_default()(props.className, 'block-editor-block-preview__live-content', 'components-disabled'), 41229 children: blocks?.length ? children : null 41230 }; 41231 } 41232 41233 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/preview-panel.js 41234 41235 /** 41236 * WordPress dependencies 41237 */ 41238 41239 41240 41241 41242 /** 41243 * Internal dependencies 41244 */ 41245 41246 41247 function InserterPreviewPanel({ 41248 item 41249 }) { 41250 var _example$viewportWidt; 41251 const { 41252 name, 41253 title, 41254 icon, 41255 description, 41256 initialAttributes, 41257 example 41258 } = item; 41259 const isReusable = (0,external_wp_blocks_namespaceObject.isReusableBlock)(item); 41260 const blocks = (0,external_wp_element_namespaceObject.useMemo)(() => { 41261 if (!example) { 41262 return (0,external_wp_blocks_namespaceObject.createBlock)(name, initialAttributes); 41263 } 41264 return (0,external_wp_blocks_namespaceObject.getBlockFromExample)(name, { 41265 attributes: { 41266 ...example.attributes, 41267 ...initialAttributes 41268 }, 41269 innerBlocks: example.innerBlocks 41270 }); 41271 }, [name, example, initialAttributes]); 41272 return (0,external_React_.createElement)("div", { 41273 className: "block-editor-inserter__preview-container" 41274 }, (0,external_React_.createElement)("div", { 41275 className: "block-editor-inserter__preview" 41276 }, isReusable || example ? (0,external_React_.createElement)("div", { 41277 className: "block-editor-inserter__preview-content" 41278 }, (0,external_React_.createElement)(block_preview, { 41279 blocks: blocks, 41280 viewportWidth: (_example$viewportWidt = example?.viewportWidth) !== null && _example$viewportWidt !== void 0 ? _example$viewportWidt : 500, 41281 additionalStyles: [{ 41282 css: 'body { padding: 24px; }' 41283 }] 41284 })) : (0,external_React_.createElement)("div", { 41285 className: "block-editor-inserter__preview-content-missing" 41286 }, (0,external_wp_i18n_namespaceObject.__)('No preview available.'))), !isReusable && (0,external_React_.createElement)(block_card, { 41287 title: title, 41288 icon: icon, 41289 description: description 41290 })); 41291 } 41292 /* harmony default export */ const preview_panel = (InserterPreviewPanel); 41293 41294 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter-listbox/item.js 41295 41296 /** 41297 * WordPress dependencies 41298 */ 41299 41300 41301 41302 /** 41303 * Internal dependencies 41304 */ 41305 41306 const { 41307 CompositeItemV2: CompositeItem 41308 } = unlock(external_wp_components_namespaceObject.privateApis); 41309 function InserterListboxItem({ 41310 isFirst, 41311 as: Component, 41312 children, 41313 ...props 41314 }, ref) { 41315 return (0,external_React_.createElement)(CompositeItem, { 41316 ref: ref, 41317 role: "option" 41318 // Use the CompositeItem `accessibleWhenDisabled` prop 41319 // over Button's `isFocusable`. The latter was shown to 41320 // cause an issue with tab order in the inserter list. 41321 , 41322 accessibleWhenDisabled: true, 41323 ...props, 41324 render: htmlProps => { 41325 const propsWithTabIndex = { 41326 ...htmlProps, 41327 tabIndex: isFirst ? 0 : htmlProps.tabIndex 41328 }; 41329 if (Component) { 41330 return (0,external_React_.createElement)(Component, { 41331 ...propsWithTabIndex 41332 }, children); 41333 } 41334 if (typeof children === 'function') { 41335 return children(propsWithTabIndex); 41336 } 41337 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 41338 ...propsWithTabIndex 41339 }, children); 41340 } 41341 }); 41342 } 41343 /* harmony default export */ const inserter_listbox_item = ((0,external_wp_element_namespaceObject.forwardRef)(InserterListboxItem)); 41344 41345 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/drag-handle.js 41346 41347 /** 41348 * WordPress dependencies 41349 */ 41350 41351 const dragHandle = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 41352 width: "24", 41353 height: "24", 41354 xmlns: "http://www.w3.org/2000/svg", 41355 viewBox: "0 0 24 24" 41356 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 41357 d: "M8 7h2V5H8v2zm0 6h2v-2H8v2zm0 6h2v-2H8v2zm6-14v2h2V5h-2zm0 8h2v-2h-2v2zm0 6h2v-2h-2v2z" 41358 })); 41359 /* harmony default export */ const drag_handle = (dragHandle); 41360 41361 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-draggable/draggable-chip.js 41362 41363 /** 41364 * WordPress dependencies 41365 */ 41366 41367 41368 41369 41370 /** 41371 * Internal dependencies 41372 */ 41373 41374 function BlockDraggableChip({ 41375 count, 41376 icon, 41377 isPattern, 41378 fadeWhenDisabled 41379 }) { 41380 const patternLabel = isPattern && (0,external_wp_i18n_namespaceObject.__)('Pattern'); 41381 return (0,external_React_.createElement)("div", { 41382 className: "block-editor-block-draggable-chip-wrapper" 41383 }, (0,external_React_.createElement)("div", { 41384 className: "block-editor-block-draggable-chip", 41385 "data-testid": "block-draggable-chip" 41386 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Flex, { 41387 justify: "center", 41388 className: "block-editor-block-draggable-chip__content" 41389 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexItem, null, icon ? (0,external_React_.createElement)(block_icon, { 41390 icon: icon 41391 }) : patternLabel || (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %d: Number of blocks. */ 41392 (0,external_wp_i18n_namespaceObject._n)('%d block', '%d blocks', count), count)), (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexItem, null, (0,external_React_.createElement)(block_icon, { 41393 icon: drag_handle 41394 })), fadeWhenDisabled && (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexItem, { 41395 className: "block-editor-block-draggable-chip__disabled" 41396 }, (0,external_React_.createElement)("span", { 41397 className: "block-editor-block-draggable-chip__disabled-icon" 41398 }))))); 41399 } 41400 41401 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter-draggable-blocks/index.js 41402 41403 /** 41404 * WordPress dependencies 41405 */ 41406 41407 41408 41409 41410 /** 41411 * Internal dependencies 41412 */ 41413 41414 41415 41416 41417 const InserterDraggableBlocks = ({ 41418 isEnabled, 41419 blocks, 41420 icon, 41421 children, 41422 pattern 41423 }) => { 41424 const transferData = { 41425 type: 'inserter', 41426 blocks 41427 }; 41428 const blockTypeIcon = (0,external_wp_data_namespaceObject.useSelect)(select => { 41429 const { 41430 getBlockType 41431 } = select(external_wp_blocks_namespaceObject.store); 41432 return blocks.length === 1 && getBlockType(blocks[0].name)?.icon; 41433 }, [blocks]); 41434 const { 41435 startDragging, 41436 stopDragging 41437 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store)); 41438 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Draggable, { 41439 __experimentalTransferDataType: "wp-blocks", 41440 transferData: transferData, 41441 onDragStart: event => { 41442 startDragging(); 41443 const parsedBlocks = pattern?.type === INSERTER_PATTERN_TYPES.user && pattern?.syncStatus !== 'unsynced' ? [(0,external_wp_blocks_namespaceObject.createBlock)('core/block', { 41444 ref: pattern.id 41445 })] : blocks; 41446 event.dataTransfer.setData('text/html', (0,external_wp_blocks_namespaceObject.serialize)(parsedBlocks)); 41447 }, 41448 onDragEnd: () => { 41449 stopDragging(); 41450 }, 41451 __experimentalDragComponent: (0,external_React_.createElement)(BlockDraggableChip, { 41452 count: blocks.length, 41453 icon: icon || !pattern && blockTypeIcon, 41454 isPattern: !!pattern 41455 }) 41456 }, ({ 41457 onDraggableStart, 41458 onDraggableEnd 41459 }) => { 41460 return children({ 41461 draggable: isEnabled, 41462 onDragStart: isEnabled ? onDraggableStart : undefined, 41463 onDragEnd: isEnabled ? onDraggableEnd : undefined 41464 }); 41465 }); 41466 }; 41467 /* harmony default export */ const inserter_draggable_blocks = (InserterDraggableBlocks); 41468 41469 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter-list-item/index.js 41470 41471 /** 41472 * External dependencies 41473 */ 41474 41475 41476 /** 41477 * WordPress dependencies 41478 */ 41479 41480 41481 41482 41483 41484 /** 41485 * Internal dependencies 41486 */ 41487 41488 41489 41490 function InserterListItem({ 41491 className, 41492 isFirst, 41493 item, 41494 onSelect, 41495 onHover, 41496 isDraggable, 41497 ...props 41498 }) { 41499 const isDragging = (0,external_wp_element_namespaceObject.useRef)(false); 41500 const itemIconStyle = item.icon ? { 41501 backgroundColor: item.icon.background, 41502 color: item.icon.foreground 41503 } : {}; 41504 const blocks = (0,external_wp_element_namespaceObject.useMemo)(() => [(0,external_wp_blocks_namespaceObject.createBlock)(item.name, item.initialAttributes, (0,external_wp_blocks_namespaceObject.createBlocksFromInnerBlocksTemplate)(item.innerBlocks))], [item.name, item.initialAttributes, item.innerBlocks]); 41505 const isSynced = (0,external_wp_blocks_namespaceObject.isReusableBlock)(item) && item.syncStatus !== 'unsynced' || (0,external_wp_blocks_namespaceObject.isTemplatePart)(item); 41506 return (0,external_React_.createElement)(inserter_draggable_blocks, { 41507 isEnabled: isDraggable && !item.isDisabled, 41508 blocks: blocks, 41509 icon: item.icon 41510 }, ({ 41511 draggable, 41512 onDragStart, 41513 onDragEnd 41514 }) => (0,external_React_.createElement)("div", { 41515 className: classnames_default()('block-editor-block-types-list__list-item', { 41516 'is-synced': isSynced 41517 }), 41518 draggable: draggable, 41519 onDragStart: event => { 41520 isDragging.current = true; 41521 if (onDragStart) { 41522 onHover(null); 41523 onDragStart(event); 41524 } 41525 }, 41526 onDragEnd: event => { 41527 isDragging.current = false; 41528 if (onDragEnd) { 41529 onDragEnd(event); 41530 } 41531 } 41532 }, (0,external_React_.createElement)(inserter_listbox_item, { 41533 isFirst: isFirst, 41534 className: classnames_default()('block-editor-block-types-list__item', className), 41535 disabled: item.isDisabled, 41536 onClick: event => { 41537 event.preventDefault(); 41538 onSelect(item, (0,external_wp_keycodes_namespaceObject.isAppleOS)() ? event.metaKey : event.ctrlKey); 41539 onHover(null); 41540 }, 41541 onKeyDown: event => { 41542 const { 41543 keyCode 41544 } = event; 41545 if (keyCode === external_wp_keycodes_namespaceObject.ENTER) { 41546 event.preventDefault(); 41547 onSelect(item, (0,external_wp_keycodes_namespaceObject.isAppleOS)() ? event.metaKey : event.ctrlKey); 41548 onHover(null); 41549 } 41550 }, 41551 onMouseEnter: () => { 41552 if (isDragging.current) { 41553 return; 41554 } 41555 onHover(item); 41556 }, 41557 onMouseLeave: () => onHover(null), 41558 ...props 41559 }, (0,external_React_.createElement)("span", { 41560 className: "block-editor-block-types-list__item-icon", 41561 style: itemIconStyle 41562 }, (0,external_React_.createElement)(block_icon, { 41563 icon: item.icon, 41564 showColors: true 41565 })), (0,external_React_.createElement)("span", { 41566 className: "block-editor-block-types-list__item-title" 41567 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalTruncate, { 41568 numberOfLines: 3 41569 }, item.title))))); 41570 } 41571 /* harmony default export */ const inserter_list_item = ((0,external_wp_element_namespaceObject.memo)(InserterListItem)); 41572 41573 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter-listbox/group.js 41574 41575 /** 41576 * WordPress dependencies 41577 */ 41578 41579 41580 41581 function InserterListboxGroup(props, ref) { 41582 const [shouldSpeak, setShouldSpeak] = (0,external_wp_element_namespaceObject.useState)(false); 41583 (0,external_wp_element_namespaceObject.useEffect)(() => { 41584 if (shouldSpeak) { 41585 (0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.__)('Use left and right arrow keys to move through blocks')); 41586 } 41587 }, [shouldSpeak]); 41588 return (0,external_React_.createElement)("div", { 41589 ref: ref, 41590 role: "listbox", 41591 "aria-orientation": "horizontal", 41592 onFocus: () => { 41593 setShouldSpeak(true); 41594 }, 41595 onBlur: event => { 41596 const focusingOutsideGroup = !event.currentTarget.contains(event.relatedTarget); 41597 if (focusingOutsideGroup) { 41598 setShouldSpeak(false); 41599 } 41600 }, 41601 ...props 41602 }); 41603 } 41604 /* harmony default export */ const group = ((0,external_wp_element_namespaceObject.forwardRef)(InserterListboxGroup)); 41605 41606 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter-listbox/row.js 41607 41608 /** 41609 * WordPress dependencies 41610 */ 41611 41612 41613 41614 /** 41615 * Internal dependencies 41616 */ 41617 41618 const { 41619 CompositeGroupV2: CompositeGroup 41620 } = unlock(external_wp_components_namespaceObject.privateApis); 41621 function InserterListboxRow(props, ref) { 41622 return (0,external_React_.createElement)(CompositeGroup, { 41623 role: "presentation", 41624 ref: ref, 41625 ...props 41626 }); 41627 } 41628 /* harmony default export */ const inserter_listbox_row = ((0,external_wp_element_namespaceObject.forwardRef)(InserterListboxRow)); 41629 41630 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-types-list/index.js 41631 41632 /** 41633 * WordPress dependencies 41634 */ 41635 41636 41637 41638 /** 41639 * Internal dependencies 41640 */ 41641 41642 41643 function chunk(array, size) { 41644 const chunks = []; 41645 for (let i = 0, j = array.length; i < j; i += size) { 41646 chunks.push(array.slice(i, i + size)); 41647 } 41648 return chunks; 41649 } 41650 function BlockTypesList({ 41651 items = [], 41652 onSelect, 41653 onHover = () => {}, 41654 children, 41655 label, 41656 isDraggable = true 41657 }) { 41658 const className = 'block-editor-block-types-list'; 41659 const listId = (0,external_wp_compose_namespaceObject.useInstanceId)(BlockTypesList, className); 41660 return (0,external_React_.createElement)(group, { 41661 className: className, 41662 "aria-label": label 41663 }, chunk(items, 3).map((row, i) => (0,external_React_.createElement)(inserter_listbox_row, { 41664 key: i 41665 }, row.map((item, j) => (0,external_React_.createElement)(inserter_list_item, { 41666 key: item.id, 41667 item: item, 41668 className: (0,external_wp_blocks_namespaceObject.getBlockMenuDefaultClassName)(item.id), 41669 onSelect: onSelect, 41670 onHover: onHover, 41671 isDraggable: isDraggable && !item.isDisabled, 41672 isFirst: i === 0 && j === 0, 41673 rowId: `$listId}-$i}` 41674 })))), children); 41675 } 41676 /* harmony default export */ const block_types_list = (BlockTypesList); 41677 41678 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/panel.js 41679 41680 /** 41681 * WordPress dependencies 41682 */ 41683 41684 function InserterPanel({ 41685 title, 41686 icon, 41687 children 41688 }) { 41689 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)("div", { 41690 className: "block-editor-inserter__panel-header" 41691 }, (0,external_React_.createElement)("h2", { 41692 className: "block-editor-inserter__panel-title" 41693 }, title), (0,external_React_.createElement)(external_wp_components_namespaceObject.Icon, { 41694 icon: icon 41695 })), (0,external_React_.createElement)("div", { 41696 className: "block-editor-inserter__panel-content" 41697 }, children)); 41698 } 41699 /* harmony default export */ const panel = (InserterPanel); 41700 41701 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter-listbox/index.js 41702 41703 /** 41704 * WordPress dependencies 41705 */ 41706 41707 41708 /** 41709 * Internal dependencies 41710 */ 41711 41712 41713 41714 41715 const { 41716 CompositeV2: Composite, 41717 useCompositeStoreV2: useCompositeStore 41718 } = unlock(external_wp_components_namespaceObject.privateApis); 41719 function InserterListbox({ 41720 children 41721 }) { 41722 const store = useCompositeStore({ 41723 focusShift: true, 41724 focusWrap: 'horizontal' 41725 }); 41726 return (0,external_React_.createElement)(Composite, { 41727 store: store, 41728 render: (0,external_React_.createElement)(external_React_.Fragment, null) 41729 }, children); 41730 } 41731 /* harmony default export */ const inserter_listbox = (InserterListbox); 41732 41733 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/block-types-tab.js 41734 41735 /** 41736 * WordPress dependencies 41737 */ 41738 41739 41740 41741 41742 /** 41743 * Internal dependencies 41744 */ 41745 41746 41747 41748 41749 41750 const getBlockNamespace = item => item.name.split('/')[0]; 41751 const MAX_SUGGESTED_ITEMS = 6; 41752 41753 /** 41754 * Shared reference to an empty array for cases where it is important to avoid 41755 * returning a new array reference on every invocation and rerendering the component. 41756 * 41757 * @type {Array} 41758 */ 41759 const block_types_tab_EMPTY_ARRAY = []; 41760 function BlockTypesTab({ 41761 rootClientId, 41762 onInsert, 41763 onHover, 41764 showMostUsedBlocks 41765 }) { 41766 const [items, categories, collections, onSelectItem] = use_block_types_state(rootClientId, onInsert); 41767 const suggestedItems = (0,external_wp_element_namespaceObject.useMemo)(() => { 41768 return orderBy(items, 'frecency', 'desc').slice(0, MAX_SUGGESTED_ITEMS); 41769 }, [items]); 41770 const uncategorizedItems = (0,external_wp_element_namespaceObject.useMemo)(() => { 41771 return items.filter(item => !item.category); 41772 }, [items]); 41773 const itemsPerCategory = (0,external_wp_element_namespaceObject.useMemo)(() => { 41774 return (0,external_wp_compose_namespaceObject.pipe)(itemList => itemList.filter(item => item.category && item.category !== 'reusable'), itemList => itemList.reduce((acc, item) => { 41775 const { 41776 category 41777 } = item; 41778 if (!acc[category]) { 41779 acc[category] = []; 41780 } 41781 acc[category].push(item); 41782 return acc; 41783 }, {}))(items); 41784 }, [items]); 41785 const itemsPerCollection = (0,external_wp_element_namespaceObject.useMemo)(() => { 41786 // Create a new Object to avoid mutating collection. 41787 const result = { 41788 ...collections 41789 }; 41790 Object.keys(collections).forEach(namespace => { 41791 result[namespace] = items.filter(item => getBlockNamespace(item) === namespace); 41792 if (result[namespace].length === 0) { 41793 delete result[namespace]; 41794 } 41795 }); 41796 return result; 41797 }, [items, collections]); 41798 41799 // Hide block preview on unmount. 41800 (0,external_wp_element_namespaceObject.useEffect)(() => () => onHover(null), []); 41801 41802 /** 41803 * The inserter contains a big number of blocks and opening it is a costful operation. 41804 * The rendering is the most costful part of it, in order to improve the responsiveness 41805 * of the "opening" action, these lazy lists allow us to render the inserter category per category, 41806 * once all the categories are rendered, we start rendering the collections and the uncategorized block types. 41807 */ 41808 const currentlyRenderedCategories = (0,external_wp_compose_namespaceObject.useAsyncList)(categories); 41809 const didRenderAllCategories = categories.length === currentlyRenderedCategories.length; 41810 41811 // Async List requires an array. 41812 const collectionEntries = (0,external_wp_element_namespaceObject.useMemo)(() => { 41813 return Object.entries(collections); 41814 }, [collections]); 41815 const currentlyRenderedCollections = (0,external_wp_compose_namespaceObject.useAsyncList)(didRenderAllCategories ? collectionEntries : block_types_tab_EMPTY_ARRAY); 41816 return (0,external_React_.createElement)(inserter_listbox, null, (0,external_React_.createElement)("div", null, showMostUsedBlocks && !!suggestedItems.length && (0,external_React_.createElement)(panel, { 41817 title: (0,external_wp_i18n_namespaceObject._x)('Most used', 'blocks') 41818 }, (0,external_React_.createElement)(block_types_list, { 41819 items: suggestedItems, 41820 onSelect: onSelectItem, 41821 onHover: onHover, 41822 label: (0,external_wp_i18n_namespaceObject._x)('Most used', 'blocks') 41823 })), currentlyRenderedCategories.map(category => { 41824 const categoryItems = itemsPerCategory[category.slug]; 41825 if (!categoryItems || !categoryItems.length) { 41826 return null; 41827 } 41828 return (0,external_React_.createElement)(panel, { 41829 key: category.slug, 41830 title: category.title, 41831 icon: category.icon 41832 }, (0,external_React_.createElement)(block_types_list, { 41833 items: categoryItems, 41834 onSelect: onSelectItem, 41835 onHover: onHover, 41836 label: category.title 41837 })); 41838 }), didRenderAllCategories && uncategorizedItems.length > 0 && (0,external_React_.createElement)(panel, { 41839 className: "block-editor-inserter__uncategorized-blocks-panel", 41840 title: (0,external_wp_i18n_namespaceObject.__)('Uncategorized') 41841 }, (0,external_React_.createElement)(block_types_list, { 41842 items: uncategorizedItems, 41843 onSelect: onSelectItem, 41844 onHover: onHover, 41845 label: (0,external_wp_i18n_namespaceObject.__)('Uncategorized') 41846 })), currentlyRenderedCollections.map(([namespace, collection]) => { 41847 const collectionItems = itemsPerCollection[namespace]; 41848 if (!collectionItems || !collectionItems.length) { 41849 return null; 41850 } 41851 return (0,external_React_.createElement)(panel, { 41852 key: namespace, 41853 title: collection.title, 41854 icon: collection.icon 41855 }, (0,external_React_.createElement)(block_types_list, { 41856 items: collectionItems, 41857 onSelect: onSelectItem, 41858 onHover: onHover, 41859 label: collection.title 41860 })); 41861 }))); 41862 } 41863 /* harmony default export */ const block_types_tab = (BlockTypesTab); 41864 41865 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.js 41866 41867 /** 41868 * WordPress dependencies 41869 */ 41870 41871 41872 function PatternCategoriesList({ 41873 selectedCategory, 41874 patternCategories, 41875 onClickCategory 41876 }) { 41877 const baseClassName = 'block-editor-block-patterns-explorer__sidebar'; 41878 return (0,external_React_.createElement)("div", { 41879 className: `$baseClassName}__categories-list` 41880 }, patternCategories.map(({ 41881 name, 41882 label 41883 }) => { 41884 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 41885 key: name, 41886 label: label, 41887 className: `$baseClassName}__categories-list__item`, 41888 isPressed: selectedCategory === name, 41889 onClick: () => { 41890 onClickCategory(name); 41891 } 41892 }, label); 41893 })); 41894 } 41895 function PatternsExplorerSearch({ 41896 searchValue, 41897 setSearchValue 41898 }) { 41899 const baseClassName = 'block-editor-block-patterns-explorer__search'; 41900 return (0,external_React_.createElement)("div", { 41901 className: baseClassName 41902 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.SearchControl, { 41903 __nextHasNoMarginBottom: true, 41904 onChange: setSearchValue, 41905 value: searchValue, 41906 label: (0,external_wp_i18n_namespaceObject.__)('Search for patterns'), 41907 placeholder: (0,external_wp_i18n_namespaceObject.__)('Search') 41908 })); 41909 } 41910 function PatternExplorerSidebar({ 41911 selectedCategory, 41912 patternCategories, 41913 onClickCategory, 41914 searchValue, 41915 setSearchValue 41916 }) { 41917 const baseClassName = 'block-editor-block-patterns-explorer__sidebar'; 41918 return (0,external_React_.createElement)("div", { 41919 className: baseClassName 41920 }, (0,external_React_.createElement)(PatternsExplorerSearch, { 41921 searchValue: searchValue, 41922 setSearchValue: setSearchValue 41923 }), !searchValue && (0,external_React_.createElement)(PatternCategoriesList, { 41924 selectedCategory: selectedCategory, 41925 patternCategories: patternCategories, 41926 onClickCategory: onClickCategory 41927 })); 41928 } 41929 /* harmony default export */ const pattern_explorer_sidebar = (PatternExplorerSidebar); 41930 41931 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-patterns-paging/index.js 41932 41933 /** 41934 * WordPress dependencies 41935 */ 41936 41937 41938 function Pagination({ 41939 currentPage, 41940 numPages, 41941 changePage, 41942 totalItems 41943 }) { 41944 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalVStack, { 41945 className: "block-editor-patterns__grid-pagination-wrapper" 41946 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalText, { 41947 variant: "muted" 41948 }, 41949 // translators: %s: Total number of patterns. 41950 (0,external_wp_i18n_namespaceObject.sprintf)( 41951 // translators: %s: Total number of patterns. 41952 (0,external_wp_i18n_namespaceObject._n)('%s item', '%s items', totalItems), totalItems)), numPages > 1 && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, { 41953 expanded: false, 41954 spacing: 3, 41955 justify: "flex-start", 41956 className: "block-editor-patterns__grid-pagination" 41957 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, { 41958 expanded: false, 41959 spacing: 1, 41960 className: "block-editor-patterns__grid-pagination-previous" 41961 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 41962 variant: "tertiary", 41963 onClick: () => changePage(1), 41964 disabled: currentPage === 1, 41965 "aria-label": (0,external_wp_i18n_namespaceObject.__)('First page') 41966 }, (0,external_React_.createElement)("span", null, "\xAB")), (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 41967 variant: "tertiary", 41968 onClick: () => changePage(currentPage - 1), 41969 disabled: currentPage === 1, 41970 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Previous page') 41971 }, (0,external_React_.createElement)("span", null, "\u2039"))), (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalText, { 41972 variant: "muted" 41973 }, (0,external_wp_i18n_namespaceObject.sprintf)( 41974 // translators: %1$s: Current page number, %2$s: Total number of pages. 41975 (0,external_wp_i18n_namespaceObject._x)('%1$s of %2$s', 'paging'), currentPage, numPages)), (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, { 41976 expanded: false, 41977 spacing: 1, 41978 className: "block-editor-patterns__grid-pagination-next" 41979 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 41980 variant: "tertiary", 41981 onClick: () => changePage(currentPage + 1), 41982 disabled: currentPage === numPages, 41983 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Next page') 41984 }, (0,external_React_.createElement)("span", null, "\u203A")), (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 41985 variant: "tertiary", 41986 onClick: () => changePage(numPages), 41987 disabled: currentPage === numPages, 41988 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Last page'), 41989 size: "default" 41990 }, (0,external_React_.createElement)("span", null, "\xBB"))))); 41991 } 41992 41993 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-patterns-list/index.js 41994 41995 /** 41996 * External dependencies 41997 */ 41998 41999 42000 /** 42001 * WordPress dependencies 42002 */ 42003 42004 42005 42006 42007 42008 42009 /** 42010 * Internal dependencies 42011 */ 42012 42013 42014 42015 42016 42017 const { 42018 CompositeV2: block_patterns_list_Composite, 42019 CompositeItemV2: block_patterns_list_CompositeItem, 42020 useCompositeStoreV2: block_patterns_list_useCompositeStore 42021 } = unlock(external_wp_components_namespaceObject.privateApis); 42022 const WithToolTip = ({ 42023 showTooltip, 42024 title, 42025 children 42026 }) => { 42027 if (showTooltip) { 42028 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Tooltip, { 42029 text: title 42030 }, children); 42031 } 42032 return (0,external_React_.createElement)(external_React_.Fragment, null, children); 42033 }; 42034 function BlockPattern({ 42035 id, 42036 isDraggable, 42037 pattern, 42038 onClick, 42039 onHover, 42040 showTooltip 42041 }) { 42042 const [isDragging, setIsDragging] = (0,external_wp_element_namespaceObject.useState)(false); 42043 const { 42044 blocks, 42045 viewportWidth 42046 } = pattern; 42047 const instanceId = (0,external_wp_compose_namespaceObject.useInstanceId)(BlockPattern); 42048 const descriptionId = `block-editor-block-patterns-list__item-description-$instanceId}`; 42049 return (0,external_React_.createElement)(inserter_draggable_blocks, { 42050 isEnabled: isDraggable, 42051 blocks: blocks, 42052 pattern: pattern 42053 }, ({ 42054 draggable, 42055 onDragStart, 42056 onDragEnd 42057 }) => (0,external_React_.createElement)("div", { 42058 className: "block-editor-block-patterns-list__list-item", 42059 draggable: draggable, 42060 onDragStart: event => { 42061 setIsDragging(true); 42062 if (onDragStart) { 42063 onHover?.(null); 42064 onDragStart(event); 42065 } 42066 }, 42067 onDragEnd: event => { 42068 setIsDragging(false); 42069 if (onDragEnd) { 42070 onDragEnd(event); 42071 } 42072 } 42073 }, (0,external_React_.createElement)(WithToolTip, { 42074 showTooltip: showTooltip && !pattern.type !== INSERTER_PATTERN_TYPES.user, 42075 title: pattern.title 42076 }, (0,external_React_.createElement)(block_patterns_list_CompositeItem, { 42077 render: (0,external_React_.createElement)("div", { 42078 role: "option", 42079 "aria-label": pattern.title, 42080 "aria-describedby": pattern.description ? descriptionId : undefined, 42081 className: classnames_default()('block-editor-block-patterns-list__item', { 42082 'block-editor-block-patterns-list__list-item-synced': pattern.type === INSERTER_PATTERN_TYPES.user && !pattern.syncStatus 42083 }) 42084 }), 42085 id: id, 42086 onClick: () => { 42087 onClick(pattern, blocks); 42088 onHover?.(null); 42089 }, 42090 onMouseEnter: () => { 42091 if (isDragging) { 42092 return; 42093 } 42094 onHover?.(pattern); 42095 }, 42096 onMouseLeave: () => onHover?.(null) 42097 }, (0,external_React_.createElement)(block_preview, { 42098 blocks: blocks, 42099 viewportWidth: viewportWidth 42100 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, { 42101 className: "block-editor-patterns__pattern-details" 42102 }, pattern.type === INSERTER_PATTERN_TYPES.user && !pattern.syncStatus && (0,external_React_.createElement)("div", { 42103 className: "block-editor-patterns__pattern-icon-wrapper" 42104 }, (0,external_React_.createElement)(build_module_icon, { 42105 className: "block-editor-patterns__pattern-icon", 42106 icon: library_symbol 42107 })), (!showTooltip || pattern.type === INSERTER_PATTERN_TYPES.user) && (0,external_React_.createElement)("div", { 42108 className: "block-editor-block-patterns-list__item-title" 42109 }, pattern.title)), !!pattern.description && (0,external_React_.createElement)(external_wp_components_namespaceObject.VisuallyHidden, { 42110 id: descriptionId 42111 }, pattern.description))))); 42112 } 42113 function BlockPatternPlaceholder() { 42114 return (0,external_React_.createElement)("div", { 42115 className: "block-editor-block-patterns-list__item is-placeholder" 42116 }); 42117 } 42118 function BlockPatternsList({ 42119 isDraggable, 42120 blockPatterns, 42121 shownPatterns, 42122 onHover, 42123 onClickPattern, 42124 orientation, 42125 label = (0,external_wp_i18n_namespaceObject.__)('Block patterns'), 42126 showTitlesAsTooltip, 42127 pagingProps 42128 }, ref) { 42129 const compositeStore = block_patterns_list_useCompositeStore({ 42130 orientation 42131 }); 42132 const { 42133 setActiveId 42134 } = compositeStore; 42135 (0,external_wp_element_namespaceObject.useEffect)(() => { 42136 // We reset the active composite item whenever the 42137 // available patterns change, to make sure that 42138 // focus is put back to the start. 42139 setActiveId(undefined); 42140 }, [setActiveId, shownPatterns, blockPatterns]); 42141 return (0,external_React_.createElement)(block_patterns_list_Composite, { 42142 store: compositeStore, 42143 role: "listbox", 42144 className: "block-editor-block-patterns-list", 42145 "aria-label": label, 42146 ref: ref 42147 }, blockPatterns.map(pattern => { 42148 const isShown = shownPatterns.includes(pattern); 42149 return isShown ? (0,external_React_.createElement)(BlockPattern, { 42150 key: pattern.name, 42151 id: pattern.name, 42152 pattern: pattern, 42153 onClick: onClickPattern, 42154 onHover: onHover, 42155 isDraggable: isDraggable, 42156 showTooltip: showTitlesAsTooltip 42157 }) : (0,external_React_.createElement)(BlockPatternPlaceholder, { 42158 key: pattern.name 42159 }); 42160 }), pagingProps && (0,external_React_.createElement)(Pagination, { 42161 ...pagingProps 42162 })); 42163 } 42164 /* harmony default export */ const block_patterns_list = ((0,external_wp_element_namespaceObject.forwardRef)(BlockPatternsList)); 42165 42166 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/hooks/use-insertion-point.js 42167 /** 42168 * WordPress dependencies 42169 */ 42170 42171 42172 42173 42174 42175 42176 /** 42177 * Internal dependencies 42178 */ 42179 42180 42181 /** 42182 * @typedef WPInserterConfig 42183 * 42184 * @property {string=} rootClientId If set, insertion will be into the 42185 * block with this ID. 42186 * @property {number=} insertionIndex If set, insertion will be into this 42187 * explicit position. 42188 * @property {string=} clientId If set, insertion will be after the 42189 * block with this ID. 42190 * @property {boolean=} isAppender Whether the inserter is an appender 42191 * or not. 42192 * @property {Function=} onSelect Called after insertion. 42193 */ 42194 42195 /** 42196 * Returns the insertion point state given the inserter config. 42197 * 42198 * @param {WPInserterConfig} config Inserter Config. 42199 * @return {Array} Insertion Point State (rootClientID, onInsertBlocks and onToggle). 42200 */ 42201 function useInsertionPoint({ 42202 rootClientId = '', 42203 insertionIndex, 42204 clientId, 42205 isAppender, 42206 onSelect, 42207 shouldFocusBlock = true, 42208 selectBlockOnInsert = true 42209 }) { 42210 const { 42211 getSelectedBlock 42212 } = (0,external_wp_data_namespaceObject.useSelect)(store); 42213 const { 42214 destinationRootClientId, 42215 destinationIndex 42216 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 42217 const { 42218 getSelectedBlockClientId, 42219 getBlockRootClientId, 42220 getBlockIndex, 42221 getBlockOrder 42222 } = select(store); 42223 const selectedBlockClientId = getSelectedBlockClientId(); 42224 let _destinationRootClientId = rootClientId; 42225 let _destinationIndex; 42226 if (insertionIndex !== undefined) { 42227 // Insert into a specific index. 42228 _destinationIndex = insertionIndex; 42229 } else if (clientId) { 42230 // Insert after a specific client ID. 42231 _destinationIndex = getBlockIndex(clientId); 42232 } else if (!isAppender && selectedBlockClientId) { 42233 _destinationRootClientId = getBlockRootClientId(selectedBlockClientId); 42234 _destinationIndex = getBlockIndex(selectedBlockClientId) + 1; 42235 } else { 42236 // Insert at the end of the list. 42237 _destinationIndex = getBlockOrder(_destinationRootClientId).length; 42238 } 42239 return { 42240 destinationRootClientId: _destinationRootClientId, 42241 destinationIndex: _destinationIndex 42242 }; 42243 }, [rootClientId, insertionIndex, clientId, isAppender]); 42244 const { 42245 replaceBlocks, 42246 insertBlocks, 42247 showInsertionPoint, 42248 hideInsertionPoint 42249 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 42250 const onInsertBlocks = (0,external_wp_element_namespaceObject.useCallback)((blocks, meta, shouldForceFocusBlock = false) => { 42251 const selectedBlock = getSelectedBlock(); 42252 if (!isAppender && selectedBlock && (0,external_wp_blocks_namespaceObject.isUnmodifiedDefaultBlock)(selectedBlock)) { 42253 replaceBlocks(selectedBlock.clientId, blocks, null, shouldFocusBlock || shouldForceFocusBlock ? 0 : null, meta); 42254 } else { 42255 insertBlocks(blocks, destinationIndex, destinationRootClientId, selectBlockOnInsert, shouldFocusBlock || shouldForceFocusBlock ? 0 : null, meta); 42256 } 42257 const blockLength = Array.isArray(blocks) ? blocks.length : 1; 42258 const message = (0,external_wp_i18n_namespaceObject.sprintf)( 42259 // translators: %d: the name of the block that has been added 42260 (0,external_wp_i18n_namespaceObject._n)('%d block added.', '%d blocks added.', blockLength), blockLength); 42261 (0,external_wp_a11y_namespaceObject.speak)(message); 42262 if (onSelect) { 42263 onSelect(blocks); 42264 } 42265 }, [isAppender, getSelectedBlock, replaceBlocks, insertBlocks, destinationRootClientId, destinationIndex, onSelect, shouldFocusBlock, selectBlockOnInsert]); 42266 const onToggleInsertionPoint = (0,external_wp_element_namespaceObject.useCallback)(show => { 42267 if (show) { 42268 showInsertionPoint(destinationRootClientId, destinationIndex); 42269 } else { 42270 hideInsertionPoint(); 42271 } 42272 }, [showInsertionPoint, hideInsertionPoint, destinationRootClientId, destinationIndex]); 42273 return [destinationRootClientId, onInsertBlocks, onToggleInsertionPoint]; 42274 } 42275 /* harmony default export */ const use_insertion_point = (useInsertionPoint); 42276 42277 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/hooks/use-patterns-state.js 42278 /** 42279 * WordPress dependencies 42280 */ 42281 42282 42283 42284 42285 42286 42287 /** 42288 * Internal dependencies 42289 */ 42290 42291 42292 42293 /** 42294 * Retrieves the block patterns inserter state. 42295 * 42296 * @param {Function} onInsert function called when inserter a list of blocks. 42297 * @param {string=} rootClientId Insertion's root client ID. 42298 * 42299 * @return {Array} Returns the patterns state. (patterns, categories, onSelect handler) 42300 */ 42301 const usePatternsState = (onInsert, rootClientId) => { 42302 const { 42303 patternCategories, 42304 patterns, 42305 userPatternCategories 42306 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 42307 const { 42308 __experimentalGetAllowedPatterns, 42309 getSettings 42310 } = select(store); 42311 const { 42312 __experimentalUserPatternCategories, 42313 __experimentalBlockPatternCategories 42314 } = getSettings(); 42315 return { 42316 patterns: __experimentalGetAllowedPatterns(rootClientId), 42317 userPatternCategories: __experimentalUserPatternCategories, 42318 patternCategories: __experimentalBlockPatternCategories 42319 }; 42320 }, [rootClientId]); 42321 const allCategories = (0,external_wp_element_namespaceObject.useMemo)(() => { 42322 const categories = [...patternCategories]; 42323 userPatternCategories?.forEach(userCategory => { 42324 if (!categories.find(existingCategory => existingCategory.name === userCategory.name)) { 42325 categories.push(userCategory); 42326 } 42327 }); 42328 return categories; 42329 }, [patternCategories, userPatternCategories]); 42330 const { 42331 createSuccessNotice 42332 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_notices_namespaceObject.store); 42333 const onClickPattern = (0,external_wp_element_namespaceObject.useCallback)((pattern, blocks) => { 42334 const patternBlocks = pattern.type === INSERTER_PATTERN_TYPES.user && pattern.syncStatus !== 'unsynced' ? [(0,external_wp_blocks_namespaceObject.createBlock)('core/block', { 42335 ref: pattern.id 42336 })] : blocks; 42337 onInsert((patternBlocks !== null && patternBlocks !== void 0 ? patternBlocks : []).map(block => (0,external_wp_blocks_namespaceObject.cloneBlock)(block)), pattern.name); 42338 createSuccessNotice((0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: block pattern title. */ 42339 (0,external_wp_i18n_namespaceObject.__)('Block pattern "%s" inserted.'), pattern.title), { 42340 type: 'snackbar', 42341 id: 'block-pattern-inserted-notice' 42342 }); 42343 }, [createSuccessNotice, onInsert]); 42344 return [patterns, allCategories, onClickPattern]; 42345 }; 42346 /* harmony default export */ const use_patterns_state = (usePatternsState); 42347 42348 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/hooks/use-patterns-paging.js 42349 /** 42350 * WordPress dependencies 42351 */ 42352 42353 42354 42355 const PAGE_SIZE = 20; 42356 const INITIAL_INSERTER_RESULTS = 5; 42357 42358 /** 42359 * Supplies values needed to page the patterns list client side. 42360 * 42361 * @param {Array} currentCategoryPatterns An array of the current patterns to display. 42362 * @param {string} currentCategory The currently selected category. 42363 * @param {Object} scrollContainerRef Ref of container to to find scroll container for when moving between pages. 42364 * @param {string} currentFilter The currently search filter. 42365 * 42366 * @return {Object} Returns the relevant paging values. (totalItems, categoryPatternsList, numPages, changePage, currentPage) 42367 */ 42368 function usePatternsPaging(currentCategoryPatterns, currentCategory, scrollContainerRef, currentFilter = '') { 42369 const [currentPage, setCurrentPage] = (0,external_wp_element_namespaceObject.useState)(1); 42370 const previousCategory = (0,external_wp_compose_namespaceObject.usePrevious)(currentCategory); 42371 const previousFilter = (0,external_wp_compose_namespaceObject.usePrevious)(currentFilter); 42372 if ((previousCategory !== currentCategory || previousFilter !== currentFilter) && currentPage !== 1) { 42373 setCurrentPage(1); 42374 } 42375 const totalItems = currentCategoryPatterns.length; 42376 const pageIndex = currentPage - 1; 42377 const categoryPatterns = (0,external_wp_element_namespaceObject.useMemo)(() => { 42378 return currentCategoryPatterns.slice(pageIndex * PAGE_SIZE, pageIndex * PAGE_SIZE + PAGE_SIZE); 42379 }, [pageIndex, currentCategoryPatterns]); 42380 const categoryPatternsAsyncList = (0,external_wp_compose_namespaceObject.useAsyncList)(categoryPatterns, { 42381 step: INITIAL_INSERTER_RESULTS 42382 }); 42383 const numPages = Math.ceil(currentCategoryPatterns.length / PAGE_SIZE); 42384 const changePage = page => { 42385 const scrollContainer = (0,external_wp_dom_namespaceObject.getScrollContainer)(scrollContainerRef?.current); 42386 scrollContainer?.scrollTo(0, 0); 42387 setCurrentPage(page); 42388 }; 42389 (0,external_wp_element_namespaceObject.useEffect)(function scrollToTopOnCategoryChange() { 42390 const scrollContainer = (0,external_wp_dom_namespaceObject.getScrollContainer)(scrollContainerRef?.current); 42391 scrollContainer?.scrollTo(0, 0); 42392 }, [currentCategory, scrollContainerRef]); 42393 return { 42394 totalItems, 42395 categoryPatterns, 42396 categoryPatternsAsyncList, 42397 numPages, 42398 changePage, 42399 currentPage 42400 }; 42401 } 42402 42403 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/block-patterns-explorer/pattern-list.js 42404 42405 /** 42406 * WordPress dependencies 42407 */ 42408 42409 42410 42411 42412 42413 42414 /** 42415 * Internal dependencies 42416 */ 42417 42418 42419 42420 42421 42422 42423 42424 42425 function PatternsListHeader({ 42426 filterValue, 42427 filteredBlockPatternsLength 42428 }) { 42429 if (!filterValue) { 42430 return null; 42431 } 42432 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHeading, { 42433 level: 2, 42434 lineHeight: '48px', 42435 className: "block-editor-block-patterns-explorer__search-results-count" 42436 }, (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %d: number of patterns. */ 42437 (0,external_wp_i18n_namespaceObject._n)('%d pattern found', '%d patterns found', filteredBlockPatternsLength), filteredBlockPatternsLength)); 42438 } 42439 function PatternList({ 42440 searchValue, 42441 selectedCategory, 42442 patternCategories, 42443 rootClientId 42444 }) { 42445 const container = (0,external_wp_element_namespaceObject.useRef)(); 42446 const debouncedSpeak = (0,external_wp_compose_namespaceObject.useDebounce)(external_wp_a11y_namespaceObject.speak, 500); 42447 const [destinationRootClientId, onInsertBlocks] = use_insertion_point({ 42448 rootClientId, 42449 shouldFocusBlock: true 42450 }); 42451 const [patterns,, onClickPattern] = use_patterns_state(onInsertBlocks, destinationRootClientId); 42452 const registeredPatternCategories = (0,external_wp_element_namespaceObject.useMemo)(() => patternCategories.map(patternCategory => patternCategory.name), [patternCategories]); 42453 const filteredBlockPatterns = (0,external_wp_element_namespaceObject.useMemo)(() => { 42454 const filteredPatterns = patterns.filter(pattern => { 42455 if (selectedCategory === allPatternsCategory.name) { 42456 return true; 42457 } 42458 if (selectedCategory === myPatternsCategory.name && pattern.type === INSERTER_PATTERN_TYPES.user) { 42459 return true; 42460 } 42461 if (selectedCategory === 'uncategorized') { 42462 const hasKnownCategory = pattern.categories.some(category => registeredPatternCategories.includes(category)); 42463 return !pattern.categories?.length || !hasKnownCategory; 42464 } 42465 return pattern.categories?.includes(selectedCategory); 42466 }); 42467 if (!searchValue) { 42468 return filteredPatterns; 42469 } 42470 return searchItems(filteredPatterns, searchValue); 42471 }, [searchValue, patterns, selectedCategory, registeredPatternCategories]); 42472 42473 // Announce search results on change. 42474 (0,external_wp_element_namespaceObject.useEffect)(() => { 42475 if (!searchValue) { 42476 return; 42477 } 42478 const count = filteredBlockPatterns.length; 42479 const resultsFoundMessage = (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %d: number of results. */ 42480 (0,external_wp_i18n_namespaceObject._n)('%d result found.', '%d results found.', count), count); 42481 debouncedSpeak(resultsFoundMessage); 42482 }, [searchValue, debouncedSpeak, filteredBlockPatterns.length]); 42483 const pagingProps = usePatternsPaging(filteredBlockPatterns, selectedCategory, container); 42484 42485 // Reset page when search value changes. 42486 const [previousSearchValue, setPreviousSearchValue] = (0,external_wp_element_namespaceObject.useState)(searchValue); 42487 if (searchValue !== previousSearchValue) { 42488 setPreviousSearchValue(searchValue); 42489 pagingProps.changePage(1); 42490 } 42491 const hasItems = !!filteredBlockPatterns?.length; 42492 return (0,external_React_.createElement)("div", { 42493 className: "block-editor-block-patterns-explorer__list", 42494 ref: container 42495 }, (0,external_React_.createElement)(PatternsListHeader, { 42496 filterValue: searchValue, 42497 filteredBlockPatternsLength: filteredBlockPatterns.length 42498 }), (0,external_React_.createElement)(inserter_listbox, null, hasItems && (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(block_patterns_list, { 42499 shownPatterns: pagingProps.categoryPatternsAsyncList, 42500 blockPatterns: pagingProps.categoryPatterns, 42501 onClickPattern: onClickPattern, 42502 isDraggable: false 42503 }), (0,external_React_.createElement)(Pagination, { 42504 ...pagingProps 42505 })))); 42506 } 42507 /* harmony default export */ const pattern_list = (PatternList); 42508 42509 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/block-patterns-tab/use-pattern-categories.js 42510 /** 42511 * WordPress dependencies 42512 */ 42513 42514 42515 42516 42517 /** 42518 * Internal dependencies 42519 */ 42520 42521 42522 function hasRegisteredCategory(pattern, allCategories) { 42523 if (!pattern.categories || !pattern.categories.length) { 42524 return false; 42525 } 42526 return pattern.categories.some(cat => allCategories.some(category => category.name === cat)); 42527 } 42528 function usePatternCategories(rootClientId, sourceFilter = 'all') { 42529 const [patterns, allCategories] = use_patterns_state(undefined, rootClientId); 42530 const filteredPatterns = (0,external_wp_element_namespaceObject.useMemo)(() => sourceFilter === 'all' ? patterns : patterns.filter(pattern => !isPatternFiltered(pattern, sourceFilter)), [sourceFilter, patterns]); 42531 42532 // Remove any empty categories. 42533 const populatedCategories = (0,external_wp_element_namespaceObject.useMemo)(() => { 42534 const categories = allCategories.filter(category => filteredPatterns.some(pattern => pattern.categories?.includes(category.name))).sort((a, b) => a.label.localeCompare(b.label)); 42535 if (filteredPatterns.some(pattern => !hasRegisteredCategory(pattern, allCategories)) && !categories.find(category => category.name === 'uncategorized')) { 42536 categories.push({ 42537 name: 'uncategorized', 42538 label: (0,external_wp_i18n_namespaceObject._x)('Uncategorized') 42539 }); 42540 } 42541 if (filteredPatterns.some(pattern => pattern.type === INSERTER_PATTERN_TYPES.user)) { 42542 categories.unshift(myPatternsCategory); 42543 } 42544 if (filteredPatterns.length > 0) { 42545 categories.unshift({ 42546 name: allPatternsCategory.name, 42547 label: allPatternsCategory.label 42548 }); 42549 } 42550 (0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %d: number of categories . */ 42551 (0,external_wp_i18n_namespaceObject._n)('%d category button displayed.', '%d category buttons displayed.', categories.length), categories.length)); 42552 return categories; 42553 }, [allCategories, filteredPatterns]); 42554 return populatedCategories; 42555 } 42556 42557 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/block-patterns-explorer/index.js 42558 42559 /** 42560 * WordPress dependencies 42561 */ 42562 42563 42564 42565 42566 /** 42567 * Internal dependencies 42568 */ 42569 42570 42571 42572 function PatternsExplorer({ 42573 initialCategory, 42574 rootClientId 42575 }) { 42576 const [searchValue, setSearchValue] = (0,external_wp_element_namespaceObject.useState)(''); 42577 const [patternSourceFilter, setPatternSourceFilter] = (0,external_wp_element_namespaceObject.useState)('all'); 42578 const [selectedCategory, setSelectedCategory] = (0,external_wp_element_namespaceObject.useState)(initialCategory?.name); 42579 const patternCategories = usePatternCategories(rootClientId, patternSourceFilter); 42580 return (0,external_React_.createElement)("div", { 42581 className: "block-editor-block-patterns-explorer" 42582 }, (0,external_React_.createElement)(pattern_explorer_sidebar, { 42583 selectedCategory: selectedCategory, 42584 patternCategories: patternCategories, 42585 onClickCategory: setSelectedCategory, 42586 searchValue: searchValue, 42587 setSearchValue: setSearchValue, 42588 patternSourceFilter: patternSourceFilter, 42589 setPatternSourceFilter: setPatternSourceFilter 42590 }), (0,external_React_.createElement)(pattern_list, { 42591 searchValue: searchValue, 42592 selectedCategory: selectedCategory, 42593 patternCategories: patternCategories, 42594 patternSourceFilter: patternSourceFilter, 42595 rootClientId: rootClientId 42596 })); 42597 } 42598 function PatternsExplorerModal({ 42599 onModalClose, 42600 ...restProps 42601 }) { 42602 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Modal, { 42603 title: (0,external_wp_i18n_namespaceObject.__)('Patterns'), 42604 onRequestClose: onModalClose, 42605 isFullScreen: true 42606 }, (0,external_React_.createElement)(PatternsExplorer, { 42607 ...restProps 42608 })); 42609 } 42610 /* harmony default export */ const block_patterns_explorer = (PatternsExplorerModal); 42611 42612 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/mobile-tab-navigation.js 42613 42614 /** 42615 * WordPress dependencies 42616 */ 42617 42618 42619 42620 function ScreenHeader({ 42621 title 42622 }) { 42623 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalVStack, { 42624 spacing: 0 42625 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalView, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalSpacer, { 42626 marginBottom: 0, 42627 paddingX: 4, 42628 paddingY: 3 42629 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, { 42630 spacing: 2 42631 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalNavigatorBackButton, { 42632 style: 42633 // TODO: This style override is also used in ToolsPanelHeader. 42634 // It should be supported out-of-the-box by Button. 42635 { 42636 minWidth: 24, 42637 padding: 0 42638 }, 42639 icon: (0,external_wp_i18n_namespaceObject.isRTL)() ? chevron_right : chevron_left, 42640 isSmall: true, 42641 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Navigate to the previous view') 42642 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalSpacer, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHeading, { 42643 level: 5 42644 }, title)))))); 42645 } 42646 function MobileTabNavigation({ 42647 categories, 42648 children 42649 }) { 42650 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalNavigatorProvider, { 42651 initialPath: "/", 42652 className: "block-editor-inserter__mobile-tab-navigation" 42653 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalNavigatorScreen, { 42654 path: "/" 42655 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalItemGroup, null, categories.map(category => (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalNavigatorButton, { 42656 key: category.name, 42657 path: `/category/$category.name}`, 42658 as: external_wp_components_namespaceObject.__experimentalItem, 42659 isAction: true 42660 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexBlock, null, category.label), (0,external_React_.createElement)(build_module_icon, { 42661 icon: (0,external_wp_i18n_namespaceObject.isRTL)() ? chevron_left : chevron_right 42662 })))))), categories.map(category => (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalNavigatorScreen, { 42663 key: category.name, 42664 path: `/category/$category.name}` 42665 }, (0,external_React_.createElement)(ScreenHeader, { 42666 title: (0,external_wp_i18n_namespaceObject.__)('Back') 42667 }), children(category)))); 42668 } 42669 42670 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/block-patterns-tab/patterns-filter.js 42671 42672 /** 42673 * WordPress dependencies 42674 */ 42675 42676 42677 42678 42679 42680 /** 42681 * Internal dependencies 42682 */ 42683 42684 const getShouldDisableSyncFilter = sourceFilter => sourceFilter !== 'all'; 42685 const getShouldDisableNonUserSources = category => { 42686 return category.name === myPatternsCategory.name; 42687 }; 42688 function PatternsFilter({ 42689 setPatternSyncFilter, 42690 setPatternSourceFilter, 42691 patternSyncFilter, 42692 patternSourceFilter, 42693 scrollContainerRef, 42694 category 42695 }) { 42696 // If the category is `myPatterns` then we need to set the source filter to `user`, but 42697 // we do this by deriving from props rather than calling setPatternSourceFilter otherwise 42698 // the user may be confused when switching to another category if the haven't explicity set 42699 // this filter themselves. 42700 const currentPatternSourceFilter = category.name === myPatternsCategory.name ? INSERTER_PATTERN_TYPES.user : patternSourceFilter; 42701 42702 // We need to disable the sync filter option if the source filter is not 'all' or 'user' 42703 // otherwise applying them will just result in no patterns being shown. 42704 const shouldDisableSyncFilter = getShouldDisableSyncFilter(currentPatternSourceFilter); 42705 42706 // We also need to disable the directory and theme source filter options if the category 42707 // is `myPatterns` otherwise applying them will also just result in no patterns being shown. 42708 const shouldDisableNonUserSources = getShouldDisableNonUserSources(category); 42709 const patternSyncMenuOptions = (0,external_wp_element_namespaceObject.useMemo)(() => [{ 42710 value: 'all', 42711 label: (0,external_wp_i18n_namespaceObject._x)('All', 'patterns') 42712 }, { 42713 value: INSERTER_SYNC_TYPES.full, 42714 label: (0,external_wp_i18n_namespaceObject._x)('Synced', 'patterns'), 42715 disabled: shouldDisableSyncFilter 42716 }, { 42717 value: INSERTER_SYNC_TYPES.unsynced, 42718 label: (0,external_wp_i18n_namespaceObject._x)('Not synced', 'patterns'), 42719 disabled: shouldDisableSyncFilter 42720 }], [shouldDisableSyncFilter]); 42721 const patternSourceMenuOptions = (0,external_wp_element_namespaceObject.useMemo)(() => [{ 42722 value: 'all', 42723 label: (0,external_wp_i18n_namespaceObject._x)('All', 'patterns'), 42724 disabled: shouldDisableNonUserSources 42725 }, { 42726 value: INSERTER_PATTERN_TYPES.directory, 42727 label: (0,external_wp_i18n_namespaceObject.__)('Pattern Directory'), 42728 disabled: shouldDisableNonUserSources 42729 }, { 42730 value: INSERTER_PATTERN_TYPES.theme, 42731 label: (0,external_wp_i18n_namespaceObject.__)('Theme & Plugins'), 42732 disabled: shouldDisableNonUserSources 42733 }, { 42734 value: INSERTER_PATTERN_TYPES.user, 42735 label: (0,external_wp_i18n_namespaceObject.__)('User') 42736 }], [shouldDisableNonUserSources]); 42737 function handleSetSourceFilterChange(newSourceFilter) { 42738 setPatternSourceFilter(newSourceFilter); 42739 if (getShouldDisableSyncFilter(newSourceFilter)) { 42740 setPatternSyncFilter('all'); 42741 } 42742 } 42743 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.DropdownMenu, { 42744 popoverProps: { 42745 placement: 'right-end' 42746 }, 42747 label: "Filter patterns", 42748 icon: (0,external_React_.createElement)(build_module_icon, { 42749 icon: (0,external_React_.createElement)(external_wp_components_namespaceObject.SVG, { 42750 width: "24", 42751 height: "24", 42752 viewBox: "0 0 24 24", 42753 fill: "none", 42754 xmlns: "http://www.w3.org/2000/svg" 42755 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Path, { 42756 d: "M10 17.5H14V16H10V17.5ZM6 6V7.5H18V6H6ZM8 12.5H16V11H8V12.5Z", 42757 fill: "#1E1E1E" 42758 })) 42759 }) 42760 }, () => (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuGroup, { 42761 label: (0,external_wp_i18n_namespaceObject.__)('Source') 42762 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItemsChoice, { 42763 choices: patternSourceMenuOptions, 42764 onSelect: value => { 42765 handleSetSourceFilterChange(value); 42766 scrollContainerRef.current?.scrollTo(0, 0); 42767 }, 42768 value: currentPatternSourceFilter 42769 })), (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuGroup, { 42770 label: (0,external_wp_i18n_namespaceObject.__)('Type') 42771 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItemsChoice, { 42772 choices: patternSyncMenuOptions, 42773 onSelect: value => { 42774 setPatternSyncFilter(value); 42775 scrollContainerRef.current?.scrollTo(0, 0); 42776 }, 42777 value: patternSyncFilter 42778 })), (0,external_React_.createElement)("div", { 42779 className: "block-editor-tool-selector__help" 42780 }, (0,external_wp_element_namespaceObject.createInterpolateElement)((0,external_wp_i18n_namespaceObject.__)('Patterns are available from the <Link>WordPress.org Pattern Directory</Link>, bundled in the active theme, or created by users on this site. Only patterns created on this site can be synced.'), { 42781 Link: (0,external_React_.createElement)(external_wp_components_namespaceObject.ExternalLink, { 42782 href: (0,external_wp_i18n_namespaceObject.__)('https://wordpress.org/patterns/') 42783 }) 42784 }))))); 42785 } 42786 42787 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/block-patterns-tab/pattern-category-previews.js 42788 42789 /** 42790 * WordPress dependencies 42791 */ 42792 42793 42794 42795 42796 /** 42797 * Internal dependencies 42798 */ 42799 42800 42801 42802 42803 42804 42805 const pattern_category_previews_noop = () => {}; 42806 function PatternCategoryPreviews({ 42807 rootClientId, 42808 onInsert, 42809 onHover = pattern_category_previews_noop, 42810 category, 42811 showTitlesAsTooltip 42812 }) { 42813 const [allPatterns,, onClickPattern] = use_patterns_state(onInsert, rootClientId); 42814 const [patternSyncFilter, setPatternSyncFilter] = (0,external_wp_element_namespaceObject.useState)('all'); 42815 const [patternSourceFilter, setPatternSourceFilter] = (0,external_wp_element_namespaceObject.useState)('all'); 42816 const availableCategories = usePatternCategories(rootClientId, patternSourceFilter); 42817 const scrollContainerRef = (0,external_wp_element_namespaceObject.useRef)(); 42818 const currentCategoryPatterns = (0,external_wp_element_namespaceObject.useMemo)(() => allPatterns.filter(pattern => { 42819 if (isPatternFiltered(pattern, patternSourceFilter, patternSyncFilter)) { 42820 return false; 42821 } 42822 if (category.name === allPatternsCategory.name) { 42823 return true; 42824 } 42825 if (category.name === myPatternsCategory.name && pattern.type === INSERTER_PATTERN_TYPES.user) { 42826 return true; 42827 } 42828 if (category.name === 'uncategorized') { 42829 // The uncategorized category should show all the patterns without any category... 42830 if (!pattern.categories) { 42831 return true; 42832 } 42833 42834 // ...or with no available category. 42835 return !pattern.categories.some(catName => availableCategories.some(c => c.name === catName)); 42836 } 42837 return pattern.categories?.includes(category.name); 42838 }), [allPatterns, availableCategories, category.name, patternSourceFilter, patternSyncFilter]); 42839 const pagingProps = usePatternsPaging(currentCategoryPatterns, category, scrollContainerRef); 42840 const { 42841 changePage 42842 } = pagingProps; 42843 42844 // Hide block pattern preview on unmount. 42845 // eslint-disable-next-line react-hooks/exhaustive-deps 42846 (0,external_wp_element_namespaceObject.useEffect)(() => () => onHover(null), []); 42847 const onSetPatternSyncFilter = (0,external_wp_element_namespaceObject.useCallback)(value => { 42848 setPatternSyncFilter(value); 42849 changePage(1); 42850 }, [setPatternSyncFilter, changePage]); 42851 const onSetPatternSourceFilter = (0,external_wp_element_namespaceObject.useCallback)(value => { 42852 setPatternSourceFilter(value); 42853 changePage(1); 42854 }, [setPatternSourceFilter, changePage]); 42855 return (0,external_React_.createElement)("div", { 42856 className: "block-editor-inserter__patterns-category-panel" 42857 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalVStack, { 42858 spacing: 2, 42859 className: "block-editor-inserter__patterns-category-panel-header" 42860 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexBlock, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHeading, { 42861 level: 4, 42862 as: "div" 42863 }, category.label)), (0,external_React_.createElement)(PatternsFilter, { 42864 patternSyncFilter: patternSyncFilter, 42865 patternSourceFilter: patternSourceFilter, 42866 setPatternSyncFilter: onSetPatternSyncFilter, 42867 setPatternSourceFilter: onSetPatternSourceFilter, 42868 scrollContainerRef: scrollContainerRef, 42869 category: category 42870 })), !currentCategoryPatterns.length && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalText, { 42871 variant: "muted", 42872 className: "block-editor-inserter__patterns-category-no-results" 42873 }, (0,external_wp_i18n_namespaceObject.__)('No results found'))), currentCategoryPatterns.length > 0 && (0,external_React_.createElement)(block_patterns_list, { 42874 ref: scrollContainerRef, 42875 shownPatterns: pagingProps.categoryPatternsAsyncList, 42876 blockPatterns: pagingProps.categoryPatterns, 42877 onClickPattern: onClickPattern, 42878 onHover: onHover, 42879 label: category.label, 42880 orientation: "vertical", 42881 category: category.name, 42882 isDraggable: true, 42883 showTitlesAsTooltip: showTitlesAsTooltip, 42884 patternFilter: patternSourceFilter, 42885 pagingProps: pagingProps 42886 })); 42887 } 42888 42889 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/block-patterns-tab/index.js 42890 42891 /** 42892 * WordPress dependencies 42893 */ 42894 42895 42896 42897 42898 42899 42900 /** 42901 * Internal dependencies 42902 */ 42903 42904 42905 42906 42907 function BlockPatternsTab({ 42908 onSelectCategory, 42909 selectedCategory, 42910 onInsert, 42911 rootClientId 42912 }) { 42913 const [showPatternsExplorer, setShowPatternsExplorer] = (0,external_wp_element_namespaceObject.useState)(false); 42914 const categories = usePatternCategories(rootClientId); 42915 const initialCategory = selectedCategory || categories[0]; 42916 const isMobile = (0,external_wp_compose_namespaceObject.useViewportMatch)('medium', '<'); 42917 return (0,external_React_.createElement)(external_React_.Fragment, null, !isMobile && (0,external_React_.createElement)("div", { 42918 className: "block-editor-inserter__block-patterns-tabs-container" 42919 }, (0,external_React_.createElement)("nav", { 42920 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Block pattern categories'), 42921 className: "block-editor-inserter__block-patterns-tabs" 42922 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalItemGroup, { 42923 role: "list" 42924 }, categories.map(category => (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalItem, { 42925 role: "listitem", 42926 key: category.name, 42927 onClick: () => onSelectCategory(category), 42928 className: category === selectedCategory ? 'block-editor-inserter__patterns-category block-editor-inserter__patterns-selected-category' : 'block-editor-inserter__patterns-category', 42929 "aria-label": category.label, 42930 "aria-current": category === selectedCategory ? 'true' : undefined 42931 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexBlock, null, category.label), (0,external_React_.createElement)(build_module_icon, { 42932 icon: (0,external_wp_i18n_namespaceObject.isRTL)() ? chevron_left : chevron_right 42933 })))), (0,external_React_.createElement)("div", { 42934 role: "listitem" 42935 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 42936 className: "block-editor-inserter__patterns-explore-button", 42937 onClick: () => setShowPatternsExplorer(true), 42938 variant: "secondary" 42939 }, (0,external_wp_i18n_namespaceObject.__)('Explore all patterns')))))), isMobile && (0,external_React_.createElement)(MobileTabNavigation, { 42940 categories: categories 42941 }, category => (0,external_React_.createElement)(PatternCategoryPreviews, { 42942 key: category.name, 42943 onInsert: onInsert, 42944 rootClientId: rootClientId, 42945 category: category, 42946 showTitlesAsTooltip: false 42947 })), showPatternsExplorer && (0,external_React_.createElement)(block_patterns_explorer, { 42948 initialCategory: initialCategory, 42949 patternCategories: categories, 42950 onModalClose: () => setShowPatternsExplorer(false), 42951 rootClientId: rootClientId 42952 })); 42953 } 42954 /* harmony default export */ const block_patterns_tab = (BlockPatternsTab); 42955 42956 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/block-patterns-tab/pattern-category-preview-panel.js 42957 42958 /** 42959 * WordPress dependencies 42960 */ 42961 42962 42963 42964 /** 42965 * Internal dependencies 42966 */ 42967 42968 42969 function PatternCategoryPreviewPanel({ 42970 rootClientId, 42971 onInsert, 42972 onHover, 42973 category, 42974 showTitlesAsTooltip, 42975 patternFilter 42976 }) { 42977 const container = (0,external_wp_element_namespaceObject.useRef)(); 42978 (0,external_wp_element_namespaceObject.useEffect)(() => { 42979 const timeout = setTimeout(() => { 42980 const [firstTabbable] = external_wp_dom_namespaceObject.focus.tabbable.find(container.current); 42981 firstTabbable?.focus(); 42982 }); 42983 return () => clearTimeout(timeout); 42984 }, [category]); 42985 return (0,external_React_.createElement)("div", { 42986 ref: container, 42987 className: "block-editor-inserter__patterns-category-dialog" 42988 }, (0,external_React_.createElement)(PatternCategoryPreviews, { 42989 key: category.name, 42990 rootClientId: rootClientId, 42991 onInsert: onInsert, 42992 onHover: onHover, 42993 category: category, 42994 showTitlesAsTooltip: showTitlesAsTooltip, 42995 patternFilter: patternFilter 42996 })); 42997 } 42998 42999 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/media-tab/hooks.js 43000 /** 43001 * WordPress dependencies 43002 */ 43003 43004 43005 43006 /** 43007 * Internal dependencies 43008 */ 43009 43010 43011 43012 /** @typedef {import('../../../store/actions').InserterMediaRequest} InserterMediaRequest */ 43013 /** @typedef {import('../../../store/actions').InserterMediaItem} InserterMediaItem */ 43014 43015 /** 43016 * Fetches media items based on the provided category. 43017 * Each media category is responsible for providing a `fetch` function. 43018 * 43019 * @param {Object} category The media category to fetch results for. 43020 * @param {InserterMediaRequest} query The query args to use for the request. 43021 * @return {InserterMediaItem[]} The media results. 43022 */ 43023 function useMediaResults(category, query = {}) { 43024 const [mediaList, setMediaList] = (0,external_wp_element_namespaceObject.useState)(); 43025 const [isLoading, setIsLoading] = (0,external_wp_element_namespaceObject.useState)(false); 43026 // We need to keep track of the last request made because 43027 // multiple request can be fired without knowing the order 43028 // of resolution, and we need to ensure we are showing 43029 // the results of the last request. 43030 // In the future we could use AbortController to cancel previous 43031 // requests, but we don't for now as it involves adding support 43032 // for this to `core-data` package. 43033 const lastRequest = (0,external_wp_element_namespaceObject.useRef)(); 43034 (0,external_wp_element_namespaceObject.useEffect)(() => { 43035 (async () => { 43036 const key = JSON.stringify({ 43037 category: category.name, 43038 ...query 43039 }); 43040 lastRequest.current = key; 43041 setIsLoading(true); 43042 setMediaList([]); // Empty the previous results. 43043 const _media = await category.fetch?.(query); 43044 if (key === lastRequest.current) { 43045 setMediaList(_media); 43046 setIsLoading(false); 43047 } 43048 })(); 43049 }, [category.name, ...Object.values(query)]); 43050 return { 43051 mediaList, 43052 isLoading 43053 }; 43054 } 43055 function useMediaCategories(rootClientId) { 43056 const [categories, setCategories] = (0,external_wp_element_namespaceObject.useState)([]); 43057 const inserterMediaCategories = (0,external_wp_data_namespaceObject.useSelect)(select => unlock(select(store)).getInserterMediaCategories(), []); 43058 const { 43059 canInsertImage, 43060 canInsertVideo, 43061 canInsertAudio 43062 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 43063 const { 43064 canInsertBlockType 43065 } = select(store); 43066 return { 43067 canInsertImage: canInsertBlockType('core/image', rootClientId), 43068 canInsertVideo: canInsertBlockType('core/video', rootClientId), 43069 canInsertAudio: canInsertBlockType('core/audio', rootClientId) 43070 }; 43071 }, [rootClientId]); 43072 (0,external_wp_element_namespaceObject.useEffect)(() => { 43073 (async () => { 43074 const _categories = []; 43075 // If `inserterMediaCategories` is not defined in 43076 // block editor settings, do not show any media categories. 43077 if (!inserterMediaCategories) { 43078 return; 43079 } 43080 // Loop through categories to check if they have at least one media item. 43081 const categoriesHaveMedia = new Map(await Promise.all(inserterMediaCategories.map(async category => { 43082 // Some sources are external and we don't need to make a request. 43083 if (category.isExternalResource) { 43084 return [category.name, true]; 43085 } 43086 let results = []; 43087 try { 43088 results = await category.fetch({ 43089 per_page: 1 43090 }); 43091 } catch (e) { 43092 // If the request fails, we shallow the error and just don't show 43093 // the category, in order to not break the media tab. 43094 } 43095 return [category.name, !!results.length]; 43096 }))); 43097 // We need to filter out categories that don't have any media items or 43098 // whose corresponding block type is not allowed to be inserted, based 43099 // on the category's `mediaType`. 43100 const canInsertMediaType = { 43101 image: canInsertImage, 43102 video: canInsertVideo, 43103 audio: canInsertAudio 43104 }; 43105 inserterMediaCategories.forEach(category => { 43106 if (canInsertMediaType[category.mediaType] && categoriesHaveMedia.get(category.name)) { 43107 _categories.push(category); 43108 } 43109 }); 43110 if (!!_categories.length) { 43111 setCategories(_categories); 43112 } 43113 })(); 43114 }, [canInsertImage, canInsertVideo, canInsertAudio, inserterMediaCategories]); 43115 return categories; 43116 } 43117 43118 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/external.js 43119 43120 /** 43121 * WordPress dependencies 43122 */ 43123 43124 const external = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 43125 xmlns: "http://www.w3.org/2000/svg", 43126 viewBox: "0 0 24 24" 43127 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 43128 d: "M19.5 4.5h-7V6h4.44l-5.97 5.97 1.06 1.06L18 7.06v4.44h1.5v-7Zm-13 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-3H17v3a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h3V5.5h-3Z" 43129 })); 43130 /* harmony default export */ const library_external = (external); 43131 43132 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/media-tab/utils.js 43133 43134 /** 43135 * WordPress dependencies 43136 */ 43137 43138 const mediaTypeTag = { 43139 image: 'img', 43140 video: 'video', 43141 audio: 'audio' 43142 }; 43143 43144 /** @typedef {import('./hooks').InserterMediaItem} InserterMediaItem */ 43145 43146 /** 43147 * Creates a block and a preview element from a media object. 43148 * 43149 * @param {InserterMediaItem} media The media object to create the block from. 43150 * @param {('image'|'audio'|'video')} mediaType The media type to create the block for. 43151 * @return {[WPBlock, JSX.Element]} An array containing the block and the preview element. 43152 */ 43153 function getBlockAndPreviewFromMedia(media, mediaType) { 43154 // Add the common attributes between the different media types. 43155 const attributes = { 43156 id: media.id || undefined, 43157 caption: media.caption || undefined 43158 }; 43159 const mediaSrc = media.url; 43160 const alt = media.alt || undefined; 43161 if (mediaType === 'image') { 43162 attributes.url = mediaSrc; 43163 attributes.alt = alt; 43164 } else if (['video', 'audio'].includes(mediaType)) { 43165 attributes.src = mediaSrc; 43166 } 43167 const PreviewTag = mediaTypeTag[mediaType]; 43168 const preview = (0,external_React_.createElement)(PreviewTag, { 43169 src: media.previewUrl || mediaSrc, 43170 alt: alt, 43171 controls: mediaType === 'audio' ? true : undefined, 43172 inert: "true", 43173 onError: ({ 43174 currentTarget 43175 }) => { 43176 // Fall back to the media source if the preview cannot be loaded. 43177 if (currentTarget.src === media.previewUrl) { 43178 currentTarget.src = mediaSrc; 43179 } 43180 } 43181 }); 43182 return [(0,external_wp_blocks_namespaceObject.createBlock)(`core/$mediaType}`, attributes), preview]; 43183 } 43184 43185 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/media-tab/media-preview.js 43186 43187 /** 43188 * External dependencies 43189 */ 43190 43191 43192 /** 43193 * WordPress dependencies 43194 */ 43195 43196 43197 43198 43199 43200 43201 43202 43203 43204 /** 43205 * Internal dependencies 43206 */ 43207 43208 43209 43210 43211 const ALLOWED_MEDIA_TYPES = ['image']; 43212 const MAXIMUM_TITLE_LENGTH = 25; 43213 const MEDIA_OPTIONS_POPOVER_PROPS = { 43214 position: 'bottom left', 43215 className: 'block-editor-inserter__media-list__item-preview-options__popover' 43216 }; 43217 const { 43218 CompositeItemV2: media_preview_CompositeItem 43219 } = unlock(external_wp_components_namespaceObject.privateApis); 43220 function MediaPreviewOptions({ 43221 category, 43222 media 43223 }) { 43224 if (!category.getReportUrl) { 43225 return null; 43226 } 43227 const reportUrl = category.getReportUrl(media); 43228 return (0,external_React_.createElement)(external_wp_components_namespaceObject.DropdownMenu, { 43229 className: "block-editor-inserter__media-list__item-preview-options", 43230 label: (0,external_wp_i18n_namespaceObject.__)('Options'), 43231 popoverProps: MEDIA_OPTIONS_POPOVER_PROPS, 43232 icon: more_vertical 43233 }, () => (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuGroup, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 43234 onClick: () => window.open(reportUrl, '_blank').focus(), 43235 icon: library_external 43236 }, (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: The media type to report e.g: "image", "video", "audio" */ 43237 (0,external_wp_i18n_namespaceObject.__)('Report %s'), category.mediaType)))); 43238 } 43239 function InsertExternalImageModal({ 43240 onClose, 43241 onSubmit 43242 }) { 43243 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Modal, { 43244 title: (0,external_wp_i18n_namespaceObject.__)('Insert external image'), 43245 onRequestClose: onClose, 43246 className: "block-editor-inserter-media-tab-media-preview-inserter-external-image-modal" 43247 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalVStack, { 43248 spacing: 3 43249 }, (0,external_React_.createElement)("p", null, (0,external_wp_i18n_namespaceObject.__)('This image cannot be uploaded to your Media Library, but it can still be inserted as an external image.')), (0,external_React_.createElement)("p", null, (0,external_wp_i18n_namespaceObject.__)('External images can be removed by the external provider without warning and could even have legal compliance issues related to privacy legislation.'))), (0,external_React_.createElement)(external_wp_components_namespaceObject.Flex, { 43250 className: "block-editor-block-lock-modal__actions", 43251 justify: "flex-end", 43252 expanded: false 43253 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexItem, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 43254 variant: "tertiary", 43255 onClick: onClose 43256 }, (0,external_wp_i18n_namespaceObject.__)('Cancel'))), (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexItem, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 43257 variant: "primary", 43258 onClick: onSubmit 43259 }, (0,external_wp_i18n_namespaceObject.__)('Insert'))))); 43260 } 43261 function MediaPreview({ 43262 media, 43263 onClick, 43264 category 43265 }) { 43266 const [showExternalUploadModal, setShowExternalUploadModal] = (0,external_wp_element_namespaceObject.useState)(false); 43267 const [isHovered, setIsHovered] = (0,external_wp_element_namespaceObject.useState)(false); 43268 const [isInserting, setIsInserting] = (0,external_wp_element_namespaceObject.useState)(false); 43269 const [block, preview] = (0,external_wp_element_namespaceObject.useMemo)(() => getBlockAndPreviewFromMedia(media, category.mediaType), [media, category.mediaType]); 43270 const { 43271 createErrorNotice, 43272 createSuccessNotice 43273 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_notices_namespaceObject.store); 43274 const mediaUpload = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getSettings().mediaUpload, []); 43275 const onMediaInsert = (0,external_wp_element_namespaceObject.useCallback)(previewBlock => { 43276 // Prevent multiple uploads when we're in the process of inserting. 43277 if (isInserting) { 43278 return; 43279 } 43280 const clonedBlock = (0,external_wp_blocks_namespaceObject.cloneBlock)(previewBlock); 43281 const { 43282 id, 43283 url, 43284 caption 43285 } = clonedBlock.attributes; 43286 // Media item already exists in library, so just insert it. 43287 if (!!id) { 43288 onClick(clonedBlock); 43289 return; 43290 } 43291 setIsInserting(true); 43292 // Media item does not exist in library, so try to upload it. 43293 // Fist fetch the image data. This may fail if the image host 43294 // doesn't allow CORS with the domain. 43295 // If this happens, we insert the image block using the external 43296 // URL and let the user know about the possible implications. 43297 window.fetch(url).then(response => response.blob()).then(blob => { 43298 mediaUpload({ 43299 filesList: [blob], 43300 additionalData: { 43301 caption 43302 }, 43303 onFileChange([img]) { 43304 if ((0,external_wp_blob_namespaceObject.isBlobURL)(img.url)) { 43305 return; 43306 } 43307 onClick({ 43308 ...clonedBlock, 43309 attributes: { 43310 ...clonedBlock.attributes, 43311 id: img.id, 43312 url: img.url 43313 } 43314 }); 43315 createSuccessNotice((0,external_wp_i18n_namespaceObject.__)('Image uploaded and inserted.'), { 43316 type: 'snackbar' 43317 }); 43318 setIsInserting(false); 43319 }, 43320 allowedTypes: ALLOWED_MEDIA_TYPES, 43321 onError(message) { 43322 createErrorNotice(message, { 43323 type: 'snackbar' 43324 }); 43325 setIsInserting(false); 43326 } 43327 }); 43328 }).catch(() => { 43329 setShowExternalUploadModal(true); 43330 setIsInserting(false); 43331 }); 43332 }, [isInserting, onClick, mediaUpload, createErrorNotice, createSuccessNotice]); 43333 const title = typeof media.title === 'string' ? media.title : media.title?.rendered || (0,external_wp_i18n_namespaceObject.__)('no title'); 43334 let truncatedTitle; 43335 if (title.length > MAXIMUM_TITLE_LENGTH) { 43336 const omission = '...'; 43337 truncatedTitle = title.slice(0, MAXIMUM_TITLE_LENGTH - omission.length) + omission; 43338 } 43339 const onMouseEnter = (0,external_wp_element_namespaceObject.useCallback)(() => setIsHovered(true), []); 43340 const onMouseLeave = (0,external_wp_element_namespaceObject.useCallback)(() => setIsHovered(false), []); 43341 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(inserter_draggable_blocks, { 43342 isEnabled: true, 43343 blocks: [block] 43344 }, ({ 43345 draggable, 43346 onDragStart, 43347 onDragEnd 43348 }) => (0,external_React_.createElement)("div", { 43349 className: classnames_default()('block-editor-inserter__media-list__list-item', { 43350 'is-hovered': isHovered 43351 }), 43352 draggable: draggable, 43353 onDragStart: onDragStart, 43354 onDragEnd: onDragEnd 43355 }, (0,external_React_.createElement)("div", { 43356 onMouseEnter: onMouseEnter, 43357 onMouseLeave: onMouseLeave 43358 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Tooltip, { 43359 text: truncatedTitle || title 43360 }, (0,external_React_.createElement)(media_preview_CompositeItem, { 43361 render: (0,external_React_.createElement)("div", { 43362 "aria-label": title, 43363 role: "option", 43364 className: "block-editor-inserter__media-list__item" 43365 }), 43366 onClick: () => onMediaInsert(block) 43367 }, (0,external_React_.createElement)("div", { 43368 className: "block-editor-inserter__media-list__item-preview" 43369 }, preview, isInserting && (0,external_React_.createElement)("div", { 43370 className: "block-editor-inserter__media-list__item-preview-spinner" 43371 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Spinner, null))))), !isInserting && (0,external_React_.createElement)(MediaPreviewOptions, { 43372 category: category, 43373 media: media 43374 })))), showExternalUploadModal && (0,external_React_.createElement)(InsertExternalImageModal, { 43375 onClose: () => setShowExternalUploadModal(false), 43376 onSubmit: () => { 43377 onClick((0,external_wp_blocks_namespaceObject.cloneBlock)(block)); 43378 createSuccessNotice((0,external_wp_i18n_namespaceObject.__)('Image inserted.'), { 43379 type: 'snackbar' 43380 }); 43381 setShowExternalUploadModal(false); 43382 } 43383 })); 43384 } 43385 43386 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/media-tab/media-list.js 43387 43388 /** 43389 * WordPress dependencies 43390 */ 43391 43392 43393 43394 /** 43395 * Internal dependencies 43396 */ 43397 43398 43399 const { 43400 CompositeV2: media_list_Composite, 43401 useCompositeStoreV2: media_list_useCompositeStore 43402 } = unlock(external_wp_components_namespaceObject.privateApis); 43403 function MediaList({ 43404 mediaList, 43405 category, 43406 onClick, 43407 label = (0,external_wp_i18n_namespaceObject.__)('Media List') 43408 }) { 43409 const compositeStore = media_list_useCompositeStore(); 43410 return (0,external_React_.createElement)(media_list_Composite, { 43411 store: compositeStore, 43412 role: "listbox", 43413 className: "block-editor-inserter__media-list", 43414 "aria-label": label 43415 }, mediaList.map((media, index) => (0,external_React_.createElement)(MediaPreview, { 43416 key: media.id || media.sourceId || index, 43417 media: media, 43418 category: category, 43419 onClick: onClick 43420 }))); 43421 } 43422 /* harmony default export */ const media_list = (MediaList); 43423 43424 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/no-results.js 43425 43426 /** 43427 * WordPress dependencies 43428 */ 43429 43430 43431 function InserterNoResults() { 43432 return (0,external_React_.createElement)("div", { 43433 className: "block-editor-inserter__no-results" 43434 }, (0,external_React_.createElement)(build_module_icon, { 43435 className: "block-editor-inserter__no-results-icon", 43436 icon: block_default 43437 }), (0,external_React_.createElement)("p", null, (0,external_wp_i18n_namespaceObject.__)('No results found.'))); 43438 } 43439 /* harmony default export */ const no_results = (InserterNoResults); 43440 43441 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/media-tab/media-panel.js 43442 43443 /** 43444 * WordPress dependencies 43445 */ 43446 43447 43448 43449 43450 43451 43452 /** 43453 * Internal dependencies 43454 */ 43455 43456 43457 43458 const INITIAL_MEDIA_ITEMS_PER_PAGE = 10; 43459 function MediaCategoryDialog({ 43460 rootClientId, 43461 onInsert, 43462 category 43463 }) { 43464 const container = (0,external_wp_element_namespaceObject.useRef)(); 43465 (0,external_wp_element_namespaceObject.useEffect)(() => { 43466 const timeout = setTimeout(() => { 43467 const [firstTabbable] = external_wp_dom_namespaceObject.focus.tabbable.find(container.current); 43468 firstTabbable?.focus(); 43469 }); 43470 return () => clearTimeout(timeout); 43471 }, [category]); 43472 return (0,external_React_.createElement)("div", { 43473 ref: container, 43474 className: "block-editor-inserter__media-dialog" 43475 }, (0,external_React_.createElement)(MediaCategoryPanel, { 43476 rootClientId: rootClientId, 43477 onInsert: onInsert, 43478 category: category 43479 })); 43480 } 43481 function MediaCategoryPanel({ 43482 rootClientId, 43483 onInsert, 43484 category 43485 }) { 43486 const [search, setSearch, debouncedSearch] = (0,external_wp_compose_namespaceObject.useDebouncedInput)(); 43487 const { 43488 mediaList, 43489 isLoading 43490 } = useMediaResults(category, { 43491 per_page: !!debouncedSearch ? 20 : INITIAL_MEDIA_ITEMS_PER_PAGE, 43492 search: debouncedSearch 43493 }); 43494 const baseCssClass = 'block-editor-inserter__media-panel'; 43495 const searchLabel = category.labels.search_items || (0,external_wp_i18n_namespaceObject.__)('Search'); 43496 return (0,external_React_.createElement)("div", { 43497 className: baseCssClass 43498 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.SearchControl, { 43499 className: `$baseCssClass}-search`, 43500 onChange: setSearch, 43501 value: search, 43502 label: searchLabel, 43503 placeholder: searchLabel 43504 }), isLoading && (0,external_React_.createElement)("div", { 43505 className: `$baseCssClass}-spinner` 43506 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Spinner, null)), !isLoading && !mediaList?.length && (0,external_React_.createElement)(no_results, null), !isLoading && !!mediaList?.length && (0,external_React_.createElement)(media_list, { 43507 rootClientId: rootClientId, 43508 onClick: onInsert, 43509 mediaList: mediaList, 43510 category: category 43511 })); 43512 } 43513 43514 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/media-tab/media-tab.js 43515 43516 /** 43517 * External dependencies 43518 */ 43519 43520 43521 /** 43522 * WordPress dependencies 43523 */ 43524 43525 43526 43527 43528 43529 43530 /** 43531 * Internal dependencies 43532 */ 43533 43534 43535 43536 43537 43538 43539 const media_tab_ALLOWED_MEDIA_TYPES = ['image', 'video', 'audio']; 43540 function MediaTab({ 43541 rootClientId, 43542 selectedCategory, 43543 onSelectCategory, 43544 onInsert 43545 }) { 43546 const mediaCategories = useMediaCategories(rootClientId); 43547 const isMobile = (0,external_wp_compose_namespaceObject.useViewportMatch)('medium', '<'); 43548 const baseCssClass = 'block-editor-inserter__media-tabs'; 43549 const onSelectMedia = (0,external_wp_element_namespaceObject.useCallback)(media => { 43550 if (!media?.url) { 43551 return; 43552 } 43553 const [block] = getBlockAndPreviewFromMedia(media, media.type); 43554 onInsert(block); 43555 }, [onInsert]); 43556 const mobileMediaCategories = (0,external_wp_element_namespaceObject.useMemo)(() => mediaCategories.map(mediaCategory => ({ 43557 ...mediaCategory, 43558 label: mediaCategory.labels.name 43559 })), [mediaCategories]); 43560 return (0,external_React_.createElement)(external_React_.Fragment, null, !isMobile && (0,external_React_.createElement)("div", { 43561 className: `$baseCssClass}-container` 43562 }, (0,external_React_.createElement)("nav", { 43563 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Media categories') 43564 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalItemGroup, { 43565 role: "list", 43566 className: baseCssClass 43567 }, mediaCategories.map(mediaCategory => (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalItem, { 43568 role: "listitem", 43569 key: mediaCategory.name, 43570 onClick: () => onSelectCategory(mediaCategory), 43571 className: classnames_default()(`$baseCssClass}__media-category`, { 43572 'is-selected': selectedCategory === mediaCategory 43573 }), 43574 "aria-label": mediaCategory.labels.name, 43575 "aria-current": mediaCategory === selectedCategory ? 'true' : undefined 43576 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexBlock, null, mediaCategory.labels.name), (0,external_React_.createElement)(build_module_icon, { 43577 icon: (0,external_wp_i18n_namespaceObject.isRTL)() ? chevron_left : chevron_right 43578 })))), (0,external_React_.createElement)("div", { 43579 role: "listitem" 43580 }, (0,external_React_.createElement)(check, null, (0,external_React_.createElement)(media_upload, { 43581 multiple: false, 43582 onSelect: onSelectMedia, 43583 allowedTypes: media_tab_ALLOWED_MEDIA_TYPES, 43584 render: ({ 43585 open 43586 }) => (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 43587 onClick: event => { 43588 // Safari doesn't emit a focus event on button elements when 43589 // clicked and we need to manually focus the button here. 43590 // The reason is that core's Media Library modal explicitly triggers a 43591 // focus event and therefore a `blur` event is triggered on a different 43592 // element, which doesn't contain the `data-unstable-ignore-focus-outside-for-relatedtarget` 43593 // attribute making the Inserter dialog to close. 43594 event.target.focus(); 43595 open(); 43596 }, 43597 className: "block-editor-inserter__media-library-button", 43598 variant: "secondary", 43599 "data-unstable-ignore-focus-outside-for-relatedtarget": ".media-modal" 43600 }, (0,external_wp_i18n_namespaceObject.__)('Open Media Library')) 43601 })))))), isMobile && (0,external_React_.createElement)(MobileTabNavigation, { 43602 categories: mobileMediaCategories 43603 }, category => (0,external_React_.createElement)(MediaCategoryPanel, { 43604 onInsert: onInsert, 43605 rootClientId: rootClientId, 43606 category: category 43607 }))); 43608 } 43609 /* harmony default export */ const media_tab = (MediaTab); 43610 43611 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter-menu-extension/index.js 43612 /** 43613 * WordPress dependencies 43614 */ 43615 43616 const { 43617 Fill: __unstableInserterMenuExtension, 43618 Slot: inserter_menu_extension_Slot 43619 } = (0,external_wp_components_namespaceObject.createSlotFill)('__unstableInserterMenuExtension'); 43620 __unstableInserterMenuExtension.Slot = inserter_menu_extension_Slot; 43621 /* harmony default export */ const inserter_menu_extension = (__unstableInserterMenuExtension); 43622 43623 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/search-results.js 43624 43625 /** 43626 * WordPress dependencies 43627 */ 43628 43629 43630 43631 43632 43633 43634 43635 /** 43636 * Internal dependencies 43637 */ 43638 43639 43640 43641 43642 43643 43644 43645 43646 43647 43648 43649 43650 43651 const search_results_INITIAL_INSERTER_RESULTS = 9; 43652 /** 43653 * Shared reference to an empty array for cases where it is important to avoid 43654 * returning a new array reference on every invocation and rerendering the component. 43655 * 43656 * @type {Array} 43657 */ 43658 const search_results_EMPTY_ARRAY = []; 43659 function InserterSearchResults({ 43660 filterValue, 43661 onSelect, 43662 onHover, 43663 onHoverPattern, 43664 rootClientId, 43665 clientId, 43666 isAppender, 43667 __experimentalInsertionIndex, 43668 maxBlockPatterns, 43669 maxBlockTypes, 43670 showBlockDirectory = false, 43671 isDraggable = true, 43672 shouldFocusBlock = true, 43673 prioritizePatterns, 43674 selectBlockOnInsert 43675 }) { 43676 const debouncedSpeak = (0,external_wp_compose_namespaceObject.useDebounce)(external_wp_a11y_namespaceObject.speak, 500); 43677 const { 43678 prioritizedBlocks 43679 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 43680 const blockListSettings = select(store).getBlockListSettings(rootClientId); 43681 return { 43682 prioritizedBlocks: blockListSettings?.prioritizedInserterBlocks || search_results_EMPTY_ARRAY 43683 }; 43684 }, [rootClientId]); 43685 const [destinationRootClientId, onInsertBlocks] = use_insertion_point({ 43686 onSelect, 43687 rootClientId, 43688 clientId, 43689 isAppender, 43690 insertionIndex: __experimentalInsertionIndex, 43691 shouldFocusBlock, 43692 selectBlockOnInsert 43693 }); 43694 const [blockTypes, blockTypeCategories, blockTypeCollections, onSelectBlockType] = use_block_types_state(destinationRootClientId, onInsertBlocks); 43695 const [patterns,, onClickPattern] = use_patterns_state(onInsertBlocks, destinationRootClientId); 43696 const filteredBlockPatterns = (0,external_wp_element_namespaceObject.useMemo)(() => { 43697 if (maxBlockPatterns === 0) { 43698 return []; 43699 } 43700 const results = searchItems(patterns, filterValue); 43701 return maxBlockPatterns !== undefined ? results.slice(0, maxBlockPatterns) : results; 43702 }, [filterValue, patterns, maxBlockPatterns]); 43703 let maxBlockTypesToShow = maxBlockTypes; 43704 if (prioritizePatterns && filteredBlockPatterns.length > 2) { 43705 maxBlockTypesToShow = 0; 43706 } 43707 const filteredBlockTypes = (0,external_wp_element_namespaceObject.useMemo)(() => { 43708 if (maxBlockTypesToShow === 0) { 43709 return []; 43710 } 43711 const nonPatternBlockTypes = blockTypes.filter(blockType => blockType.name !== 'core/block'); 43712 let orderedItems = orderBy(nonPatternBlockTypes, 'frecency', 'desc'); 43713 if (!filterValue && prioritizedBlocks.length) { 43714 orderedItems = orderInserterBlockItems(orderedItems, prioritizedBlocks); 43715 } 43716 const results = searchBlockItems(orderedItems, blockTypeCategories, blockTypeCollections, filterValue); 43717 return maxBlockTypesToShow !== undefined ? results.slice(0, maxBlockTypesToShow) : results; 43718 }, [filterValue, blockTypes, blockTypeCategories, blockTypeCollections, maxBlockTypesToShow, prioritizedBlocks]); 43719 43720 // Announce search results on change. 43721 (0,external_wp_element_namespaceObject.useEffect)(() => { 43722 if (!filterValue) { 43723 return; 43724 } 43725 const count = filteredBlockTypes.length + filteredBlockPatterns.length; 43726 const resultsFoundMessage = (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %d: number of results. */ 43727 (0,external_wp_i18n_namespaceObject._n)('%d result found.', '%d results found.', count), count); 43728 debouncedSpeak(resultsFoundMessage); 43729 }, [filterValue, debouncedSpeak, filteredBlockTypes, filteredBlockPatterns]); 43730 const currentShownBlockTypes = (0,external_wp_compose_namespaceObject.useAsyncList)(filteredBlockTypes, { 43731 step: search_results_INITIAL_INSERTER_RESULTS 43732 }); 43733 const currentShownPatterns = (0,external_wp_compose_namespaceObject.useAsyncList)(currentShownBlockTypes.length === filteredBlockTypes.length ? filteredBlockPatterns : search_results_EMPTY_ARRAY); 43734 const hasItems = filteredBlockTypes.length > 0 || filteredBlockPatterns.length > 0; 43735 const blocksUI = !!filteredBlockTypes.length && (0,external_React_.createElement)(panel, { 43736 title: (0,external_React_.createElement)(external_wp_components_namespaceObject.VisuallyHidden, null, (0,external_wp_i18n_namespaceObject.__)('Blocks')) 43737 }, (0,external_React_.createElement)(block_types_list, { 43738 items: currentShownBlockTypes, 43739 onSelect: onSelectBlockType, 43740 onHover: onHover, 43741 label: (0,external_wp_i18n_namespaceObject.__)('Blocks'), 43742 isDraggable: isDraggable 43743 })); 43744 const patternsUI = !!filteredBlockPatterns.length && (0,external_React_.createElement)(panel, { 43745 title: (0,external_React_.createElement)(external_wp_components_namespaceObject.VisuallyHidden, null, (0,external_wp_i18n_namespaceObject.__)('Block patterns')) 43746 }, (0,external_React_.createElement)("div", { 43747 className: "block-editor-inserter__quick-inserter-patterns" 43748 }, (0,external_React_.createElement)(block_patterns_list, { 43749 shownPatterns: currentShownPatterns, 43750 blockPatterns: filteredBlockPatterns, 43751 onClickPattern: onClickPattern, 43752 onHover: onHoverPattern, 43753 isDraggable: isDraggable 43754 }))); 43755 return (0,external_React_.createElement)(inserter_listbox, null, !showBlockDirectory && !hasItems && (0,external_React_.createElement)(no_results, null), prioritizePatterns ? patternsUI : blocksUI, !!filteredBlockTypes.length && !!filteredBlockPatterns.length && (0,external_React_.createElement)("div", { 43756 className: "block-editor-inserter__quick-inserter-separator" 43757 }), prioritizePatterns ? blocksUI : patternsUI, showBlockDirectory && (0,external_React_.createElement)(inserter_menu_extension.Slot, { 43758 fillProps: { 43759 onSelect: onSelectBlockType, 43760 onHover, 43761 filterValue, 43762 hasItems, 43763 rootClientId: destinationRootClientId 43764 } 43765 }, fills => { 43766 if (fills.length) { 43767 return fills; 43768 } 43769 if (!hasItems) { 43770 return (0,external_React_.createElement)(no_results, null); 43771 } 43772 return null; 43773 })); 43774 } 43775 /* harmony default export */ const search_results = (InserterSearchResults); 43776 43777 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/tabs.js 43778 43779 /** 43780 * WordPress dependencies 43781 */ 43782 43783 43784 43785 /** 43786 * Internal dependencies 43787 */ 43788 43789 const { 43790 Tabs 43791 } = unlock(external_wp_components_namespaceObject.privateApis); 43792 const blocksTab = { 43793 name: 'blocks', 43794 /* translators: Blocks tab title in the block inserter. */ 43795 title: (0,external_wp_i18n_namespaceObject.__)('Blocks') 43796 }; 43797 const patternsTab = { 43798 name: 'patterns', 43799 /* translators: Theme and Directory Patterns tab title in the block inserter. */ 43800 title: (0,external_wp_i18n_namespaceObject.__)('Patterns') 43801 }; 43802 const mediaTab = { 43803 name: 'media', 43804 /* translators: Media tab title in the block inserter. */ 43805 title: (0,external_wp_i18n_namespaceObject.__)('Media') 43806 }; 43807 function InserterTabs({ 43808 showPatterns = false, 43809 showMedia = false, 43810 onSelect, 43811 tabsContents 43812 }) { 43813 const tabs = [blocksTab, showPatterns && patternsTab, showMedia && mediaTab].filter(Boolean); 43814 return (0,external_React_.createElement)("div", { 43815 className: "block-editor-inserter__tabs" 43816 }, (0,external_React_.createElement)(Tabs, { 43817 onSelect: onSelect 43818 }, (0,external_React_.createElement)(Tabs.TabList, null, tabs.map(tab => (0,external_React_.createElement)(Tabs.Tab, { 43819 key: tab.name, 43820 tabId: tab.name 43821 }, tab.title))), tabs.map(tab => (0,external_React_.createElement)(Tabs.TabPanel, { 43822 key: tab.name, 43823 tabId: tab.name, 43824 focusable: false 43825 }, tabsContents[tab.name])))); 43826 } 43827 /* harmony default export */ const tabs = (InserterTabs); 43828 43829 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/menu.js 43830 43831 /** 43832 * External dependencies 43833 */ 43834 43835 43836 /** 43837 * WordPress dependencies 43838 */ 43839 43840 43841 43842 43843 43844 43845 /** 43846 * Internal dependencies 43847 */ 43848 43849 43850 43851 43852 43853 43854 43855 43856 43857 43858 43859 function InserterMenu({ 43860 rootClientId, 43861 clientId, 43862 isAppender, 43863 __experimentalInsertionIndex, 43864 onSelect, 43865 showInserterHelpPanel, 43866 showMostUsedBlocks, 43867 __experimentalFilterValue = '', 43868 shouldFocusBlock = true 43869 }, ref) { 43870 const [filterValue, setFilterValue, delayedFilterValue] = (0,external_wp_compose_namespaceObject.useDebouncedInput)(__experimentalFilterValue); 43871 const [hoveredItem, setHoveredItem] = (0,external_wp_element_namespaceObject.useState)(null); 43872 const [selectedPatternCategory, setSelectedPatternCategory] = (0,external_wp_element_namespaceObject.useState)(null); 43873 const [patternFilter, setPatternFilter] = (0,external_wp_element_namespaceObject.useState)('all'); 43874 const [selectedMediaCategory, setSelectedMediaCategory] = (0,external_wp_element_namespaceObject.useState)(null); 43875 const [selectedTab, setSelectedTab] = (0,external_wp_element_namespaceObject.useState)(null); 43876 const [destinationRootClientId, onInsertBlocks, onToggleInsertionPoint] = use_insertion_point({ 43877 rootClientId, 43878 clientId, 43879 isAppender, 43880 insertionIndex: __experimentalInsertionIndex, 43881 shouldFocusBlock 43882 }); 43883 const { 43884 showPatterns 43885 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 43886 const { 43887 hasAllowedPatterns 43888 } = unlock(select(store)); 43889 return { 43890 showPatterns: hasAllowedPatterns(destinationRootClientId) 43891 }; 43892 }, [destinationRootClientId]); 43893 const mediaCategories = useMediaCategories(destinationRootClientId); 43894 const showMedia = mediaCategories.length > 0; 43895 const onInsert = (0,external_wp_element_namespaceObject.useCallback)((blocks, meta, shouldForceFocusBlock) => { 43896 onInsertBlocks(blocks, meta, shouldForceFocusBlock); 43897 onSelect(); 43898 }, [onInsertBlocks, onSelect]); 43899 const onInsertPattern = (0,external_wp_element_namespaceObject.useCallback)((blocks, patternName) => { 43900 onInsertBlocks(blocks, { 43901 patternName 43902 }); 43903 onSelect(); 43904 }, [onInsertBlocks, onSelect]); 43905 const onHover = (0,external_wp_element_namespaceObject.useCallback)(item => { 43906 onToggleInsertionPoint(!!item); 43907 setHoveredItem(item); 43908 }, [onToggleInsertionPoint, setHoveredItem]); 43909 const onHoverPattern = (0,external_wp_element_namespaceObject.useCallback)(item => { 43910 onToggleInsertionPoint(!!item); 43911 }, [onToggleInsertionPoint]); 43912 const onClickPatternCategory = (0,external_wp_element_namespaceObject.useCallback)((patternCategory, filter) => { 43913 setSelectedPatternCategory(patternCategory); 43914 setPatternFilter(filter); 43915 }, [setSelectedPatternCategory]); 43916 const blocksTab = (0,external_wp_element_namespaceObject.useMemo)(() => (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)("div", { 43917 className: "block-editor-inserter__block-list" 43918 }, (0,external_React_.createElement)(block_types_tab, { 43919 rootClientId: destinationRootClientId, 43920 onInsert: onInsert, 43921 onHover: onHover, 43922 showMostUsedBlocks: showMostUsedBlocks 43923 })), showInserterHelpPanel && (0,external_React_.createElement)("div", { 43924 className: "block-editor-inserter__tips" 43925 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.VisuallyHidden, { 43926 as: "h2" 43927 }, (0,external_wp_i18n_namespaceObject.__)('A tip for using the block editor')), (0,external_React_.createElement)(tips, null))), [destinationRootClientId, onInsert, onHover, showMostUsedBlocks, showInserterHelpPanel]); 43928 const patternsTab = (0,external_wp_element_namespaceObject.useMemo)(() => (0,external_React_.createElement)(block_patterns_tab, { 43929 rootClientId: destinationRootClientId, 43930 onInsert: onInsertPattern, 43931 onSelectCategory: onClickPatternCategory, 43932 selectedCategory: selectedPatternCategory 43933 }), [destinationRootClientId, onInsertPattern, onClickPatternCategory, selectedPatternCategory]); 43934 const mediaTab = (0,external_wp_element_namespaceObject.useMemo)(() => (0,external_React_.createElement)(media_tab, { 43935 rootClientId: destinationRootClientId, 43936 selectedCategory: selectedMediaCategory, 43937 onSelectCategory: setSelectedMediaCategory, 43938 onInsert: onInsert 43939 }), [destinationRootClientId, onInsert, selectedMediaCategory, setSelectedMediaCategory]); 43940 const inserterTabsContents = (0,external_wp_element_namespaceObject.useMemo)(() => ({ 43941 blocks: blocksTab, 43942 patterns: patternsTab, 43943 media: mediaTab 43944 }), [blocksTab, mediaTab, patternsTab]); 43945 const searchRef = (0,external_wp_element_namespaceObject.useRef)(); 43946 (0,external_wp_element_namespaceObject.useImperativeHandle)(ref, () => ({ 43947 focusSearch: () => { 43948 searchRef.current.focus(); 43949 } 43950 })); 43951 const showPatternPanel = selectedTab === 'patterns' && !delayedFilterValue && selectedPatternCategory; 43952 const showAsTabs = !delayedFilterValue && (showPatterns || showMedia); 43953 const showMediaPanel = selectedTab === 'media' && !delayedFilterValue && selectedMediaCategory; 43954 const handleSetSelectedTab = value => { 43955 // If no longer on patterns tab remove the category setting. 43956 if (value !== 'patterns') { 43957 setSelectedPatternCategory(null); 43958 } 43959 setSelectedTab(value); 43960 }; 43961 return (0,external_React_.createElement)("div", { 43962 className: "block-editor-inserter__menu" 43963 }, (0,external_React_.createElement)("div", { 43964 className: classnames_default()('block-editor-inserter__main-area', { 43965 'show-as-tabs': showAsTabs 43966 }) 43967 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.SearchControl, { 43968 __nextHasNoMarginBottom: true, 43969 className: "block-editor-inserter__search", 43970 onChange: value => { 43971 if (hoveredItem) setHoveredItem(null); 43972 setFilterValue(value); 43973 }, 43974 value: filterValue, 43975 label: (0,external_wp_i18n_namespaceObject.__)('Search for blocks and patterns'), 43976 placeholder: (0,external_wp_i18n_namespaceObject.__)('Search'), 43977 ref: searchRef 43978 }), !!delayedFilterValue && (0,external_React_.createElement)("div", { 43979 className: "block-editor-inserter__no-tab-container" 43980 }, (0,external_React_.createElement)(search_results, { 43981 filterValue: delayedFilterValue, 43982 onSelect: onSelect, 43983 onHover: onHover, 43984 onHoverPattern: onHoverPattern, 43985 rootClientId: rootClientId, 43986 clientId: clientId, 43987 isAppender: isAppender, 43988 __experimentalInsertionIndex: __experimentalInsertionIndex, 43989 showBlockDirectory: true, 43990 shouldFocusBlock: shouldFocusBlock 43991 })), showAsTabs && (0,external_React_.createElement)(tabs, { 43992 showPatterns: showPatterns, 43993 showMedia: showMedia, 43994 onSelect: handleSetSelectedTab, 43995 tabsContents: inserterTabsContents 43996 }), !delayedFilterValue && !showAsTabs && (0,external_React_.createElement)("div", { 43997 className: "block-editor-inserter__no-tab-container" 43998 }, blocksTab)), showMediaPanel && (0,external_React_.createElement)(MediaCategoryDialog, { 43999 rootClientId: destinationRootClientId, 44000 onInsert: onInsert, 44001 category: selectedMediaCategory 44002 }), showInserterHelpPanel && hoveredItem && (0,external_React_.createElement)(external_wp_components_namespaceObject.Popover, { 44003 className: "block-editor-inserter__preview-container__popover", 44004 placement: "right-start", 44005 offset: 16, 44006 focusOnMount: false, 44007 animate: false 44008 }, (0,external_React_.createElement)(preview_panel, { 44009 item: hoveredItem 44010 })), showPatternPanel && (0,external_React_.createElement)(PatternCategoryPreviewPanel, { 44011 rootClientId: destinationRootClientId, 44012 onInsert: onInsertPattern, 44013 onHover: onHoverPattern, 44014 category: selectedPatternCategory, 44015 patternFilter: patternFilter, 44016 showTitlesAsTooltip: true 44017 })); 44018 } 44019 /* harmony default export */ const menu = ((0,external_wp_element_namespaceObject.forwardRef)(InserterMenu)); 44020 44021 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/quick-inserter.js 44022 44023 /** 44024 * External dependencies 44025 */ 44026 44027 44028 /** 44029 * WordPress dependencies 44030 */ 44031 44032 44033 44034 44035 44036 /** 44037 * Internal dependencies 44038 */ 44039 44040 44041 44042 44043 44044 const SEARCH_THRESHOLD = 6; 44045 const quick_inserter_SHOWN_BLOCK_TYPES = 6; 44046 const SHOWN_BLOCK_PATTERNS = 2; 44047 const SHOWN_BLOCK_PATTERNS_WITH_PRIORITIZATION = 4; 44048 function QuickInserter({ 44049 onSelect, 44050 rootClientId, 44051 clientId, 44052 isAppender, 44053 prioritizePatterns, 44054 selectBlockOnInsert, 44055 hasSearch = true 44056 }) { 44057 const [filterValue, setFilterValue] = (0,external_wp_element_namespaceObject.useState)(''); 44058 const [destinationRootClientId, onInsertBlocks] = use_insertion_point({ 44059 onSelect, 44060 rootClientId, 44061 clientId, 44062 isAppender, 44063 selectBlockOnInsert 44064 }); 44065 const [blockTypes] = use_block_types_state(destinationRootClientId, onInsertBlocks); 44066 const [patterns] = use_patterns_state(onInsertBlocks, destinationRootClientId); 44067 const { 44068 setInserterIsOpened, 44069 insertionIndex 44070 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 44071 const { 44072 getSettings, 44073 getBlockIndex, 44074 getBlockCount 44075 } = select(store); 44076 const settings = getSettings(); 44077 const index = getBlockIndex(clientId); 44078 const blockCount = getBlockCount(); 44079 return { 44080 setInserterIsOpened: settings.__experimentalSetIsInserterOpened, 44081 insertionIndex: index === -1 ? blockCount : index 44082 }; 44083 }, [clientId]); 44084 const showPatterns = patterns.length && (!!filterValue || prioritizePatterns); 44085 const showSearch = hasSearch && (showPatterns && patterns.length > SEARCH_THRESHOLD || blockTypes.length > SEARCH_THRESHOLD); 44086 (0,external_wp_element_namespaceObject.useEffect)(() => { 44087 if (setInserterIsOpened) { 44088 setInserterIsOpened(false); 44089 } 44090 }, [setInserterIsOpened]); 44091 44092 // When clicking Browse All select the appropriate block so as 44093 // the insertion point can work as expected. 44094 const onBrowseAll = () => { 44095 setInserterIsOpened({ 44096 rootClientId, 44097 insertionIndex, 44098 filterValue 44099 }); 44100 }; 44101 let maxBlockPatterns = 0; 44102 if (showPatterns) { 44103 maxBlockPatterns = prioritizePatterns ? SHOWN_BLOCK_PATTERNS_WITH_PRIORITIZATION : SHOWN_BLOCK_PATTERNS; 44104 } 44105 return (0,external_React_.createElement)("div", { 44106 className: classnames_default()('block-editor-inserter__quick-inserter', { 44107 'has-search': showSearch, 44108 'has-expand': setInserterIsOpened 44109 }) 44110 }, showSearch && (0,external_React_.createElement)(external_wp_components_namespaceObject.SearchControl, { 44111 __nextHasNoMarginBottom: true, 44112 className: "block-editor-inserter__search", 44113 value: filterValue, 44114 onChange: value => { 44115 setFilterValue(value); 44116 }, 44117 label: (0,external_wp_i18n_namespaceObject.__)('Search for blocks and patterns'), 44118 placeholder: (0,external_wp_i18n_namespaceObject.__)('Search') 44119 }), (0,external_React_.createElement)("div", { 44120 className: "block-editor-inserter__quick-inserter-results" 44121 }, (0,external_React_.createElement)(search_results, { 44122 filterValue: filterValue, 44123 onSelect: onSelect, 44124 rootClientId: rootClientId, 44125 clientId: clientId, 44126 isAppender: isAppender, 44127 maxBlockPatterns: maxBlockPatterns, 44128 maxBlockTypes: quick_inserter_SHOWN_BLOCK_TYPES, 44129 isDraggable: false, 44130 prioritizePatterns: prioritizePatterns, 44131 selectBlockOnInsert: selectBlockOnInsert 44132 })), setInserterIsOpened && (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 44133 className: "block-editor-inserter__quick-inserter-expand", 44134 onClick: onBrowseAll, 44135 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Browse all. This will open the main inserter panel in the editor toolbar.') 44136 }, (0,external_wp_i18n_namespaceObject.__)('Browse all'))); 44137 } 44138 44139 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/index.js 44140 44141 /** 44142 * External dependencies 44143 */ 44144 44145 44146 /** 44147 * WordPress dependencies 44148 */ 44149 44150 44151 44152 44153 44154 44155 44156 44157 44158 /** 44159 * Internal dependencies 44160 */ 44161 44162 44163 44164 const defaultRenderToggle = ({ 44165 onToggle, 44166 disabled, 44167 isOpen, 44168 blockTitle, 44169 hasSingleBlockType, 44170 toggleProps = {}, 44171 prioritizePatterns 44172 }) => { 44173 const { 44174 as: Wrapper = external_wp_components_namespaceObject.Button, 44175 label: labelProp, 44176 onClick, 44177 ...rest 44178 } = toggleProps; 44179 let label = labelProp; 44180 if (!label && hasSingleBlockType) { 44181 label = (0,external_wp_i18n_namespaceObject.sprintf)( 44182 // translators: %s: the name of the block when there is only one 44183 (0,external_wp_i18n_namespaceObject._x)('Add %s', 'directly add the only allowed block'), blockTitle); 44184 } else if (!label && prioritizePatterns) { 44185 label = (0,external_wp_i18n_namespaceObject.__)('Add pattern'); 44186 } else if (!label) { 44187 label = (0,external_wp_i18n_namespaceObject._x)('Add block', 'Generic label for block inserter button'); 44188 } 44189 44190 // Handle both onClick functions from the toggle and the parent component. 44191 function handleClick(event) { 44192 if (onToggle) { 44193 onToggle(event); 44194 } 44195 if (onClick) { 44196 onClick(event); 44197 } 44198 } 44199 return (0,external_React_.createElement)(Wrapper, { 44200 icon: library_plus, 44201 label: label, 44202 tooltipPosition: "bottom", 44203 onClick: handleClick, 44204 className: "block-editor-inserter__toggle", 44205 "aria-haspopup": !hasSingleBlockType ? 'true' : false, 44206 "aria-expanded": !hasSingleBlockType ? isOpen : false, 44207 disabled: disabled, 44208 ...rest 44209 }); 44210 }; 44211 class PrivateInserter extends external_wp_element_namespaceObject.Component { 44212 constructor() { 44213 super(...arguments); 44214 this.onToggle = this.onToggle.bind(this); 44215 this.renderToggle = this.renderToggle.bind(this); 44216 this.renderContent = this.renderContent.bind(this); 44217 } 44218 onToggle(isOpen) { 44219 const { 44220 onToggle 44221 } = this.props; 44222 44223 // Surface toggle callback to parent component. 44224 if (onToggle) { 44225 onToggle(isOpen); 44226 } 44227 } 44228 44229 /** 44230 * Render callback to display Dropdown toggle element. 44231 * 44232 * @param {Object} options 44233 * @param {Function} options.onToggle Callback to invoke when toggle is 44234 * pressed. 44235 * @param {boolean} options.isOpen Whether dropdown is currently open. 44236 * 44237 * @return {Element} Dropdown toggle element. 44238 */ 44239 renderToggle({ 44240 onToggle, 44241 isOpen 44242 }) { 44243 const { 44244 disabled, 44245 blockTitle, 44246 hasSingleBlockType, 44247 directInsertBlock, 44248 toggleProps, 44249 hasItems, 44250 renderToggle = defaultRenderToggle, 44251 prioritizePatterns 44252 } = this.props; 44253 return renderToggle({ 44254 onToggle, 44255 isOpen, 44256 disabled: disabled || !hasItems, 44257 blockTitle, 44258 hasSingleBlockType, 44259 directInsertBlock, 44260 toggleProps, 44261 prioritizePatterns 44262 }); 44263 } 44264 44265 /** 44266 * Render callback to display Dropdown content element. 44267 * 44268 * @param {Object} options 44269 * @param {Function} options.onClose Callback to invoke when dropdown is 44270 * closed. 44271 * 44272 * @return {Element} Dropdown content element. 44273 */ 44274 renderContent({ 44275 onClose 44276 }) { 44277 const { 44278 rootClientId, 44279 clientId, 44280 isAppender, 44281 showInserterHelpPanel, 44282 // This prop is experimental to give some time for the quick inserter to mature 44283 // Feel free to make them stable after a few releases. 44284 __experimentalIsQuick: isQuick, 44285 prioritizePatterns, 44286 onSelectOrClose, 44287 selectBlockOnInsert 44288 } = this.props; 44289 if (isQuick) { 44290 return (0,external_React_.createElement)(QuickInserter, { 44291 onSelect: blocks => { 44292 const firstBlock = Array.isArray(blocks) && blocks?.length ? blocks[0] : blocks; 44293 if (onSelectOrClose && typeof onSelectOrClose === 'function') { 44294 onSelectOrClose(firstBlock); 44295 } 44296 onClose(); 44297 }, 44298 rootClientId: rootClientId, 44299 clientId: clientId, 44300 isAppender: isAppender, 44301 prioritizePatterns: prioritizePatterns, 44302 selectBlockOnInsert: selectBlockOnInsert 44303 }); 44304 } 44305 return (0,external_React_.createElement)(menu, { 44306 onSelect: () => { 44307 onClose(); 44308 }, 44309 rootClientId: rootClientId, 44310 clientId: clientId, 44311 isAppender: isAppender, 44312 showInserterHelpPanel: showInserterHelpPanel 44313 }); 44314 } 44315 render() { 44316 const { 44317 position, 44318 hasSingleBlockType, 44319 directInsertBlock, 44320 insertOnlyAllowedBlock, 44321 __experimentalIsQuick: isQuick, 44322 onSelectOrClose 44323 } = this.props; 44324 if (hasSingleBlockType || directInsertBlock) { 44325 return this.renderToggle({ 44326 onToggle: insertOnlyAllowedBlock 44327 }); 44328 } 44329 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Dropdown, { 44330 className: "block-editor-inserter", 44331 contentClassName: classnames_default()('block-editor-inserter__popover', { 44332 'is-quick': isQuick 44333 }), 44334 popoverProps: { 44335 position, 44336 shift: true 44337 }, 44338 onToggle: this.onToggle, 44339 expandOnMobile: true, 44340 headerTitle: (0,external_wp_i18n_namespaceObject.__)('Add a block'), 44341 renderToggle: this.renderToggle, 44342 renderContent: this.renderContent, 44343 onClose: onSelectOrClose 44344 }); 44345 } 44346 } 44347 const ComposedPrivateInserter = (0,external_wp_compose_namespaceObject.compose)([(0,external_wp_data_namespaceObject.withSelect)((select, { 44348 clientId, 44349 rootClientId, 44350 shouldDirectInsert = true 44351 }) => { 44352 const { 44353 getBlockRootClientId, 44354 hasInserterItems, 44355 getAllowedBlocks, 44356 getDirectInsertBlock, 44357 getSettings 44358 } = select(store); 44359 const { 44360 getBlockVariations 44361 } = select(external_wp_blocks_namespaceObject.store); 44362 rootClientId = rootClientId || getBlockRootClientId(clientId) || undefined; 44363 const allowedBlocks = getAllowedBlocks(rootClientId); 44364 const directInsertBlock = shouldDirectInsert && getDirectInsertBlock(rootClientId); 44365 const settings = getSettings(); 44366 const hasSingleBlockType = allowedBlocks?.length === 1 && getBlockVariations(allowedBlocks[0].name, 'inserter')?.length === 0; 44367 let allowedBlockType = false; 44368 if (hasSingleBlockType) { 44369 allowedBlockType = allowedBlocks[0]; 44370 } 44371 return { 44372 hasItems: hasInserterItems(rootClientId), 44373 hasSingleBlockType, 44374 blockTitle: allowedBlockType ? allowedBlockType.title : '', 44375 allowedBlockType, 44376 directInsertBlock, 44377 rootClientId, 44378 prioritizePatterns: settings.__experimentalPreferPatternsOnRoot && !rootClientId 44379 }; 44380 }), (0,external_wp_data_namespaceObject.withDispatch)((dispatch, ownProps, { 44381 select 44382 }) => { 44383 return { 44384 insertOnlyAllowedBlock() { 44385 const { 44386 rootClientId, 44387 clientId, 44388 isAppender, 44389 hasSingleBlockType, 44390 allowedBlockType, 44391 directInsertBlock, 44392 onSelectOrClose, 44393 selectBlockOnInsert 44394 } = ownProps; 44395 if (!hasSingleBlockType && !directInsertBlock) { 44396 return; 44397 } 44398 function getAdjacentBlockAttributes(attributesToCopy) { 44399 const { 44400 getBlock, 44401 getPreviousBlockClientId 44402 } = select(store); 44403 if (!attributesToCopy || !clientId && !rootClientId) { 44404 return {}; 44405 } 44406 const result = {}; 44407 let adjacentAttributes = {}; 44408 44409 // If there is no clientId, then attempt to get attributes 44410 // from the last block within innerBlocks of the root block. 44411 if (!clientId) { 44412 const parentBlock = getBlock(rootClientId); 44413 if (parentBlock?.innerBlocks?.length) { 44414 const lastInnerBlock = parentBlock.innerBlocks[parentBlock.innerBlocks.length - 1]; 44415 if (directInsertBlock && directInsertBlock?.name === lastInnerBlock.name) { 44416 adjacentAttributes = lastInnerBlock.attributes; 44417 } 44418 } 44419 } else { 44420 // Otherwise, attempt to get attributes from the 44421 // previous block relative to the current clientId. 44422 const currentBlock = getBlock(clientId); 44423 const previousBlock = getBlock(getPreviousBlockClientId(clientId)); 44424 if (currentBlock?.name === previousBlock?.name) { 44425 adjacentAttributes = previousBlock?.attributes || {}; 44426 } 44427 } 44428 44429 // Copy over only those attributes flagged to be copied. 44430 attributesToCopy.forEach(attribute => { 44431 if (adjacentAttributes.hasOwnProperty(attribute)) { 44432 result[attribute] = adjacentAttributes[attribute]; 44433 } 44434 }); 44435 return result; 44436 } 44437 function getInsertionIndex() { 44438 const { 44439 getBlockIndex, 44440 getBlockSelectionEnd, 44441 getBlockOrder, 44442 getBlockRootClientId 44443 } = select(store); 44444 44445 // If the clientId is defined, we insert at the position of the block. 44446 if (clientId) { 44447 return getBlockIndex(clientId); 44448 } 44449 44450 // If there a selected block, we insert after the selected block. 44451 const end = getBlockSelectionEnd(); 44452 if (!isAppender && end && getBlockRootClientId(end) === rootClientId) { 44453 return getBlockIndex(end) + 1; 44454 } 44455 44456 // Otherwise, we insert at the end of the current rootClientId. 44457 return getBlockOrder(rootClientId).length; 44458 } 44459 const { 44460 insertBlock 44461 } = dispatch(store); 44462 let blockToInsert; 44463 44464 // Attempt to augment the directInsertBlock with attributes from an adjacent block. 44465 // This ensures styling from nearby blocks is preserved in the newly inserted block. 44466 // See: https://github.com/WordPress/gutenberg/issues/37904 44467 if (directInsertBlock) { 44468 const newAttributes = getAdjacentBlockAttributes(directInsertBlock.attributesToCopy); 44469 blockToInsert = (0,external_wp_blocks_namespaceObject.createBlock)(directInsertBlock.name, { 44470 ...(directInsertBlock.attributes || {}), 44471 ...newAttributes 44472 }); 44473 } else { 44474 blockToInsert = (0,external_wp_blocks_namespaceObject.createBlock)(allowedBlockType.name); 44475 } 44476 insertBlock(blockToInsert, getInsertionIndex(), rootClientId, selectBlockOnInsert); 44477 if (onSelectOrClose) { 44478 onSelectOrClose({ 44479 clientId: blockToInsert?.clientId 44480 }); 44481 } 44482 const message = (0,external_wp_i18n_namespaceObject.sprintf)( 44483 // translators: %s: the name of the block that has been added 44484 (0,external_wp_i18n_namespaceObject.__)('%s block added'), allowedBlockType.title); 44485 (0,external_wp_a11y_namespaceObject.speak)(message); 44486 } 44487 }; 44488 }), 44489 // The global inserter should always be visible, we are using ( ! isAppender && ! rootClientId && ! clientId ) as 44490 // a way to detect the global Inserter. 44491 (0,external_wp_compose_namespaceObject.ifCondition)(({ 44492 hasItems, 44493 isAppender, 44494 rootClientId, 44495 clientId 44496 }) => hasItems || !isAppender && !rootClientId && !clientId)])(PrivateInserter); 44497 const Inserter = (0,external_wp_element_namespaceObject.forwardRef)((props, ref) => { 44498 return (0,external_React_.createElement)(ComposedPrivateInserter, { 44499 ref: ref, 44500 ...props 44501 }); 44502 }); 44503 /* harmony default export */ const inserter = (Inserter); 44504 44505 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/default-block-appender/index.js 44506 44507 /** 44508 * External dependencies 44509 */ 44510 44511 44512 /** 44513 * WordPress dependencies 44514 */ 44515 44516 44517 44518 44519 44520 /** 44521 * Internal dependencies 44522 */ 44523 44524 44525 44526 /** 44527 * Zero width non-breaking space, used as padding for the paragraph when it is 44528 * empty. 44529 */ 44530 const ZWNBSP = '\ufeff'; 44531 function DefaultBlockAppender({ 44532 rootClientId 44533 }) { 44534 const { 44535 showPrompt, 44536 isLocked, 44537 placeholder 44538 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 44539 const { 44540 getBlockCount, 44541 getSettings, 44542 getTemplateLock 44543 } = select(store); 44544 const isEmpty = !getBlockCount(rootClientId); 44545 const { 44546 bodyPlaceholder 44547 } = getSettings(); 44548 return { 44549 showPrompt: isEmpty, 44550 isLocked: !!getTemplateLock(rootClientId), 44551 placeholder: bodyPlaceholder 44552 }; 44553 }, [rootClientId]); 44554 const { 44555 insertDefaultBlock, 44556 startTyping 44557 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 44558 if (isLocked) { 44559 return null; 44560 } 44561 const value = (0,external_wp_htmlEntities_namespaceObject.decodeEntities)(placeholder) || (0,external_wp_i18n_namespaceObject.__)('Type / to choose a block'); 44562 const onAppend = () => { 44563 insertDefaultBlock(undefined, rootClientId); 44564 startTyping(); 44565 }; 44566 return (0,external_React_.createElement)("div", { 44567 "data-root-client-id": rootClientId || '', 44568 className: classnames_default()('block-editor-default-block-appender', { 44569 'has-visible-prompt': showPrompt 44570 }) 44571 }, (0,external_React_.createElement)("p", { 44572 tabIndex: "0" 44573 // We want this element to be styled as a paragraph by themes. 44574 // eslint-disable-next-line jsx-a11y/no-noninteractive-element-to-interactive-role 44575 , 44576 role: "button", 44577 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Add default block') 44578 // A wrapping container for this one already has the wp-block className. 44579 , 44580 className: "block-editor-default-block-appender__content", 44581 onKeyDown: event => { 44582 if (external_wp_keycodes_namespaceObject.ENTER === event.keyCode || external_wp_keycodes_namespaceObject.SPACE === event.keyCode) { 44583 onAppend(); 44584 } 44585 }, 44586 onClick: () => onAppend(), 44587 onFocus: () => { 44588 if (showPrompt) { 44589 onAppend(); 44590 } 44591 } 44592 }, showPrompt ? value : ZWNBSP), (0,external_React_.createElement)(inserter, { 44593 rootClientId: rootClientId, 44594 position: "bottom right", 44595 isAppender: true, 44596 __experimentalIsQuick: true 44597 })); 44598 } 44599 44600 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/button-block-appender/index.js 44601 44602 /** 44603 * External dependencies 44604 */ 44605 44606 44607 /** 44608 * WordPress dependencies 44609 */ 44610 44611 44612 44613 44614 44615 44616 /** 44617 * Internal dependencies 44618 */ 44619 44620 function ButtonBlockAppender({ 44621 rootClientId, 44622 className, 44623 onFocus, 44624 tabIndex 44625 }, ref) { 44626 return (0,external_React_.createElement)(inserter, { 44627 position: "bottom center", 44628 rootClientId: rootClientId, 44629 __experimentalIsQuick: true, 44630 renderToggle: ({ 44631 onToggle, 44632 disabled, 44633 isOpen, 44634 blockTitle, 44635 hasSingleBlockType 44636 }) => { 44637 let label; 44638 if (hasSingleBlockType) { 44639 label = (0,external_wp_i18n_namespaceObject.sprintf)( 44640 // translators: %s: the name of the block when there is only one 44641 (0,external_wp_i18n_namespaceObject._x)('Add %s', 'directly add the only allowed block'), blockTitle); 44642 } else { 44643 label = (0,external_wp_i18n_namespaceObject._x)('Add block', 'Generic label for block inserter button'); 44644 } 44645 const isToggleButton = !hasSingleBlockType; 44646 let inserterButton = (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 44647 ref: ref, 44648 onFocus: onFocus, 44649 tabIndex: tabIndex, 44650 className: classnames_default()(className, 'block-editor-button-block-appender'), 44651 onClick: onToggle, 44652 "aria-haspopup": isToggleButton ? 'true' : undefined, 44653 "aria-expanded": isToggleButton ? isOpen : undefined, 44654 disabled: disabled, 44655 label: label 44656 }, !hasSingleBlockType && (0,external_React_.createElement)(external_wp_components_namespaceObject.VisuallyHidden, { 44657 as: "span" 44658 }, label), (0,external_React_.createElement)(build_module_icon, { 44659 icon: library_plus 44660 })); 44661 if (isToggleButton || hasSingleBlockType) { 44662 inserterButton = (0,external_React_.createElement)(external_wp_components_namespaceObject.Tooltip, { 44663 text: label 44664 }, inserterButton); 44665 } 44666 return inserterButton; 44667 }, 44668 isAppender: true 44669 }); 44670 } 44671 44672 /** 44673 * Use `ButtonBlockAppender` instead. 44674 * 44675 * @deprecated 44676 */ 44677 const ButtonBlockerAppender = (0,external_wp_element_namespaceObject.forwardRef)((props, ref) => { 44678 external_wp_deprecated_default()(`wp.blockEditor.ButtonBlockerAppender`, { 44679 alternative: 'wp.blockEditor.ButtonBlockAppender', 44680 since: '5.9' 44681 }); 44682 return ButtonBlockAppender(props, ref); 44683 }); 44684 44685 /** 44686 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/button-block-appender/README.md 44687 */ 44688 /* harmony default export */ const button_block_appender = ((0,external_wp_element_namespaceObject.forwardRef)(ButtonBlockAppender)); 44689 44690 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list-appender/index.js 44691 44692 /** 44693 * External dependencies 44694 */ 44695 44696 44697 /** 44698 * WordPress dependencies 44699 */ 44700 44701 44702 44703 /** 44704 * Internal dependencies 44705 */ 44706 44707 44708 44709 function DefaultAppender({ 44710 rootClientId 44711 }) { 44712 const canInsertDefaultBlock = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).canInsertBlockType((0,external_wp_blocks_namespaceObject.getDefaultBlockName)(), rootClientId)); 44713 if (canInsertDefaultBlock) { 44714 // Render the default block appender if the context supports use 44715 // of the default appender. 44716 return (0,external_React_.createElement)(DefaultBlockAppender, { 44717 rootClientId: rootClientId 44718 }); 44719 } 44720 44721 // Fallback in case the default block can't be inserted. 44722 return (0,external_React_.createElement)(button_block_appender, { 44723 rootClientId: rootClientId, 44724 className: "block-list-appender__toggle" 44725 }); 44726 } 44727 function BlockListAppender({ 44728 rootClientId, 44729 CustomAppender, 44730 className, 44731 tagName: TagName = 'div' 44732 }) { 44733 const isDragOver = (0,external_wp_data_namespaceObject.useSelect)(select => { 44734 const { 44735 getBlockInsertionPoint, 44736 isBlockInsertionPointVisible, 44737 getBlockCount 44738 } = select(store); 44739 const insertionPoint = getBlockInsertionPoint(); 44740 // Ideally we should also check for `isDragging` but currently it 44741 // requires a lot more setup. We can revisit this once we refactor 44742 // the DnD utility hooks. 44743 return isBlockInsertionPointVisible() && rootClientId === insertionPoint?.rootClientId && getBlockCount(rootClientId) === 0; 44744 }, [rootClientId]); 44745 return (0,external_React_.createElement)(TagName 44746 // A `tabIndex` is used on the wrapping `div` element in order to 44747 // force a focus event to occur when an appender `button` element 44748 // is clicked. In some browsers (Firefox, Safari), button clicks do 44749 // not emit a focus event, which could cause this event to propagate 44750 // unexpectedly. The `tabIndex` ensures that the interaction is 44751 // captured as a focus, without also adding an extra tab stop. 44752 // 44753 // See: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Clicking_and_focus 44754 , { 44755 tabIndex: -1, 44756 className: classnames_default()('block-list-appender wp-block', className, { 44757 'is-drag-over': isDragOver 44758 }) 44759 // Needed in case the whole editor is content editable (for multi 44760 // selection). It fixes an edge case where ArrowDown and ArrowRight 44761 // should collapse the selection to the end of that selection and 44762 // not into the appender. 44763 , 44764 contentEditable: false 44765 // The appender exists to let you add the first Paragraph before 44766 // any is inserted. To that end, this appender should visually be 44767 // presented as a block. That means theme CSS should style it as if 44768 // it were an empty paragraph block. That means a `wp-block` class to 44769 // ensure the width is correct, and a [data-block] attribute to ensure 44770 // the correct margin is applied, especially for classic themes which 44771 // have commonly targeted that attribute for margins. 44772 , 44773 "data-block": true 44774 }, CustomAppender ? (0,external_React_.createElement)(CustomAppender, null) : (0,external_React_.createElement)(DefaultAppender, { 44775 rootClientId: rootClientId 44776 })); 44777 } 44778 44779 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-popover/inbetween.js 44780 44781 /** 44782 * External dependencies 44783 */ 44784 44785 44786 /** 44787 * WordPress dependencies 44788 */ 44789 44790 44791 44792 44793 44794 /** 44795 * Internal dependencies 44796 */ 44797 44798 44799 44800 const inbetween_MAX_POPOVER_RECOMPUTE_COUNTER = Number.MAX_SAFE_INTEGER; 44801 const InsertionPointOpenRef = (0,external_wp_element_namespaceObject.createContext)(); 44802 function BlockPopoverInbetween({ 44803 previousClientId, 44804 nextClientId, 44805 children, 44806 __unstablePopoverSlot, 44807 __unstableContentRef, 44808 operation = 'insert', 44809 nearestSide = 'right', 44810 ...props 44811 }) { 44812 // This is a temporary hack to get the inbetween inserter to recompute properly. 44813 const [popoverRecomputeCounter, forcePopoverRecompute] = (0,external_wp_element_namespaceObject.useReducer)( 44814 // Module is there to make sure that the counter doesn't overflow. 44815 s => (s + 1) % inbetween_MAX_POPOVER_RECOMPUTE_COUNTER, 0); 44816 const { 44817 orientation, 44818 rootClientId, 44819 isVisible 44820 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 44821 const { 44822 getBlockListSettings, 44823 getBlockRootClientId, 44824 isBlockVisible 44825 } = select(store); 44826 const _rootClientId = getBlockRootClientId(previousClientId !== null && previousClientId !== void 0 ? previousClientId : nextClientId); 44827 return { 44828 orientation: getBlockListSettings(_rootClientId)?.orientation || 'vertical', 44829 rootClientId: _rootClientId, 44830 isVisible: isBlockVisible(previousClientId) && isBlockVisible(nextClientId) 44831 }; 44832 }, [previousClientId, nextClientId]); 44833 const previousElement = useBlockElement(previousClientId); 44834 const nextElement = useBlockElement(nextClientId); 44835 const isVertical = orientation === 'vertical'; 44836 const popoverAnchor = (0,external_wp_element_namespaceObject.useMemo)(() => { 44837 if ( 44838 // popoverRecomputeCounter is by definition always equal or greater than 0. 44839 // This check is only there to satisfy the correctness of the 44840 // exhaustive-deps rule for the `useMemo` hook. 44841 popoverRecomputeCounter < 0 || !previousElement && !nextElement || !isVisible) { 44842 return undefined; 44843 } 44844 const contextElement = operation === 'group' ? nextElement || previousElement : previousElement || nextElement; 44845 return { 44846 contextElement, 44847 getBoundingClientRect() { 44848 const previousRect = previousElement ? previousElement.getBoundingClientRect() : null; 44849 const nextRect = nextElement ? nextElement.getBoundingClientRect() : null; 44850 let left = 0; 44851 let top = 0; 44852 let width = 0; 44853 let height = 0; 44854 if (operation === 'group') { 44855 const targetRect = nextRect || previousRect; 44856 top = targetRect.top; 44857 // No spacing is likely around blocks in this operation. 44858 // So width of the inserter containing rect is set to 0. 44859 width = 0; 44860 height = targetRect.bottom - targetRect.top; 44861 // Popover calculates its distance from mid-block so some 44862 // adjustments are needed to make it appear in the right place. 44863 left = nearestSide === 'left' ? targetRect.left - 2 : targetRect.right - 2; 44864 } else if (isVertical) { 44865 // vertical 44866 top = previousRect ? previousRect.bottom : nextRect.top; 44867 width = previousRect ? previousRect.width : nextRect.width; 44868 height = nextRect && previousRect ? nextRect.top - previousRect.bottom : 0; 44869 left = previousRect ? previousRect.left : nextRect.left; 44870 } else { 44871 top = previousRect ? previousRect.top : nextRect.top; 44872 height = previousRect ? previousRect.height : nextRect.height; 44873 if ((0,external_wp_i18n_namespaceObject.isRTL)()) { 44874 // non vertical, rtl 44875 left = nextRect ? nextRect.right : previousRect.left; 44876 width = previousRect && nextRect ? previousRect.left - nextRect.right : 0; 44877 } else { 44878 // non vertical, ltr 44879 left = previousRect ? previousRect.right : nextRect.left; 44880 width = previousRect && nextRect ? nextRect.left - previousRect.right : 0; 44881 } 44882 } 44883 return new window.DOMRect(left, top, width, height); 44884 } 44885 }; 44886 }, [previousElement, nextElement, popoverRecomputeCounter, isVertical, isVisible, operation, nearestSide]); 44887 const popoverScrollRef = use_popover_scroll(__unstableContentRef); 44888 44889 // This is only needed for a smooth transition when moving blocks. 44890 // When blocks are moved up/down, their position can be set by 44891 // updating the `transform` property manually (i.e. without using CSS 44892 // transitions or animations). The animation, which can also scroll the block 44893 // editor, can sometimes cause the position of the Popover to get out of sync. 44894 // A MutationObserver is therefore used to make sure that changes to the 44895 // selectedElement's attribute (i.e. `transform`) can be tracked and used to 44896 // trigger the Popover to rerender. 44897 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 44898 if (!previousElement) { 44899 return; 44900 } 44901 const observer = new window.MutationObserver(forcePopoverRecompute); 44902 observer.observe(previousElement, { 44903 attributes: true 44904 }); 44905 return () => { 44906 observer.disconnect(); 44907 }; 44908 }, [previousElement]); 44909 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 44910 if (!nextElement) { 44911 return; 44912 } 44913 const observer = new window.MutationObserver(forcePopoverRecompute); 44914 observer.observe(nextElement, { 44915 attributes: true 44916 }); 44917 return () => { 44918 observer.disconnect(); 44919 }; 44920 }, [nextElement]); 44921 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 44922 if (!previousElement) { 44923 return; 44924 } 44925 previousElement.ownerDocument.defaultView.addEventListener('resize', forcePopoverRecompute); 44926 return () => { 44927 previousElement.ownerDocument.defaultView?.removeEventListener('resize', forcePopoverRecompute); 44928 }; 44929 }, [previousElement]); 44930 44931 // If there's either a previous or a next element, show the inbetween popover. 44932 // Note that drag and drop uses the inbetween popover to show the drop indicator 44933 // before the first block and after the last block. 44934 if (!previousElement && !nextElement || !isVisible) { 44935 return null; 44936 } 44937 44938 /* eslint-disable jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */ 44939 // While ideally it would be enough to capture the 44940 // bubbling focus event from the Inserter, due to the 44941 // characteristics of click focusing of `button`s in 44942 // Firefox and Safari, it is not reliable. 44943 // 44944 // See: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Clicking_and_focus 44945 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Popover, { 44946 ref: popoverScrollRef, 44947 animate: false, 44948 anchor: popoverAnchor, 44949 focusOnMount: false 44950 // Render in the old slot if needed for backward compatibility, 44951 // otherwise render in place (not in the default popover slot). 44952 , 44953 __unstableSlotName: __unstablePopoverSlot, 44954 inline: !__unstablePopoverSlot 44955 // Forces a remount of the popover when its position changes 44956 // This makes sure the popover doesn't animate from its previous position. 44957 , 44958 key: nextClientId + '--' + rootClientId, 44959 ...props, 44960 className: classnames_default()('block-editor-block-popover', 'block-editor-block-popover__inbetween', props.className), 44961 resize: false, 44962 flip: false, 44963 placement: "overlay", 44964 variant: "unstyled" 44965 }, (0,external_React_.createElement)("div", { 44966 className: "block-editor-block-popover__inbetween-container" 44967 }, children)); 44968 /* eslint-enable jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */ 44969 } 44970 /* harmony default export */ const inbetween = (BlockPopoverInbetween); 44971 44972 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-popover/drop-zone.js 44973 44974 /** 44975 * WordPress dependencies 44976 */ 44977 44978 44979 44980 44981 /** 44982 * Internal dependencies 44983 */ 44984 44985 44986 const animateVariants = { 44987 hide: { 44988 opacity: 0, 44989 scaleY: 0.75 44990 }, 44991 show: { 44992 opacity: 1, 44993 scaleY: 1 44994 }, 44995 exit: { 44996 opacity: 0, 44997 scaleY: 0.9 44998 } 44999 }; 45000 function BlockDropZonePopover({ 45001 __unstablePopoverSlot, 45002 __unstableContentRef 45003 }) { 45004 const { 45005 clientId 45006 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 45007 const { 45008 getBlockOrder, 45009 getBlockInsertionPoint 45010 } = select(store); 45011 const insertionPoint = getBlockInsertionPoint(); 45012 const order = getBlockOrder(insertionPoint.rootClientId); 45013 if (!order.length) { 45014 return {}; 45015 } 45016 return { 45017 clientId: order[insertionPoint.index] 45018 }; 45019 }, []); 45020 const reducedMotion = (0,external_wp_compose_namespaceObject.useReducedMotion)(); 45021 return (0,external_React_.createElement)(block_popover, { 45022 clientId: clientId, 45023 __unstableCoverTarget: true, 45024 __unstablePopoverSlot: __unstablePopoverSlot, 45025 __unstableContentRef: __unstableContentRef, 45026 className: "block-editor-block-popover__drop-zone" 45027 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__unstableMotion.div, { 45028 "data-testid": "block-popover-drop-zone", 45029 initial: reducedMotion ? animateVariants.show : animateVariants.hide, 45030 animate: animateVariants.show, 45031 exit: reducedMotion ? animateVariants.show : animateVariants.exit, 45032 className: "block-editor-block-popover__drop-zone-foreground" 45033 })); 45034 } 45035 /* harmony default export */ const drop_zone = (BlockDropZonePopover); 45036 45037 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-tools/insertion-point.js 45038 45039 /** 45040 * External dependencies 45041 */ 45042 45043 45044 /** 45045 * WordPress dependencies 45046 */ 45047 45048 45049 45050 45051 45052 /** 45053 * Internal dependencies 45054 */ 45055 45056 45057 45058 45059 const insertion_point_InsertionPointOpenRef = (0,external_wp_element_namespaceObject.createContext)(); 45060 function InbetweenInsertionPointPopover({ 45061 __unstablePopoverSlot, 45062 __unstableContentRef, 45063 operation = 'insert', 45064 nearestSide = 'right' 45065 }) { 45066 const { 45067 selectBlock, 45068 hideInsertionPoint 45069 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 45070 const openRef = (0,external_wp_element_namespaceObject.useContext)(insertion_point_InsertionPointOpenRef); 45071 const ref = (0,external_wp_element_namespaceObject.useRef)(); 45072 const { 45073 orientation, 45074 previousClientId, 45075 nextClientId, 45076 rootClientId, 45077 isInserterShown, 45078 isDistractionFree, 45079 isNavigationMode 45080 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 45081 const { 45082 getBlockOrder, 45083 getBlockListSettings, 45084 getBlockInsertionPoint, 45085 isBlockBeingDragged, 45086 getPreviousBlockClientId, 45087 getNextBlockClientId, 45088 getSettings, 45089 isNavigationMode: _isNavigationMode 45090 } = select(store); 45091 const insertionPoint = getBlockInsertionPoint(); 45092 const order = getBlockOrder(insertionPoint.rootClientId); 45093 if (!order.length) { 45094 return {}; 45095 } 45096 let _previousClientId = order[insertionPoint.index - 1]; 45097 let _nextClientId = order[insertionPoint.index]; 45098 while (isBlockBeingDragged(_previousClientId)) { 45099 _previousClientId = getPreviousBlockClientId(_previousClientId); 45100 } 45101 while (isBlockBeingDragged(_nextClientId)) { 45102 _nextClientId = getNextBlockClientId(_nextClientId); 45103 } 45104 const settings = getSettings(); 45105 return { 45106 previousClientId: _previousClientId, 45107 nextClientId: _nextClientId, 45108 orientation: getBlockListSettings(insertionPoint.rootClientId)?.orientation || 'vertical', 45109 rootClientId: insertionPoint.rootClientId, 45110 isNavigationMode: _isNavigationMode(), 45111 isDistractionFree: settings.isDistractionFree, 45112 isInserterShown: insertionPoint?.__unstableWithInserter 45113 }; 45114 }, []); 45115 const { 45116 getBlockEditingMode 45117 } = (0,external_wp_data_namespaceObject.useSelect)(store); 45118 const disableMotion = (0,external_wp_compose_namespaceObject.useReducedMotion)(); 45119 function onClick(event) { 45120 if (event.target === ref.current && nextClientId && getBlockEditingMode(nextClientId) !== 'disabled') { 45121 selectBlock(nextClientId, -1); 45122 } 45123 } 45124 function maybeHideInserterPoint(event) { 45125 // Only hide the inserter if it's triggered on the wrapper, 45126 // and the inserter is not open. 45127 if (event.target === ref.current && !openRef.current) { 45128 hideInsertionPoint(); 45129 } 45130 } 45131 function onFocus(event) { 45132 // Only handle click on the wrapper specifically, and not an event 45133 // bubbled from the inserter itself. 45134 if (event.target !== ref.current) { 45135 openRef.current = true; 45136 } 45137 } 45138 const lineVariants = { 45139 // Initial position starts from the center and invisible. 45140 start: { 45141 opacity: 0, 45142 scale: 0 45143 }, 45144 // The line expands to fill the container. If the inserter is visible it 45145 // is delayed so it appears orchestrated. 45146 rest: { 45147 opacity: 1, 45148 scale: 1, 45149 transition: { 45150 delay: isInserterShown ? 0.5 : 0, 45151 type: 'tween' 45152 } 45153 }, 45154 hover: { 45155 opacity: 1, 45156 scale: 1, 45157 transition: { 45158 delay: 0.5, 45159 type: 'tween' 45160 } 45161 } 45162 }; 45163 const inserterVariants = { 45164 start: { 45165 scale: disableMotion ? 1 : 0 45166 }, 45167 rest: { 45168 scale: 1, 45169 transition: { 45170 delay: 0.4, 45171 type: 'tween' 45172 } 45173 } 45174 }; 45175 if (isDistractionFree && !isNavigationMode) { 45176 return null; 45177 } 45178 const orientationClassname = orientation === 'horizontal' || operation === 'group' ? 'is-horizontal' : 'is-vertical'; 45179 const className = classnames_default()('block-editor-block-list__insertion-point', orientationClassname); 45180 return (0,external_React_.createElement)(inbetween, { 45181 previousClientId: previousClientId, 45182 nextClientId: nextClientId, 45183 __unstablePopoverSlot: __unstablePopoverSlot, 45184 __unstableContentRef: __unstableContentRef, 45185 operation: operation, 45186 nearestSide: nearestSide 45187 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__unstableMotion.div, { 45188 layout: !disableMotion, 45189 initial: disableMotion ? 'rest' : 'start', 45190 animate: "rest", 45191 whileHover: "hover", 45192 whileTap: "pressed", 45193 exit: "start", 45194 ref: ref, 45195 tabIndex: -1, 45196 onClick: onClick, 45197 onFocus: onFocus, 45198 className: classnames_default()(className, { 45199 'is-with-inserter': isInserterShown 45200 }), 45201 onHoverEnd: maybeHideInserterPoint 45202 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__unstableMotion.div, { 45203 variants: lineVariants, 45204 className: "block-editor-block-list__insertion-point-indicator", 45205 "data-testid": "block-list-insertion-point-indicator" 45206 }), isInserterShown && (0,external_React_.createElement)(external_wp_components_namespaceObject.__unstableMotion.div, { 45207 variants: inserterVariants, 45208 className: classnames_default()('block-editor-block-list__insertion-point-inserter') 45209 }, (0,external_React_.createElement)(inserter, { 45210 position: "bottom center", 45211 clientId: nextClientId, 45212 rootClientId: rootClientId, 45213 __experimentalIsQuick: true, 45214 onToggle: isOpen => { 45215 openRef.current = isOpen; 45216 }, 45217 onSelectOrClose: () => { 45218 openRef.current = false; 45219 } 45220 })))); 45221 } 45222 function InsertionPoint(props) { 45223 const { 45224 insertionPoint, 45225 isVisible, 45226 isBlockListEmpty 45227 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 45228 const { 45229 getBlockInsertionPoint, 45230 isBlockInsertionPointVisible, 45231 getBlockCount 45232 } = select(store); 45233 const blockInsertionPoint = getBlockInsertionPoint(); 45234 return { 45235 insertionPoint: blockInsertionPoint, 45236 isVisible: isBlockInsertionPointVisible(), 45237 isBlockListEmpty: getBlockCount(blockInsertionPoint?.rootClientId) === 0 45238 }; 45239 }, []); 45240 if (!isVisible || 45241 // Don't render the insertion point if the block list is empty. 45242 // The insertion point will be represented by the appender instead. 45243 isBlockListEmpty) { 45244 return null; 45245 } 45246 45247 /** 45248 * Render a popover that overlays the block when the desired operation is to replace it. 45249 * Otherwise, render a popover in between blocks for the indication of inserting between them. 45250 */ 45251 return insertionPoint.operation === 'replace' ? (0,external_React_.createElement)(drop_zone 45252 // Force remount to trigger the animation. 45253 , { 45254 key: `$insertionPoint.rootClientId}-$insertionPoint.index}`, 45255 ...props 45256 }) : (0,external_React_.createElement)(InbetweenInsertionPointPopover, { 45257 operation: insertionPoint.operation, 45258 nearestSide: insertionPoint.nearestSide, 45259 ...props 45260 }); 45261 } 45262 45263 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-in-between-inserter.js 45264 /** 45265 * WordPress dependencies 45266 */ 45267 45268 45269 45270 45271 45272 /** 45273 * Internal dependencies 45274 */ 45275 45276 45277 function useInBetweenInserter() { 45278 const openRef = (0,external_wp_element_namespaceObject.useContext)(insertion_point_InsertionPointOpenRef); 45279 const isInBetweenInserterDisabled = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getSettings().isDistractionFree || select(store).__unstableGetEditorMode() === 'zoom-out', []); 45280 const { 45281 getBlockListSettings, 45282 getBlockIndex, 45283 isMultiSelecting, 45284 getSelectedBlockClientIds, 45285 getTemplateLock, 45286 __unstableIsWithinBlockOverlay, 45287 getBlockEditingMode, 45288 getBlockName 45289 } = (0,external_wp_data_namespaceObject.useSelect)(store); 45290 const { 45291 showInsertionPoint, 45292 hideInsertionPoint 45293 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 45294 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 45295 if (isInBetweenInserterDisabled) { 45296 return; 45297 } 45298 function onMouseMove(event) { 45299 if (openRef.current) { 45300 return; 45301 } 45302 45303 // Ignore text nodes sometimes detected in FireFox. 45304 if (event.target.nodeType === event.target.TEXT_NODE) { 45305 return; 45306 } 45307 if (isMultiSelecting()) { 45308 return; 45309 } 45310 if (!event.target.classList.contains('block-editor-block-list__layout')) { 45311 hideInsertionPoint(); 45312 return; 45313 } 45314 let rootClientId; 45315 if (!event.target.classList.contains('is-root-container')) { 45316 const blockElement = !!event.target.getAttribute('data-block') ? event.target : event.target.closest('[data-block]'); 45317 rootClientId = blockElement.getAttribute('data-block'); 45318 } 45319 if (getTemplateLock(rootClientId) || getBlockEditingMode(rootClientId) === 'disabled' || getBlockName(rootClientId) === 'core/block') { 45320 return; 45321 } 45322 const orientation = getBlockListSettings(rootClientId)?.orientation || 'vertical'; 45323 const offsetTop = event.clientY; 45324 const offsetLeft = event.clientX; 45325 const children = Array.from(event.target.children); 45326 let element = children.find(blockEl => { 45327 const blockElRect = blockEl.getBoundingClientRect(); 45328 return blockEl.classList.contains('wp-block') && orientation === 'vertical' && blockElRect.top > offsetTop || blockEl.classList.contains('wp-block') && orientation === 'horizontal' && ((0,external_wp_i18n_namespaceObject.isRTL)() ? blockElRect.right < offsetLeft : blockElRect.left > offsetLeft); 45329 }); 45330 if (!element) { 45331 hideInsertionPoint(); 45332 return; 45333 } 45334 45335 // The block may be in an alignment wrapper, so check the first direct 45336 // child if the element has no ID. 45337 if (!element.id) { 45338 element = element.firstElementChild; 45339 if (!element) { 45340 hideInsertionPoint(); 45341 return; 45342 } 45343 } 45344 45345 // Don't show the insertion point if a parent block has an "overlay" 45346 // See https://github.com/WordPress/gutenberg/pull/34012#pullrequestreview-727762337 45347 const clientId = element.id.slice('block-'.length); 45348 if (!clientId || __unstableIsWithinBlockOverlay(clientId)) { 45349 return; 45350 } 45351 45352 // Don't show the inserter when hovering above (conflicts with 45353 // block toolbar) or inside selected block(s). 45354 if (getSelectedBlockClientIds().includes(clientId)) { 45355 return; 45356 } 45357 const elementRect = element.getBoundingClientRect(); 45358 if (orientation === 'horizontal' && (event.clientY > elementRect.bottom || event.clientY < elementRect.top) || orientation === 'vertical' && (event.clientX > elementRect.right || event.clientX < elementRect.left)) { 45359 hideInsertionPoint(); 45360 return; 45361 } 45362 const index = getBlockIndex(clientId); 45363 45364 // Don't show the in-between inserter before the first block in 45365 // the list (preserves the original behaviour). 45366 if (index === 0) { 45367 hideInsertionPoint(); 45368 return; 45369 } 45370 showInsertionPoint(rootClientId, index, { 45371 __unstableWithInserter: true 45372 }); 45373 } 45374 node.addEventListener('mousemove', onMouseMove); 45375 return () => { 45376 node.removeEventListener('mousemove', onMouseMove); 45377 }; 45378 }, [openRef, getBlockListSettings, getBlockIndex, isMultiSelecting, showInsertionPoint, hideInsertionPoint, getSelectedBlockClientIds, isInBetweenInserterDisabled]); 45379 } 45380 45381 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inner-blocks/with-client-id.js 45382 45383 /** 45384 * WordPress dependencies 45385 */ 45386 45387 45388 /** 45389 * Internal dependencies 45390 */ 45391 45392 const withClientId = (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(WrappedComponent => props => { 45393 const { 45394 clientId 45395 } = useBlockEditContext(); 45396 return (0,external_React_.createElement)(WrappedComponent, { 45397 ...props, 45398 clientId: clientId 45399 }); 45400 }, 'withClientId'); 45401 /* harmony default export */ const with_client_id = (withClientId); 45402 45403 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inner-blocks/button-block-appender.js 45404 45405 /** 45406 * External dependencies 45407 */ 45408 45409 45410 /** 45411 * Internal dependencies 45412 */ 45413 45414 45415 const button_block_appender_ButtonBlockAppender = ({ 45416 clientId, 45417 showSeparator, 45418 isFloating, 45419 onAddBlock, 45420 isToggle 45421 }) => { 45422 return (0,external_React_.createElement)(button_block_appender, { 45423 className: classnames_default()({ 45424 'block-list-appender__toggle': isToggle 45425 }), 45426 rootClientId: clientId, 45427 showSeparator: showSeparator, 45428 isFloating: isFloating, 45429 onAddBlock: onAddBlock 45430 }); 45431 }; 45432 /* harmony default export */ const inner_blocks_button_block_appender = (with_client_id(button_block_appender_ButtonBlockAppender)); 45433 45434 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inner-blocks/default-block-appender.js 45435 45436 /** 45437 * WordPress dependencies 45438 */ 45439 45440 45441 45442 /** 45443 * Internal dependencies 45444 */ 45445 45446 45447 45448 const default_block_appender_DefaultBlockAppender = ({ 45449 clientId 45450 }) => { 45451 return (0,external_React_.createElement)(DefaultBlockAppender, { 45452 rootClientId: clientId 45453 }); 45454 }; 45455 /* harmony default export */ const default_block_appender = ((0,external_wp_compose_namespaceObject.compose)([with_client_id, (0,external_wp_data_namespaceObject.withSelect)((select, { 45456 clientId 45457 }) => { 45458 const { 45459 getBlockOrder 45460 } = select(store); 45461 const blockClientIds = getBlockOrder(clientId); 45462 return { 45463 lastBlockClientId: blockClientIds[blockClientIds.length - 1] 45464 }; 45465 })])(default_block_appender_DefaultBlockAppender)); 45466 45467 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inner-blocks/use-nested-settings-update.js 45468 /** 45469 * WordPress dependencies 45470 */ 45471 45472 45473 45474 45475 45476 /** 45477 * Internal dependencies 45478 */ 45479 45480 45481 45482 /** @typedef {import('../../selectors').WPDirectInsertBlock } WPDirectInsertBlock */ 45483 45484 const pendingSettingsUpdates = new WeakMap(); 45485 function useShallowMemo(value) { 45486 const [prevValue, setPrevValue] = (0,external_wp_element_namespaceObject.useState)(value); 45487 if (!external_wp_isShallowEqual_default()(prevValue, value)) { 45488 setPrevValue(value); 45489 } 45490 return prevValue; 45491 } 45492 45493 /** 45494 * This hook is a side effect which updates the block-editor store when changes 45495 * happen to inner block settings. The given props are transformed into a 45496 * settings object, and if that is different from the current settings object in 45497 * the block-editor store, then the store is updated with the new settings which 45498 * came from props. 45499 * 45500 * @param {string} clientId The client ID of the block to update. 45501 * @param {string} parentLock 45502 * @param {string[]} allowedBlocks An array of block names which are permitted 45503 * in inner blocks. 45504 * @param {string[]} prioritizedInserterBlocks Block names and/or block variations to be prioritized in the inserter, in the format {blockName}/{variationName}. 45505 * @param {?WPDirectInsertBlock} defaultBlock The default block to insert: [ blockName, { blockAttributes } ]. 45506 * @param {?Function|boolean} directInsert If a default block should be inserted directly by the appender. 45507 * 45508 * @param {?WPDirectInsertBlock} __experimentalDefaultBlock A deprecated prop for the default block to insert: [ blockName, { blockAttributes } ]. Use `defaultBlock` instead. 45509 * 45510 * @param {?Function|boolean} __experimentalDirectInsert A deprecated prop for whether a default block should be inserted directly by the appender. Use `directInsert` instead. 45511 * 45512 * @param {string} [templateLock] The template lock specified for the inner 45513 * blocks component. (e.g. "all") 45514 * @param {boolean} captureToolbars Whether or children toolbars should be shown 45515 * in the inner blocks component rather than on 45516 * the child block. 45517 * @param {string} orientation The direction in which the block 45518 * should face. 45519 * @param {Object} layout The layout object for the block container. 45520 */ 45521 function useNestedSettingsUpdate(clientId, parentLock, allowedBlocks, prioritizedInserterBlocks, defaultBlock, directInsert, __experimentalDefaultBlock, __experimentalDirectInsert, templateLock, captureToolbars, orientation, layout) { 45522 // Instead of adding a useSelect mapping here, please add to the useSelect 45523 // mapping in InnerBlocks! Every subscription impacts performance. 45524 45525 const { 45526 updateBlockListSettings 45527 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 45528 const registry = (0,external_wp_data_namespaceObject.useRegistry)(); 45529 45530 // Implementors often pass a new array on every render, 45531 // and the contents of the arrays are just strings, so the entire array 45532 // can be passed as dependencies but We need to include the length of the array, 45533 // otherwise if the arrays change length but the first elements are equal the comparison, 45534 // does not works as expected. 45535 const _allowedBlocks = useShallowMemo(allowedBlocks); 45536 const _prioritizedInserterBlocks = (0,external_wp_element_namespaceObject.useMemo)(() => prioritizedInserterBlocks, 45537 // eslint-disable-next-line react-hooks/exhaustive-deps 45538 prioritizedInserterBlocks); 45539 const _templateLock = templateLock === undefined || parentLock === 'contentOnly' ? parentLock : templateLock; 45540 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 45541 const newSettings = { 45542 allowedBlocks: _allowedBlocks, 45543 prioritizedInserterBlocks: _prioritizedInserterBlocks, 45544 templateLock: _templateLock 45545 }; 45546 45547 // These values are not defined for RN, so only include them if they 45548 // are defined. 45549 if (captureToolbars !== undefined) { 45550 newSettings.__experimentalCaptureToolbars = captureToolbars; 45551 } 45552 45553 // Orientation depends on layout, 45554 // ideally the separate orientation prop should be deprecated. 45555 if (orientation !== undefined) { 45556 newSettings.orientation = orientation; 45557 } else { 45558 const layoutType = getLayoutType(layout?.type); 45559 newSettings.orientation = layoutType.getOrientation(layout); 45560 } 45561 if (__experimentalDefaultBlock !== undefined) { 45562 external_wp_deprecated_default()('__experimentalDefaultBlock', { 45563 alternative: 'defaultBlock', 45564 since: '6.3', 45565 version: '6.4' 45566 }); 45567 newSettings.defaultBlock = __experimentalDefaultBlock; 45568 } 45569 if (defaultBlock !== undefined) { 45570 newSettings.defaultBlock = defaultBlock; 45571 } 45572 if (__experimentalDirectInsert !== undefined) { 45573 external_wp_deprecated_default()('__experimentalDirectInsert', { 45574 alternative: 'directInsert', 45575 since: '6.3', 45576 version: '6.4' 45577 }); 45578 newSettings.directInsert = __experimentalDirectInsert; 45579 } 45580 if (directInsert !== undefined) { 45581 newSettings.directInsert = directInsert; 45582 } 45583 45584 // Batch updates to block list settings to avoid triggering cascading renders 45585 // for each container block included in a tree and optimize initial render. 45586 // To avoid triggering updateBlockListSettings for each container block 45587 // causing X re-renderings for X container blocks, 45588 // we batch all the updatedBlockListSettings in a single "data" batch 45589 // which results in a single re-render. 45590 if (!pendingSettingsUpdates.get(registry)) { 45591 pendingSettingsUpdates.set(registry, []); 45592 } 45593 pendingSettingsUpdates.get(registry).push([clientId, newSettings]); 45594 window.queueMicrotask(() => { 45595 if (pendingSettingsUpdates.get(registry)?.length) { 45596 registry.batch(() => { 45597 pendingSettingsUpdates.get(registry).forEach(args => { 45598 updateBlockListSettings(...args); 45599 }); 45600 pendingSettingsUpdates.set(registry, []); 45601 }); 45602 } 45603 }); 45604 }, [clientId, _allowedBlocks, _prioritizedInserterBlocks, _templateLock, defaultBlock, directInsert, __experimentalDefaultBlock, __experimentalDirectInsert, captureToolbars, orientation, updateBlockListSettings, layout, registry]); 45605 } 45606 45607 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inner-blocks/use-inner-block-template-sync.js 45608 /** 45609 * External dependencies 45610 */ 45611 45612 45613 /** 45614 * WordPress dependencies 45615 */ 45616 45617 45618 45619 45620 /** 45621 * Internal dependencies 45622 */ 45623 45624 45625 /** 45626 * This hook makes sure that a block's inner blocks stay in sync with the given 45627 * block "template". The template is a block hierarchy to which inner blocks must 45628 * conform. If the blocks get "out of sync" with the template and the template 45629 * is meant to be locked (e.g. templateLock = "all" or templateLock = "contentOnly"), 45630 * then we replace the inner blocks with the correct value after synchronizing it with the template. 45631 * 45632 * @param {string} clientId The block client ID. 45633 * @param {Object} template The template to match. 45634 * @param {string} templateLock The template lock state for the inner blocks. For 45635 * example, if the template lock is set to "all", 45636 * then the inner blocks will stay in sync with the 45637 * template. If not defined or set to false, then 45638 * the inner blocks will not be synchronized with 45639 * the given template. 45640 * @param {boolean} templateInsertUpdatesSelection Whether or not to update the 45641 * block-editor selection state when inner blocks 45642 * are replaced after template synchronization. 45643 */ 45644 function useInnerBlockTemplateSync(clientId, template, templateLock, templateInsertUpdatesSelection) { 45645 // Instead of adding a useSelect mapping here, please add to the useSelect 45646 // mapping in InnerBlocks! Every subscription impacts performance. 45647 45648 const { 45649 getBlocks, 45650 getSelectedBlocksInitialCaretPosition, 45651 isBlockSelected 45652 } = (0,external_wp_data_namespaceObject.useSelect)(store); 45653 const { 45654 replaceInnerBlocks, 45655 __unstableMarkNextChangeAsNotPersistent 45656 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 45657 45658 // Maintain a reference to the previous value so we can do a deep equality check. 45659 const existingTemplate = (0,external_wp_element_namespaceObject.useRef)(null); 45660 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 45661 let isCancelled = false; 45662 45663 // There's an implicit dependency between useInnerBlockTemplateSync and useNestedSettingsUpdate 45664 // The former needs to happen after the latter and since the latter is using microtasks to batch updates (performance optimization), 45665 // we need to schedule this one in a microtask as well. 45666 // Example: If you remove queueMicrotask here, ctrl + click to insert quote block won't close the inserter. 45667 window.queueMicrotask(() => { 45668 if (isCancelled) { 45669 return; 45670 } 45671 45672 // Only synchronize innerBlocks with template if innerBlocks are empty 45673 // or a locking "all" or "contentOnly" exists directly on the block. 45674 const currentInnerBlocks = getBlocks(clientId); 45675 const shouldApplyTemplate = currentInnerBlocks.length === 0 || templateLock === 'all' || templateLock === 'contentOnly'; 45676 const hasTemplateChanged = !es6_default()(template, existingTemplate.current); 45677 if (!shouldApplyTemplate || !hasTemplateChanged) { 45678 return; 45679 } 45680 existingTemplate.current = template; 45681 const nextBlocks = (0,external_wp_blocks_namespaceObject.synchronizeBlocksWithTemplate)(currentInnerBlocks, template); 45682 if (!es6_default()(nextBlocks, currentInnerBlocks)) { 45683 __unstableMarkNextChangeAsNotPersistent(); 45684 replaceInnerBlocks(clientId, nextBlocks, currentInnerBlocks.length === 0 && templateInsertUpdatesSelection && nextBlocks.length !== 0 && isBlockSelected(clientId), 45685 // This ensures the "initialPosition" doesn't change when applying the template 45686 // If we're supposed to focus the block, we'll focus the first inner block 45687 // otherwise, we won't apply any auto-focus. 45688 // This ensures for instance that the focus stays in the inserter when inserting the "buttons" block. 45689 getSelectedBlocksInitialCaretPosition()); 45690 } 45691 }); 45692 return () => { 45693 isCancelled = true; 45694 }; 45695 }, [template, templateLock, clientId]); 45696 } 45697 45698 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inner-blocks/use-block-context.js 45699 /** 45700 * WordPress dependencies 45701 */ 45702 45703 45704 45705 /** 45706 * Internal dependencies 45707 */ 45708 45709 45710 /** 45711 * Returns a context object for a given block. 45712 * 45713 * @param {string} clientId The block client ID. 45714 * 45715 * @return {Record<string,*>} Context value. 45716 */ 45717 function useBlockContext(clientId) { 45718 return (0,external_wp_data_namespaceObject.useSelect)(select => { 45719 const block = select(store).getBlock(clientId); 45720 if (!block) { 45721 return undefined; 45722 } 45723 const blockType = select(external_wp_blocks_namespaceObject.store).getBlockType(block.name); 45724 if (!blockType) { 45725 return undefined; 45726 } 45727 if (Object.keys(blockType.providesContext).length === 0) { 45728 return undefined; 45729 } 45730 return Object.fromEntries(Object.entries(blockType.providesContext).map(([contextName, attributeName]) => [contextName, block.attributes[attributeName]])); 45731 }, [clientId]); 45732 } 45733 45734 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/use-on-block-drop/index.js 45735 /** 45736 * WordPress dependencies 45737 */ 45738 45739 45740 45741 45742 45743 /** 45744 * Internal dependencies 45745 */ 45746 45747 45748 /** @typedef {import('react').SyntheticEvent} SyntheticEvent */ 45749 /** @typedef {import('./types').WPDropOperation} WPDropOperation */ 45750 45751 /** 45752 * Retrieve the data for a block drop event. 45753 * 45754 * @param {SyntheticEvent} event The drop event. 45755 * 45756 * @return {Object} An object with block drag and drop data. 45757 */ 45758 function parseDropEvent(event) { 45759 let result = { 45760 srcRootClientId: null, 45761 srcClientIds: null, 45762 srcIndex: null, 45763 type: null, 45764 blocks: null 45765 }; 45766 if (!event.dataTransfer) { 45767 return result; 45768 } 45769 try { 45770 result = Object.assign(result, JSON.parse(event.dataTransfer.getData('wp-blocks'))); 45771 } catch (err) { 45772 return result; 45773 } 45774 return result; 45775 } 45776 45777 /** 45778 * A function that returns an event handler function for block drop events. 45779 * 45780 * @param {string} targetRootClientId The root client id where the block(s) will be inserted. 45781 * @param {number} targetBlockIndex The index where the block(s) will be inserted. 45782 * @param {Function} getBlockIndex A function that gets the index of a block. 45783 * @param {Function} getClientIdsOfDescendants A function that gets the client ids of descendant blocks. 45784 * @param {Function} moveBlocks A function that moves blocks. 45785 * @param {Function} insertOrReplaceBlocks A function that inserts or replaces blocks. 45786 * @param {Function} clearSelectedBlock A function that clears block selection. 45787 * @param {string} operation The type of operation to perform on drop. Could be `insert` or `replace` or `group`. 45788 * @param {Function} getBlock A function that returns a block given its client id. 45789 * @return {Function} The event handler for a block drop event. 45790 */ 45791 function onBlockDrop(targetRootClientId, targetBlockIndex, getBlockIndex, getClientIdsOfDescendants, moveBlocks, insertOrReplaceBlocks, clearSelectedBlock, operation, getBlock) { 45792 return event => { 45793 const { 45794 srcRootClientId: sourceRootClientId, 45795 srcClientIds: sourceClientIds, 45796 type: dropType, 45797 blocks 45798 } = parseDropEvent(event); 45799 45800 // If the user is inserting a block. 45801 if (dropType === 'inserter') { 45802 clearSelectedBlock(); 45803 const blocksToInsert = blocks.map(block => (0,external_wp_blocks_namespaceObject.cloneBlock)(block)); 45804 insertOrReplaceBlocks(blocksToInsert, true, null); 45805 } 45806 45807 // If the user is moving a block. 45808 if (dropType === 'block') { 45809 const sourceBlockIndex = getBlockIndex(sourceClientIds[0]); 45810 45811 // If the user is dropping to the same position, return early. 45812 if (sourceRootClientId === targetRootClientId && sourceBlockIndex === targetBlockIndex) { 45813 return; 45814 } 45815 45816 // If the user is attempting to drop a block within its own 45817 // nested blocks, return early as this would create infinite 45818 // recursion. 45819 if (sourceClientIds.includes(targetRootClientId) || getClientIdsOfDescendants(sourceClientIds).some(id => id === targetRootClientId)) { 45820 return; 45821 } 45822 45823 // If the user is dropping a block over another block, replace both blocks 45824 // with a group block containing them 45825 if (operation === 'group') { 45826 const blocksToInsert = sourceClientIds.map(clientId => getBlock(clientId)); 45827 insertOrReplaceBlocks(blocksToInsert, true, null, sourceClientIds); 45828 return; 45829 } 45830 const isAtSameLevel = sourceRootClientId === targetRootClientId; 45831 const draggedBlockCount = sourceClientIds.length; 45832 45833 // If the block is kept at the same level and moved downwards, 45834 // subtract to take into account that the blocks being dragged 45835 // were removed from the block list above the insertion point. 45836 const insertIndex = isAtSameLevel && sourceBlockIndex < targetBlockIndex ? targetBlockIndex - draggedBlockCount : targetBlockIndex; 45837 moveBlocks(sourceClientIds, sourceRootClientId, insertIndex); 45838 } 45839 }; 45840 } 45841 45842 /** 45843 * A function that returns an event handler function for block-related file drop events. 45844 * 45845 * @param {string} targetRootClientId The root client id where the block(s) will be inserted. 45846 * @param {Function} getSettings A function that gets the block editor settings. 45847 * @param {Function} updateBlockAttributes A function that updates a block's attributes. 45848 * @param {Function} canInsertBlockType A function that returns checks whether a block type can be inserted. 45849 * @param {Function} insertOrReplaceBlocks A function that inserts or replaces blocks. 45850 * 45851 * @return {Function} The event handler for a block-related file drop event. 45852 */ 45853 function onFilesDrop(targetRootClientId, getSettings, updateBlockAttributes, canInsertBlockType, insertOrReplaceBlocks) { 45854 return files => { 45855 if (!getSettings().mediaUpload) { 45856 return; 45857 } 45858 const transformation = (0,external_wp_blocks_namespaceObject.findTransform)((0,external_wp_blocks_namespaceObject.getBlockTransforms)('from'), transform => transform.type === 'files' && canInsertBlockType(transform.blockName, targetRootClientId) && transform.isMatch(files)); 45859 if (transformation) { 45860 const blocks = transformation.transform(files, updateBlockAttributes); 45861 insertOrReplaceBlocks(blocks); 45862 } 45863 }; 45864 } 45865 45866 /** 45867 * A function that returns an event handler function for block-related HTML drop events. 45868 * 45869 * @param {Function} insertOrReplaceBlocks A function that inserts or replaces blocks. 45870 * 45871 * @return {Function} The event handler for a block-related HTML drop event. 45872 */ 45873 function onHTMLDrop(insertOrReplaceBlocks) { 45874 return HTML => { 45875 const blocks = (0,external_wp_blocks_namespaceObject.pasteHandler)({ 45876 HTML, 45877 mode: 'BLOCKS' 45878 }); 45879 if (blocks.length) { 45880 insertOrReplaceBlocks(blocks); 45881 } 45882 }; 45883 } 45884 45885 /** 45886 * A React hook for handling block drop events. 45887 * 45888 * @param {string} targetRootClientId The root client id where the block(s) will be inserted. 45889 * @param {number} targetBlockIndex The index where the block(s) will be inserted. 45890 * @param {Object} options The optional options. 45891 * @param {WPDropOperation} [options.operation] The type of operation to perform on drop. Could be `insert` or `replace` for now. 45892 * 45893 * @return {Function} A function to be passed to the onDrop handler. 45894 */ 45895 function useOnBlockDrop(targetRootClientId, targetBlockIndex, options = {}) { 45896 const { 45897 operation = 'insert', 45898 nearestSide = 'right' 45899 } = options; 45900 const { 45901 canInsertBlockType, 45902 getBlockIndex, 45903 getClientIdsOfDescendants, 45904 getBlockOrder, 45905 getBlocksByClientId, 45906 getSettings, 45907 getBlock, 45908 isGroupable 45909 } = (0,external_wp_data_namespaceObject.useSelect)(store); 45910 const { 45911 getGroupingBlockName 45912 } = (0,external_wp_data_namespaceObject.useSelect)(external_wp_blocks_namespaceObject.store); 45913 const { 45914 insertBlocks, 45915 moveBlocksToPosition, 45916 updateBlockAttributes, 45917 clearSelectedBlock, 45918 replaceBlocks, 45919 removeBlocks 45920 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 45921 const registry = (0,external_wp_data_namespaceObject.useRegistry)(); 45922 const insertOrReplaceBlocks = (0,external_wp_element_namespaceObject.useCallback)((blocks, updateSelection = true, initialPosition = 0, clientIdsToReplace = []) => { 45923 if (!Array.isArray(blocks)) blocks = [blocks]; 45924 const clientIds = getBlockOrder(targetRootClientId); 45925 const clientId = clientIds[targetBlockIndex]; 45926 const blocksClientIds = blocks.map(block => block.clientId); 45927 const areGroupableBlocks = isGroupable([...blocksClientIds, clientId]); 45928 if (operation === 'replace') { 45929 replaceBlocks(clientId, blocks, undefined, initialPosition); 45930 } else if (operation === 'group' && areGroupableBlocks) { 45931 const targetBlock = getBlock(clientId); 45932 if (nearestSide === 'left') { 45933 blocks.push(targetBlock); 45934 } else { 45935 blocks.unshift(targetBlock); 45936 } 45937 const groupInnerBlocks = blocks.map(block => { 45938 return (0,external_wp_blocks_namespaceObject.createBlock)(block.name, block.attributes, block.innerBlocks); 45939 }); 45940 const areAllImages = blocks.every(block => { 45941 return block.name === 'core/image'; 45942 }); 45943 const galleryBlock = canInsertBlockType('core/gallery', targetRootClientId); 45944 const wrappedBlocks = (0,external_wp_blocks_namespaceObject.createBlock)(areAllImages && galleryBlock ? 'core/gallery' : getGroupingBlockName(), { 45945 layout: { 45946 type: 'flex', 45947 flexWrap: areAllImages && galleryBlock ? null : 'nowrap' 45948 } 45949 }, groupInnerBlocks); 45950 // Need to make sure both the target block and the block being dragged are replaced 45951 // otherwise the dragged block will be duplicated. 45952 replaceBlocks([clientId, ...clientIdsToReplace], wrappedBlocks, undefined, initialPosition); 45953 } else { 45954 insertBlocks(blocks, targetBlockIndex, targetRootClientId, updateSelection, initialPosition); 45955 } 45956 }, [getBlockOrder, targetRootClientId, targetBlockIndex, isGroupable, operation, replaceBlocks, getBlock, nearestSide, canInsertBlockType, getGroupingBlockName, insertBlocks]); 45957 const moveBlocks = (0,external_wp_element_namespaceObject.useCallback)((sourceClientIds, sourceRootClientId, insertIndex) => { 45958 if (operation === 'replace') { 45959 const sourceBlocks = getBlocksByClientId(sourceClientIds); 45960 const targetBlockClientIds = getBlockOrder(targetRootClientId); 45961 const targetBlockClientId = targetBlockClientIds[targetBlockIndex]; 45962 registry.batch(() => { 45963 // Remove the source blocks. 45964 removeBlocks(sourceClientIds, false); 45965 // Replace the target block with the source blocks. 45966 replaceBlocks(targetBlockClientId, sourceBlocks, undefined, 0); 45967 }); 45968 } else { 45969 moveBlocksToPosition(sourceClientIds, sourceRootClientId, targetRootClientId, insertIndex); 45970 } 45971 }, [operation, getBlockOrder, getBlocksByClientId, moveBlocksToPosition, registry, removeBlocks, replaceBlocks, targetBlockIndex, targetRootClientId]); 45972 const _onDrop = onBlockDrop(targetRootClientId, targetBlockIndex, getBlockIndex, getClientIdsOfDescendants, moveBlocks, insertOrReplaceBlocks, clearSelectedBlock, operation, getBlock); 45973 const _onFilesDrop = onFilesDrop(targetRootClientId, getSettings, updateBlockAttributes, canInsertBlockType, insertOrReplaceBlocks); 45974 const _onHTMLDrop = onHTMLDrop(insertOrReplaceBlocks); 45975 return event => { 45976 const files = (0,external_wp_dom_namespaceObject.getFilesFromDataTransfer)(event.dataTransfer); 45977 const html = event.dataTransfer.getData('text/html'); 45978 45979 /** 45980 * From Windows Chrome 96, the `event.dataTransfer` returns both file object and HTML. 45981 * The order of the checks is important to recognise the HTML drop. 45982 */ 45983 if (html) { 45984 _onHTMLDrop(html); 45985 } else if (files.length) { 45986 _onFilesDrop(files); 45987 } else { 45988 _onDrop(event); 45989 } 45990 }; 45991 } 45992 45993 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/math.js 45994 /** 45995 * A string representing the name of an edge. 45996 * 45997 * @typedef {'top'|'right'|'bottom'|'left'} WPEdgeName 45998 */ 45999 46000 /** 46001 * @typedef {Object} WPPoint 46002 * @property {number} x The horizontal position. 46003 * @property {number} y The vertical position. 46004 */ 46005 46006 /** 46007 * Given a point, a DOMRect and the name of an edge, returns the distance to 46008 * that edge of the rect. 46009 * 46010 * This function works for edges that are horizontal or vertical (e.g. not 46011 * rotated), the following terms are used so that the function works in both 46012 * orientations: 46013 * 46014 * - Forward, meaning the axis running horizontally when an edge is vertical 46015 * and vertically when an edge is horizontal. 46016 * - Lateral, meaning the axis running vertically when an edge is vertical 46017 * and horizontally when an edge is horizontal. 46018 * 46019 * @param {WPPoint} point The point to measure distance from. 46020 * @param {DOMRect} rect A DOM Rect containing edge positions. 46021 * @param {WPEdgeName} edge The edge to measure to. 46022 */ 46023 function getDistanceFromPointToEdge(point, rect, edge) { 46024 const isHorizontal = edge === 'top' || edge === 'bottom'; 46025 const { 46026 x, 46027 y 46028 } = point; 46029 const pointLateralPosition = isHorizontal ? x : y; 46030 const pointForwardPosition = isHorizontal ? y : x; 46031 const edgeStart = isHorizontal ? rect.left : rect.top; 46032 const edgeEnd = isHorizontal ? rect.right : rect.bottom; 46033 const edgeForwardPosition = rect[edge]; 46034 46035 // Measure the straight line distance to the edge of the rect, when the 46036 // point is adjacent to the edge. 46037 // Else, if the point is positioned diagonally to the edge of the rect, 46038 // measure diagonally to the nearest corner that the edge meets. 46039 let edgeLateralPosition; 46040 if (pointLateralPosition >= edgeStart && pointLateralPosition <= edgeEnd) { 46041 edgeLateralPosition = pointLateralPosition; 46042 } else if (pointLateralPosition < edgeEnd) { 46043 edgeLateralPosition = edgeStart; 46044 } else { 46045 edgeLateralPosition = edgeEnd; 46046 } 46047 return Math.sqrt((pointLateralPosition - edgeLateralPosition) ** 2 + (pointForwardPosition - edgeForwardPosition) ** 2); 46048 } 46049 46050 /** 46051 * Given a point, a DOMRect and a list of allowed edges returns the name of and 46052 * distance to the nearest edge. 46053 * 46054 * @param {WPPoint} point The point to measure distance from. 46055 * @param {DOMRect} rect A DOM Rect containing edge positions. 46056 * @param {WPEdgeName[]} allowedEdges A list of the edges included in the 46057 * calculation. Defaults to all edges. 46058 * 46059 * @return {[number, string]} An array where the first value is the distance 46060 * and a second is the edge name. 46061 */ 46062 function getDistanceToNearestEdge(point, rect, allowedEdges = ['top', 'bottom', 'left', 'right']) { 46063 let candidateDistance; 46064 let candidateEdge; 46065 allowedEdges.forEach(edge => { 46066 const distance = getDistanceFromPointToEdge(point, rect, edge); 46067 if (candidateDistance === undefined || distance < candidateDistance) { 46068 candidateDistance = distance; 46069 candidateEdge = edge; 46070 } 46071 }); 46072 return [candidateDistance, candidateEdge]; 46073 } 46074 46075 /** 46076 * Is the point contained by the rectangle. 46077 * 46078 * @param {WPPoint} point The point. 46079 * @param {DOMRect} rect The rectangle. 46080 * 46081 * @return {boolean} True if the point is contained by the rectangle, false otherwise. 46082 */ 46083 function isPointContainedByRect(point, rect) { 46084 return rect.left <= point.x && rect.right >= point.x && rect.top <= point.y && rect.bottom >= point.y; 46085 } 46086 46087 /** 46088 * Is the point within the top and bottom boundaries of the rectangle. 46089 * 46090 * @param {WPPoint} point The point. 46091 * @param {DOMRect} rect The rectangle. 46092 * 46093 * @return {boolean} True if the point is within top and bottom of rectangle, false otherwise. 46094 */ 46095 function isPointWithinTopAndBottomBoundariesOfRect(point, rect) { 46096 return rect.top <= point.y && rect.bottom >= point.y; 46097 } 46098 46099 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/use-block-drop-zone/index.js 46100 /** 46101 * WordPress dependencies 46102 */ 46103 46104 46105 46106 46107 46108 46109 /** 46110 * Internal dependencies 46111 */ 46112 46113 46114 46115 46116 const THRESHOLD_DISTANCE = 30; 46117 const MINIMUM_HEIGHT_FOR_THRESHOLD = 120; 46118 const MINIMUM_WIDTH_FOR_THRESHOLD = 120; 46119 46120 /** @typedef {import('../../utils/math').WPPoint} WPPoint */ 46121 /** @typedef {import('../use-on-block-drop/types').WPDropOperation} WPDropOperation */ 46122 46123 /** 46124 * The orientation of a block list. 46125 * 46126 * @typedef {'horizontal'|'vertical'|undefined} WPBlockListOrientation 46127 */ 46128 46129 /** 46130 * The insert position when dropping a block. 46131 * 46132 * @typedef {'before'|'after'} WPInsertPosition 46133 */ 46134 46135 /** 46136 * @typedef {Object} WPBlockData 46137 * @property {boolean} isUnmodifiedDefaultBlock Is the block unmodified default block. 46138 * @property {() => DOMRect} getBoundingClientRect Get the bounding client rect of the block. 46139 * @property {number} blockIndex The index of the block. 46140 */ 46141 46142 /** 46143 * Get the drop target position from a given drop point and the orientation. 46144 * 46145 * @param {WPBlockData[]} blocksData The block data list. 46146 * @param {WPPoint} position The position of the item being dragged. 46147 * @param {WPBlockListOrientation} orientation The orientation of the block list. 46148 * @param {Object} options Additional options. 46149 * @return {[number, WPDropOperation]} The drop target position. 46150 */ 46151 function getDropTargetPosition(blocksData, position, orientation = 'vertical', options = {}) { 46152 const allowedEdges = orientation === 'horizontal' ? ['left', 'right'] : ['top', 'bottom']; 46153 let nearestIndex = 0; 46154 let insertPosition = 'before'; 46155 let minDistance = Infinity; 46156 let targetBlockIndex = null; 46157 let nearestSide = 'right'; 46158 const { 46159 dropZoneElement, 46160 parentBlockOrientation, 46161 rootBlockIndex = 0 46162 } = options; 46163 46164 // Allow before/after when dragging over the top/bottom edges of the drop zone. 46165 if (dropZoneElement && parentBlockOrientation !== 'horizontal') { 46166 const rect = dropZoneElement.getBoundingClientRect(); 46167 const [distance, edge] = getDistanceToNearestEdge(position, rect, ['top', 'bottom']); 46168 46169 // If dragging over the top or bottom of the drop zone, insert the block 46170 // before or after the parent block. This only applies to blocks that use 46171 // a drop zone element, typically container blocks such as Group or Cover. 46172 if (rect.height > MINIMUM_HEIGHT_FOR_THRESHOLD && distance < THRESHOLD_DISTANCE) { 46173 if (edge === 'top') { 46174 return [rootBlockIndex, 'before']; 46175 } 46176 if (edge === 'bottom') { 46177 return [rootBlockIndex + 1, 'after']; 46178 } 46179 } 46180 } 46181 const isRightToLeft = (0,external_wp_i18n_namespaceObject.isRTL)(); 46182 46183 // Allow before/after when dragging over the left/right edges of the drop zone. 46184 if (dropZoneElement && parentBlockOrientation === 'horizontal') { 46185 const rect = dropZoneElement.getBoundingClientRect(); 46186 const [distance, edge] = getDistanceToNearestEdge(position, rect, ['left', 'right']); 46187 46188 // If dragging over the left or right of the drop zone, insert the block 46189 // before or after the parent block. This only applies to blocks that use 46190 // a drop zone element, typically container blocks such as Group. 46191 if (rect.width > MINIMUM_WIDTH_FOR_THRESHOLD && distance < THRESHOLD_DISTANCE) { 46192 if (isRightToLeft && edge === 'right' || !isRightToLeft && edge === 'left') { 46193 return [rootBlockIndex, 'before']; 46194 } 46195 if (isRightToLeft && edge === 'left' || !isRightToLeft && edge === 'right') { 46196 return [rootBlockIndex + 1, 'after']; 46197 } 46198 } 46199 } 46200 blocksData.forEach(({ 46201 isUnmodifiedDefaultBlock, 46202 getBoundingClientRect, 46203 blockIndex, 46204 blockOrientation 46205 }) => { 46206 const rect = getBoundingClientRect(); 46207 let [distance, edge] = getDistanceToNearestEdge(position, rect, allowedEdges); 46208 // If the the point is close to a side, prioritize that side. 46209 const [sideDistance, sideEdge] = getDistanceToNearestEdge(position, rect, ['left', 'right']); 46210 const isPointInsideRect = isPointContainedByRect(position, rect); 46211 46212 // Prioritize the element if the point is inside of an unmodified default block. 46213 if (isUnmodifiedDefaultBlock && isPointInsideRect) { 46214 distance = 0; 46215 } else if (orientation === 'vertical' && blockOrientation !== 'horizontal' && (isPointInsideRect && sideDistance < THRESHOLD_DISTANCE || !isPointInsideRect && isPointWithinTopAndBottomBoundariesOfRect(position, rect))) { 46216 /** 46217 * This condition should only apply when the layout is vertical (otherwise there's 46218 * no need to create a Row) and dropzones should only activate when the block is 46219 * either within and close to the sides of the target block or on its outer sides. 46220 */ 46221 targetBlockIndex = blockIndex; 46222 nearestSide = sideEdge; 46223 } 46224 if (distance < minDistance) { 46225 // Where the dropped block will be inserted on the nearest block. 46226 insertPosition = edge === 'bottom' || !isRightToLeft && edge === 'right' || isRightToLeft && edge === 'left' ? 'after' : 'before'; 46227 46228 // Update the currently known best candidate. 46229 minDistance = distance; 46230 nearestIndex = blockIndex; 46231 } 46232 }); 46233 const adjacentIndex = nearestIndex + (insertPosition === 'after' ? 1 : -1); 46234 const isNearestBlockUnmodifiedDefaultBlock = !!blocksData[nearestIndex]?.isUnmodifiedDefaultBlock; 46235 const isAdjacentBlockUnmodifiedDefaultBlock = !!blocksData[adjacentIndex]?.isUnmodifiedDefaultBlock; 46236 46237 // If the target index is set then group with the block at that index. 46238 if (targetBlockIndex !== null) { 46239 return [targetBlockIndex, 'group', nearestSide]; 46240 } 46241 // If both blocks are not unmodified default blocks then just insert between them. 46242 if (!isNearestBlockUnmodifiedDefaultBlock && !isAdjacentBlockUnmodifiedDefaultBlock) { 46243 // If the user is dropping to the trailing edge of the block 46244 // add 1 to the index to represent dragging after. 46245 const insertionIndex = insertPosition === 'after' ? nearestIndex + 1 : nearestIndex; 46246 return [insertionIndex, 'insert']; 46247 } 46248 46249 // Otherwise, replace the nearest unmodified default block. 46250 return [isNearestBlockUnmodifiedDefaultBlock ? nearestIndex : adjacentIndex, 'replace']; 46251 } 46252 46253 /** 46254 * Check if the dragged blocks can be dropped on the target. 46255 * @param {Function} getBlockType 46256 * @param {Object[]} allowedBlocks 46257 * @param {string[]} draggedBlockNames 46258 * @param {string} targetBlockName 46259 * @return {boolean} Whether the dragged blocks can be dropped on the target. 46260 */ 46261 function isDropTargetValid(getBlockType, allowedBlocks, draggedBlockNames, targetBlockName) { 46262 // At root level allowedBlocks is undefined and all blocks are allowed. 46263 // Otherwise, check if all dragged blocks are allowed. 46264 let areBlocksAllowed = true; 46265 if (allowedBlocks) { 46266 const allowedBlockNames = allowedBlocks?.map(({ 46267 name 46268 }) => name); 46269 areBlocksAllowed = draggedBlockNames.every(name => allowedBlockNames?.includes(name)); 46270 } 46271 46272 // Work out if dragged blocks have an allowed parent and if so 46273 // check target block matches the allowed parent. 46274 const draggedBlockTypes = draggedBlockNames.map(name => getBlockType(name)); 46275 const targetMatchesDraggedBlockParents = draggedBlockTypes.every(block => { 46276 const [allowedParentName] = block?.parent || []; 46277 if (!allowedParentName) { 46278 return true; 46279 } 46280 return allowedParentName === targetBlockName; 46281 }); 46282 return areBlocksAllowed && targetMatchesDraggedBlockParents; 46283 } 46284 46285 /** 46286 * @typedef {Object} WPBlockDropZoneConfig 46287 * @property {?HTMLElement} dropZoneElement Optional element to be used as the drop zone. 46288 * @property {string} rootClientId The root client id for the block list. 46289 */ 46290 46291 /** 46292 * A React hook that can be used to make a block list handle drag and drop. 46293 * 46294 * @param {WPBlockDropZoneConfig} dropZoneConfig configuration data for the drop zone. 46295 */ 46296 function useBlockDropZone({ 46297 dropZoneElement, 46298 // An undefined value represents a top-level block. Default to an empty 46299 // string for this so that `targetRootClientId` can be easily compared to 46300 // values returned by the `getRootBlockClientId` selector, which also uses 46301 // an empty string to represent top-level blocks. 46302 rootClientId: targetRootClientId = '', 46303 parentClientId: parentBlockClientId = '', 46304 isDisabled = false 46305 } = {}) { 46306 const registry = (0,external_wp_data_namespaceObject.useRegistry)(); 46307 const [dropTarget, setDropTarget] = (0,external_wp_element_namespaceObject.useState)({ 46308 index: null, 46309 operation: 'insert' 46310 }); 46311 const { 46312 getBlockType 46313 } = (0,external_wp_data_namespaceObject.useSelect)(external_wp_blocks_namespaceObject.store); 46314 const { 46315 getBlockListSettings, 46316 getBlocks, 46317 getBlockIndex, 46318 getDraggedBlockClientIds, 46319 getBlockNamesByClientId, 46320 getAllowedBlocks, 46321 isDragging 46322 } = unlock((0,external_wp_data_namespaceObject.useSelect)(store)); 46323 const { 46324 showInsertionPoint, 46325 hideInsertionPoint, 46326 startDragging, 46327 stopDragging 46328 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store)); 46329 const onBlockDrop = useOnBlockDrop(dropTarget.operation === 'before' || dropTarget.operation === 'after' ? parentBlockClientId : targetRootClientId, dropTarget.index, { 46330 operation: dropTarget.operation, 46331 nearestSide: dropTarget.nearestSide 46332 }); 46333 const throttled = (0,external_wp_compose_namespaceObject.useThrottle)((0,external_wp_element_namespaceObject.useCallback)((event, ownerDocument) => { 46334 if (!isDragging()) { 46335 // When dragging from the desktop, no drag start event is fired. 46336 // So, ensure that the drag state is set when the user drags over a drop zone. 46337 startDragging(); 46338 } 46339 const allowedBlocks = getAllowedBlocks(targetRootClientId); 46340 const targetBlockName = getBlockNamesByClientId([targetRootClientId])[0]; 46341 const draggedBlockNames = getBlockNamesByClientId(getDraggedBlockClientIds()); 46342 const isBlockDroppingAllowed = isDropTargetValid(getBlockType, allowedBlocks, draggedBlockNames, targetBlockName); 46343 if (!isBlockDroppingAllowed) { 46344 return; 46345 } 46346 const blocks = getBlocks(targetRootClientId); 46347 46348 // The block list is empty, don't show the insertion point but still allow dropping. 46349 if (blocks.length === 0) { 46350 registry.batch(() => { 46351 setDropTarget({ 46352 index: 0, 46353 operation: 'insert' 46354 }); 46355 showInsertionPoint(targetRootClientId, 0, { 46356 operation: 'insert' 46357 }); 46358 }); 46359 return; 46360 } 46361 const blocksData = blocks.map(block => { 46362 const clientId = block.clientId; 46363 return { 46364 isUnmodifiedDefaultBlock: (0,external_wp_blocks_namespaceObject.isUnmodifiedDefaultBlock)(block), 46365 getBoundingClientRect: () => ownerDocument.getElementById(`block-$clientId}`).getBoundingClientRect(), 46366 blockIndex: getBlockIndex(clientId), 46367 blockOrientation: getBlockListSettings(clientId)?.orientation 46368 }; 46369 }); 46370 const [targetIndex, operation, nearestSide] = getDropTargetPosition(blocksData, { 46371 x: event.clientX, 46372 y: event.clientY 46373 }, getBlockListSettings(targetRootClientId)?.orientation, { 46374 dropZoneElement, 46375 parentBlockClientId, 46376 parentBlockOrientation: parentBlockClientId ? getBlockListSettings(parentBlockClientId)?.orientation : undefined, 46377 rootBlockIndex: getBlockIndex(targetRootClientId) 46378 }); 46379 registry.batch(() => { 46380 setDropTarget({ 46381 index: targetIndex, 46382 operation, 46383 nearestSide 46384 }); 46385 const insertionPointClientId = ['before', 'after'].includes(operation) ? parentBlockClientId : targetRootClientId; 46386 showInsertionPoint(insertionPointClientId, targetIndex, { 46387 operation, 46388 nearestSide 46389 }); 46390 }); 46391 }, [getAllowedBlocks, targetRootClientId, getBlockNamesByClientId, getDraggedBlockClientIds, getBlockType, getBlocks, getBlockListSettings, dropZoneElement, parentBlockClientId, getBlockIndex, registry, showInsertionPoint, isDragging, startDragging]), 200); 46392 return (0,external_wp_compose_namespaceObject.__experimentalUseDropZone)({ 46393 dropZoneElement, 46394 isDisabled, 46395 onDrop: onBlockDrop, 46396 onDragOver(event) { 46397 // `currentTarget` is only available while the event is being 46398 // handled, so get it now and pass it to the thottled function. 46399 // https://developer.mozilla.org/en-US/docs/Web/API/Event/currentTarget 46400 throttled(event, event.currentTarget.ownerDocument); 46401 }, 46402 onDragLeave() { 46403 throttled.cancel(); 46404 hideInsertionPoint(); 46405 }, 46406 onDragEnd() { 46407 throttled.cancel(); 46408 stopDragging(); 46409 hideInsertionPoint(); 46410 } 46411 }); 46412 } 46413 46414 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inner-blocks/index.js 46415 46416 /** 46417 * External dependencies 46418 */ 46419 46420 46421 /** 46422 * WordPress dependencies 46423 */ 46424 46425 46426 46427 46428 46429 /** 46430 * Internal dependencies 46431 */ 46432 46433 46434 46435 46436 46437 46438 46439 46440 46441 46442 46443 46444 const inner_blocks_EMPTY_OBJECT = {}; 46445 function BlockContext({ 46446 children, 46447 clientId 46448 }) { 46449 const context = useBlockContext(clientId); 46450 return (0,external_React_.createElement)(BlockContextProvider, { 46451 value: context 46452 }, children); 46453 } 46454 const BlockListItemsMemo = (0,external_wp_element_namespaceObject.memo)(BlockListItems); 46455 46456 /** 46457 * InnerBlocks is a component which allows a single block to have multiple blocks 46458 * as children. The UncontrolledInnerBlocks component is used whenever the inner 46459 * blocks are not controlled by another entity. In other words, it is normally 46460 * used for inner blocks in the post editor 46461 * 46462 * @param {Object} props The component props. 46463 */ 46464 function UncontrolledInnerBlocks(props) { 46465 const { 46466 clientId, 46467 allowedBlocks, 46468 prioritizedInserterBlocks, 46469 defaultBlock, 46470 directInsert, 46471 __experimentalDefaultBlock, 46472 __experimentalDirectInsert, 46473 template, 46474 templateLock, 46475 wrapperRef, 46476 templateInsertUpdatesSelection, 46477 __experimentalCaptureToolbars: captureToolbars, 46478 __experimentalAppenderTagName, 46479 renderAppender, 46480 orientation, 46481 placeholder, 46482 layout, 46483 name, 46484 blockType, 46485 parentLock, 46486 defaultLayout 46487 } = props; 46488 useNestedSettingsUpdate(clientId, parentLock, allowedBlocks, prioritizedInserterBlocks, defaultBlock, directInsert, __experimentalDefaultBlock, __experimentalDirectInsert, templateLock, captureToolbars, orientation, layout); 46489 useInnerBlockTemplateSync(clientId, template, templateLock, templateInsertUpdatesSelection); 46490 const defaultLayoutBlockSupport = (0,external_wp_blocks_namespaceObject.getBlockSupport)(name, 'layout') || (0,external_wp_blocks_namespaceObject.getBlockSupport)(name, '__experimentalLayout') || inner_blocks_EMPTY_OBJECT; 46491 const { 46492 allowSizingOnChildren = false 46493 } = defaultLayoutBlockSupport; 46494 const usedLayout = layout || defaultLayoutBlockSupport; 46495 const memoedLayout = (0,external_wp_element_namespaceObject.useMemo)(() => ({ 46496 // Default layout will know about any content/wide size defined by the theme. 46497 ...defaultLayout, 46498 ...usedLayout, 46499 ...(allowSizingOnChildren && { 46500 allowSizingOnChildren: true 46501 }) 46502 }), [defaultLayout, usedLayout, allowSizingOnChildren]); 46503 46504 // For controlled inner blocks, we don't want a change in blocks to 46505 // re-render the blocks list. 46506 const items = (0,external_React_.createElement)(BlockListItemsMemo, { 46507 rootClientId: clientId, 46508 renderAppender: renderAppender, 46509 __experimentalAppenderTagName: __experimentalAppenderTagName, 46510 layout: memoedLayout, 46511 wrapperRef: wrapperRef, 46512 placeholder: placeholder 46513 }); 46514 if (Object.keys(blockType.providesContext).length === 0) { 46515 return items; 46516 } 46517 return (0,external_React_.createElement)(BlockContext, { 46518 clientId: clientId 46519 }, items); 46520 } 46521 46522 /** 46523 * The controlled inner blocks component wraps the uncontrolled inner blocks 46524 * component with the blockSync hook. This keeps the innerBlocks of the block in 46525 * the block-editor store in sync with the blocks of the controlling entity. An 46526 * example of an inner block controller is a template part block, which provides 46527 * its own blocks from the template part entity data source. 46528 * 46529 * @param {Object} props The component props. 46530 */ 46531 function ControlledInnerBlocks(props) { 46532 useBlockSync(props); 46533 return (0,external_React_.createElement)(UncontrolledInnerBlocks, { 46534 ...props 46535 }); 46536 } 46537 const ForwardedInnerBlocks = (0,external_wp_element_namespaceObject.forwardRef)((props, ref) => { 46538 const innerBlocksProps = useInnerBlocksProps({ 46539 ref 46540 }, props); 46541 return (0,external_React_.createElement)("div", { 46542 className: "block-editor-inner-blocks" 46543 }, (0,external_React_.createElement)("div", { 46544 ...innerBlocksProps 46545 })); 46546 }); 46547 46548 /** 46549 * This hook is used to lightly mark an element as an inner blocks wrapper 46550 * element. Call this hook and pass the returned props to the element to mark as 46551 * an inner blocks wrapper, automatically rendering inner blocks as children. If 46552 * you define a ref for the element, it is important to pass the ref to this 46553 * hook, which the hook in turn will pass to the component through the props it 46554 * returns. Optionally, you can also pass any other props through this hook, and 46555 * they will be merged and returned. 46556 * 46557 * @param {Object} props Optional. Props to pass to the element. Must contain 46558 * the ref if one is defined. 46559 * @param {Object} options Optional. Inner blocks options. 46560 * 46561 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/inner-blocks/README.md 46562 */ 46563 function useInnerBlocksProps(props = {}, options = {}) { 46564 const { 46565 __unstableDisableLayoutClassNames, 46566 __unstableDisableDropZone, 46567 dropZoneElement 46568 } = options; 46569 const { 46570 clientId, 46571 layout = null, 46572 __unstableLayoutClassNames: layoutClassNames = '' 46573 } = useBlockEditContext(); 46574 const selected = (0,external_wp_data_namespaceObject.useSelect)(select => { 46575 if (!clientId) { 46576 return {}; 46577 } 46578 const { 46579 getBlockName, 46580 isBlockSelected, 46581 hasSelectedInnerBlock, 46582 __unstableGetEditorMode, 46583 getTemplateLock, 46584 getBlockRootClientId, 46585 getBlockEditingMode, 46586 getBlockSettings, 46587 isDragging 46588 } = unlock(select(store)); 46589 const { 46590 hasBlockSupport, 46591 getBlockType 46592 } = select(external_wp_blocks_namespaceObject.store); 46593 const blockName = getBlockName(clientId); 46594 const enableClickThrough = __unstableGetEditorMode() === 'navigation'; 46595 const blockEditingMode = getBlockEditingMode(clientId); 46596 const parentClientId = getBlockRootClientId(clientId); 46597 const [defaultLayout] = getBlockSettings(clientId, 'layout'); 46598 return { 46599 __experimentalCaptureToolbars: hasBlockSupport(blockName, '__experimentalExposeControlsToChildren', false), 46600 hasOverlay: blockName !== 'core/template' && !isBlockSelected(clientId) && !hasSelectedInnerBlock(clientId, true) && enableClickThrough && !isDragging(), 46601 name: blockName, 46602 blockType: getBlockType(blockName), 46603 parentLock: getTemplateLock(parentClientId), 46604 parentClientId, 46605 isDropZoneDisabled: blockEditingMode === 'disabled', 46606 defaultLayout 46607 }; 46608 }, [clientId]); 46609 const { 46610 __experimentalCaptureToolbars, 46611 hasOverlay, 46612 name, 46613 blockType, 46614 parentLock, 46615 parentClientId, 46616 isDropZoneDisabled, 46617 defaultLayout 46618 } = selected; 46619 const blockDropZoneRef = useBlockDropZone({ 46620 dropZoneElement, 46621 rootClientId: clientId, 46622 parentClientId, 46623 isDisabled: isDropZoneDisabled 46624 }); 46625 const ref = (0,external_wp_compose_namespaceObject.useMergeRefs)([props.ref, __unstableDisableDropZone ? null : blockDropZoneRef]); 46626 const innerBlocksProps = { 46627 __experimentalCaptureToolbars, 46628 layout, 46629 name, 46630 blockType, 46631 parentLock, 46632 defaultLayout, 46633 ...options 46634 }; 46635 const InnerBlocks = innerBlocksProps.value && innerBlocksProps.onChange ? ControlledInnerBlocks : UncontrolledInnerBlocks; 46636 return { 46637 ...props, 46638 ref, 46639 className: classnames_default()(props.className, 'block-editor-block-list__layout', __unstableDisableLayoutClassNames ? '' : layoutClassNames, { 46640 'has-overlay': hasOverlay 46641 }), 46642 children: clientId ? (0,external_React_.createElement)(InnerBlocks, { 46643 ...innerBlocksProps, 46644 clientId: clientId 46645 }) : (0,external_React_.createElement)(BlockListItems, { 46646 ...options 46647 }) 46648 }; 46649 } 46650 useInnerBlocksProps.save = external_wp_blocks_namespaceObject.__unstableGetInnerBlocksProps; 46651 46652 // Expose default appender placeholders as components. 46653 ForwardedInnerBlocks.DefaultBlockAppender = default_block_appender; 46654 ForwardedInnerBlocks.ButtonBlockAppender = inner_blocks_button_block_appender; 46655 ForwardedInnerBlocks.Content = () => useInnerBlocksProps.save().children; 46656 46657 /** 46658 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/inner-blocks/README.md 46659 */ 46660 /* harmony default export */ const inner_blocks = (ForwardedInnerBlocks); 46661 46662 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/observe-typing/index.js 46663 46664 /** 46665 * WordPress dependencies 46666 */ 46667 46668 46669 46670 46671 46672 /** 46673 * Internal dependencies 46674 */ 46675 46676 46677 /** 46678 * Set of key codes upon which typing is to be initiated on a keydown event. 46679 * 46680 * @type {Set<number>} 46681 */ 46682 const KEY_DOWN_ELIGIBLE_KEY_CODES = new Set([external_wp_keycodes_namespaceObject.UP, external_wp_keycodes_namespaceObject.RIGHT, external_wp_keycodes_namespaceObject.DOWN, external_wp_keycodes_namespaceObject.LEFT, external_wp_keycodes_namespaceObject.ENTER, external_wp_keycodes_namespaceObject.BACKSPACE]); 46683 46684 /** 46685 * Returns true if a given keydown event can be inferred as intent to start 46686 * typing, or false otherwise. A keydown is considered eligible if it is a 46687 * text navigation without shift active. 46688 * 46689 * @param {KeyboardEvent} event Keydown event to test. 46690 * 46691 * @return {boolean} Whether event is eligible to start typing. 46692 */ 46693 function isKeyDownEligibleForStartTyping(event) { 46694 const { 46695 keyCode, 46696 shiftKey 46697 } = event; 46698 return !shiftKey && KEY_DOWN_ELIGIBLE_KEY_CODES.has(keyCode); 46699 } 46700 46701 /** 46702 * Removes the `isTyping` flag when the mouse moves in the document of the given 46703 * element. 46704 */ 46705 function useMouseMoveTypingReset() { 46706 const isTyping = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).isTyping(), []); 46707 const { 46708 stopTyping 46709 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 46710 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 46711 if (!isTyping) { 46712 return; 46713 } 46714 const { 46715 ownerDocument 46716 } = node; 46717 let lastClientX; 46718 let lastClientY; 46719 46720 /** 46721 * On mouse move, unset typing flag if user has moved cursor. 46722 * 46723 * @param {MouseEvent} event Mousemove event. 46724 */ 46725 function stopTypingOnMouseMove(event) { 46726 const { 46727 clientX, 46728 clientY 46729 } = event; 46730 46731 // We need to check that the mouse really moved because Safari 46732 // triggers mousemove events when shift or ctrl are pressed. 46733 if (lastClientX && lastClientY && (lastClientX !== clientX || lastClientY !== clientY)) { 46734 stopTyping(); 46735 } 46736 lastClientX = clientX; 46737 lastClientY = clientY; 46738 } 46739 ownerDocument.addEventListener('mousemove', stopTypingOnMouseMove); 46740 return () => { 46741 ownerDocument.removeEventListener('mousemove', stopTypingOnMouseMove); 46742 }; 46743 }, [isTyping, stopTyping]); 46744 } 46745 46746 /** 46747 * Sets and removes the `isTyping` flag based on user actions: 46748 * 46749 * - Sets the flag if the user types within the given element. 46750 * - Removes the flag when the user selects some text, focusses a non-text 46751 * field, presses ESC or TAB, or moves the mouse in the document. 46752 */ 46753 function useTypingObserver() { 46754 const { 46755 isTyping, 46756 hasInlineToolbar 46757 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 46758 const { 46759 isTyping: _isTyping, 46760 getSettings 46761 } = select(store); 46762 return { 46763 isTyping: _isTyping(), 46764 hasInlineToolbar: getSettings().hasInlineToolbar 46765 }; 46766 }, []); 46767 const { 46768 startTyping, 46769 stopTyping 46770 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 46771 const ref1 = useMouseMoveTypingReset(); 46772 const ref2 = (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 46773 const { 46774 ownerDocument 46775 } = node; 46776 const { 46777 defaultView 46778 } = ownerDocument; 46779 const selection = defaultView.getSelection(); 46780 46781 // Listeners to stop typing should only be added when typing. 46782 // Listeners to start typing should only be added when not typing. 46783 if (isTyping) { 46784 let timerId; 46785 46786 /** 46787 * Stops typing when focus transitions to a non-text field element. 46788 * 46789 * @param {FocusEvent} event Focus event. 46790 */ 46791 function stopTypingOnNonTextField(event) { 46792 const { 46793 target 46794 } = event; 46795 46796 // Since focus to a non-text field via arrow key will trigger 46797 // before the keydown event, wait until after current stack 46798 // before evaluating whether typing is to be stopped. Otherwise, 46799 // typing will re-start. 46800 timerId = defaultView.setTimeout(() => { 46801 if (!(0,external_wp_dom_namespaceObject.isTextField)(target)) { 46802 stopTyping(); 46803 } 46804 }); 46805 } 46806 46807 /** 46808 * Unsets typing flag if user presses Escape while typing flag is 46809 * active. 46810 * 46811 * @param {KeyboardEvent} event Keypress or keydown event to 46812 * interpret. 46813 */ 46814 function stopTypingOnEscapeKey(event) { 46815 const { 46816 keyCode 46817 } = event; 46818 if (keyCode === external_wp_keycodes_namespaceObject.ESCAPE || keyCode === external_wp_keycodes_namespaceObject.TAB) { 46819 stopTyping(); 46820 } 46821 } 46822 46823 /** 46824 * On selection change, unset typing flag if user has made an 46825 * uncollapsed (shift) selection. 46826 */ 46827 function stopTypingOnSelectionUncollapse() { 46828 if (!selection.isCollapsed) { 46829 stopTyping(); 46830 } 46831 } 46832 node.addEventListener('focus', stopTypingOnNonTextField); 46833 node.addEventListener('keydown', stopTypingOnEscapeKey); 46834 if (!hasInlineToolbar) { 46835 ownerDocument.addEventListener('selectionchange', stopTypingOnSelectionUncollapse); 46836 } 46837 return () => { 46838 defaultView.clearTimeout(timerId); 46839 node.removeEventListener('focus', stopTypingOnNonTextField); 46840 node.removeEventListener('keydown', stopTypingOnEscapeKey); 46841 ownerDocument.removeEventListener('selectionchange', stopTypingOnSelectionUncollapse); 46842 }; 46843 } 46844 46845 /** 46846 * Handles a keypress or keydown event to infer intention to start 46847 * typing. 46848 * 46849 * @param {KeyboardEvent} event Keypress or keydown event to interpret. 46850 */ 46851 function startTypingInTextField(event) { 46852 const { 46853 type, 46854 target 46855 } = event; 46856 46857 // Abort early if already typing, or key press is incurred outside a 46858 // text field (e.g. arrow-ing through toolbar buttons). 46859 // Ignore typing if outside the current DOM container 46860 if (!(0,external_wp_dom_namespaceObject.isTextField)(target) || !node.contains(target)) { 46861 return; 46862 } 46863 46864 // Special-case keydown because certain keys do not emit a keypress 46865 // event. Conversely avoid keydown as the canonical event since 46866 // there are many keydown which are explicitly not targeted for 46867 // typing. 46868 if (type === 'keydown' && !isKeyDownEligibleForStartTyping(event)) { 46869 return; 46870 } 46871 startTyping(); 46872 } 46873 node.addEventListener('keypress', startTypingInTextField); 46874 node.addEventListener('keydown', startTypingInTextField); 46875 return () => { 46876 node.removeEventListener('keypress', startTypingInTextField); 46877 node.removeEventListener('keydown', startTypingInTextField); 46878 }; 46879 }, [isTyping, hasInlineToolbar, startTyping, stopTyping]); 46880 return (0,external_wp_compose_namespaceObject.useMergeRefs)([ref1, ref2]); 46881 } 46882 function ObserveTyping({ 46883 children 46884 }) { 46885 return (0,external_React_.createElement)("div", { 46886 ref: useTypingObserver() 46887 }, children); 46888 } 46889 46890 /** 46891 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/observe-typing/README.md 46892 */ 46893 /* harmony default export */ const observe_typing = (ObserveTyping); 46894 46895 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/index.js 46896 46897 /** 46898 * External dependencies 46899 */ 46900 46901 46902 /** 46903 * WordPress dependencies 46904 */ 46905 46906 46907 46908 46909 /** 46910 * Internal dependencies 46911 */ 46912 46913 46914 46915 46916 46917 46918 46919 46920 46921 46922 const block_list_IntersectionObserver = (0,external_wp_element_namespaceObject.createContext)(); 46923 const pendingBlockVisibilityUpdatesPerRegistry = new WeakMap(); 46924 function block_list_Root({ 46925 className, 46926 ...settings 46927 }) { 46928 const isLargeViewport = (0,external_wp_compose_namespaceObject.useViewportMatch)('medium'); 46929 const { 46930 isOutlineMode, 46931 isFocusMode, 46932 editorMode 46933 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 46934 const { 46935 getSettings, 46936 __unstableGetEditorMode 46937 } = select(store); 46938 const { 46939 outlineMode, 46940 focusMode 46941 } = getSettings(); 46942 return { 46943 isOutlineMode: outlineMode, 46944 isFocusMode: focusMode, 46945 editorMode: __unstableGetEditorMode() 46946 }; 46947 }, []); 46948 const registry = (0,external_wp_data_namespaceObject.useRegistry)(); 46949 const { 46950 setBlockVisibility 46951 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 46952 const delayedBlockVisibilityUpdates = (0,external_wp_compose_namespaceObject.useDebounce)((0,external_wp_element_namespaceObject.useCallback)(() => { 46953 const updates = {}; 46954 pendingBlockVisibilityUpdatesPerRegistry.get(registry).forEach(([id, isIntersecting]) => { 46955 updates[id] = isIntersecting; 46956 }); 46957 setBlockVisibility(updates); 46958 }, [registry]), 300, { 46959 trailing: true 46960 }); 46961 const intersectionObserver = (0,external_wp_element_namespaceObject.useMemo)(() => { 46962 const { 46963 IntersectionObserver: Observer 46964 } = window; 46965 if (!Observer) { 46966 return; 46967 } 46968 return new Observer(entries => { 46969 if (!pendingBlockVisibilityUpdatesPerRegistry.get(registry)) { 46970 pendingBlockVisibilityUpdatesPerRegistry.set(registry, []); 46971 } 46972 for (const entry of entries) { 46973 const clientId = entry.target.getAttribute('data-block'); 46974 pendingBlockVisibilityUpdatesPerRegistry.get(registry).push([clientId, entry.isIntersecting]); 46975 } 46976 delayedBlockVisibilityUpdates(); 46977 }); 46978 }, []); 46979 const innerBlocksProps = useInnerBlocksProps({ 46980 ref: (0,external_wp_compose_namespaceObject.useMergeRefs)([useBlockSelectionClearer(), useInBetweenInserter(), useTypingObserver()]), 46981 className: classnames_default()('is-root-container', className, { 46982 'is-outline-mode': isOutlineMode, 46983 'is-focus-mode': isFocusMode && isLargeViewport, 46984 'is-navigate-mode': editorMode === 'navigation' 46985 }) 46986 }, settings); 46987 return (0,external_React_.createElement)(block_list_IntersectionObserver.Provider, { 46988 value: intersectionObserver 46989 }, (0,external_React_.createElement)("div", { 46990 ...innerBlocksProps 46991 })); 46992 } 46993 function StopEditingAsBlocksOnOutsideSelect({ 46994 clientId 46995 }) { 46996 const { 46997 stopEditingAsBlocks 46998 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store)); 46999 const isBlockOrDescendantSelected = (0,external_wp_data_namespaceObject.useSelect)(select => { 47000 const { 47001 isBlockSelected, 47002 hasSelectedInnerBlock 47003 } = select(store); 47004 return isBlockSelected(clientId) || hasSelectedInnerBlock(clientId, true); 47005 }, [clientId]); 47006 (0,external_wp_element_namespaceObject.useEffect)(() => { 47007 if (!isBlockOrDescendantSelected) { 47008 stopEditingAsBlocks(clientId); 47009 } 47010 }, [isBlockOrDescendantSelected, clientId, stopEditingAsBlocks]); 47011 return null; 47012 } 47013 function BlockList(settings) { 47014 return (0,external_React_.createElement)(Provider, { 47015 value: DEFAULT_BLOCK_EDIT_CONTEXT 47016 }, (0,external_React_.createElement)(block_list_Root, { 47017 ...settings 47018 })); 47019 } 47020 function Items({ 47021 placeholder, 47022 rootClientId, 47023 renderAppender: CustomAppender, 47024 __experimentalAppenderTagName, 47025 layout = defaultLayout 47026 }) { 47027 // Avoid passing CustomAppender to useSelect because it could be a new 47028 // function on every render. 47029 const hasAppender = CustomAppender !== false; 47030 const hasCustomAppender = !!CustomAppender; 47031 const { 47032 order, 47033 selectedBlocks, 47034 visibleBlocks, 47035 temporarilyEditingAsBlocks, 47036 shouldRenderAppender 47037 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 47038 const { 47039 getBlockOrder, 47040 getSelectedBlockClientId, 47041 getSelectedBlockClientIds, 47042 __unstableGetVisibleBlocks, 47043 __unstableGetTemporarilyEditingAsBlocks, 47044 getTemplateLock, 47045 getBlockEditingMode, 47046 __unstableGetEditorMode 47047 } = select(store); 47048 const selectedBlockClientId = getSelectedBlockClientId(); 47049 return { 47050 order: getBlockOrder(rootClientId), 47051 selectedBlocks: getSelectedBlockClientIds(), 47052 visibleBlocks: __unstableGetVisibleBlocks(), 47053 temporarilyEditingAsBlocks: __unstableGetTemporarilyEditingAsBlocks(), 47054 shouldRenderAppender: hasAppender && (hasCustomAppender ? !getTemplateLock(rootClientId) && getBlockEditingMode(rootClientId) !== 'disabled' && __unstableGetEditorMode() !== 'zoom-out' : rootClientId === selectedBlockClientId || !rootClientId && !selectedBlockClientId) 47055 }; 47056 }, [rootClientId, hasAppender, hasCustomAppender]); 47057 return (0,external_React_.createElement)(LayoutProvider, { 47058 value: layout 47059 }, order.map(clientId => (0,external_React_.createElement)(external_wp_data_namespaceObject.AsyncModeProvider, { 47060 key: clientId, 47061 value: 47062 // Only provide data asynchronously if the block is 47063 // not visible and not selected. 47064 !visibleBlocks.has(clientId) && !selectedBlocks.includes(clientId) 47065 }, (0,external_React_.createElement)(block_list_block, { 47066 rootClientId: rootClientId, 47067 clientId: clientId 47068 }))), order.length < 1 && placeholder, !!temporarilyEditingAsBlocks && (0,external_React_.createElement)(StopEditingAsBlocksOnOutsideSelect, { 47069 clientId: temporarilyEditingAsBlocks 47070 }), shouldRenderAppender && (0,external_React_.createElement)(BlockListAppender, { 47071 tagName: __experimentalAppenderTagName, 47072 rootClientId: rootClientId, 47073 CustomAppender: CustomAppender 47074 })); 47075 } 47076 function BlockListItems(props) { 47077 // This component needs to always be synchronous as it's the one changing 47078 // the async mode depending on the block selection. 47079 return (0,external_React_.createElement)(external_wp_data_namespaceObject.AsyncModeProvider, { 47080 value: false 47081 }, (0,external_React_.createElement)(Items, { 47082 ...props 47083 })); 47084 } 47085 47086 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-tools/use-block-toolbar-popover-props.js 47087 /** 47088 * WordPress dependencies 47089 */ 47090 47091 47092 47093 47094 47095 /** 47096 * Internal dependencies 47097 */ 47098 47099 47100 47101 const COMMON_PROPS = { 47102 placement: 'top-start' 47103 }; 47104 47105 // By default the toolbar sets the `shift` prop. If the user scrolls the page 47106 // down the toolbar will stay on screen by adopting a sticky position at the 47107 // top of the viewport. 47108 const DEFAULT_PROPS = { 47109 ...COMMON_PROPS, 47110 flip: false, 47111 shift: true 47112 }; 47113 47114 // When there isn't enough height between the top of the block and the editor 47115 // canvas, the `shift` prop is set to `false`, as it will cause the block to be 47116 // obscured. The `flip` behavior is enabled, which positions the toolbar below 47117 // the block. This only happens if the block is smaller than the viewport, as 47118 // otherwise the toolbar will be off-screen. 47119 const RESTRICTED_HEIGHT_PROPS = { 47120 ...COMMON_PROPS, 47121 flip: true, 47122 shift: false 47123 }; 47124 47125 /** 47126 * Get the popover props for the block toolbar, determined by the space at the top of the canvas and the toolbar height. 47127 * 47128 * @param {Element} contentElement The DOM element that represents the editor content or canvas. 47129 * @param {Element} selectedBlockElement The outer DOM element of the first selected block. 47130 * @param {Element} scrollContainer The scrollable container for the contentElement. 47131 * @param {number} toolbarHeight The height of the toolbar in pixels. 47132 * @param {boolean} isSticky Whether or not the selected block is sticky or fixed. 47133 * 47134 * @return {Object} The popover props used to determine the position of the toolbar. 47135 */ 47136 function getProps(contentElement, selectedBlockElement, scrollContainer, toolbarHeight, isSticky) { 47137 if (!contentElement || !selectedBlockElement) { 47138 return DEFAULT_PROPS; 47139 } 47140 47141 // Get how far the content area has been scrolled. 47142 const scrollTop = scrollContainer?.scrollTop || 0; 47143 const blockRect = selectedBlockElement.getBoundingClientRect(); 47144 const contentRect = contentElement.getBoundingClientRect(); 47145 47146 // Get the vertical position of top of the visible content area. 47147 const topOfContentElementInViewport = scrollTop + contentRect.top; 47148 47149 // The document element's clientHeight represents the viewport height. 47150 const viewportHeight = contentElement.ownerDocument.documentElement.clientHeight; 47151 47152 // The restricted height area is calculated as the sum of the 47153 // vertical position of the visible content area, plus the height 47154 // of the block toolbar. 47155 const restrictedTopArea = topOfContentElementInViewport + toolbarHeight; 47156 const hasSpaceForToolbarAbove = blockRect.top > restrictedTopArea; 47157 const isBlockTallerThanViewport = blockRect.height > viewportHeight - toolbarHeight; 47158 47159 // Sticky blocks are treated as if they will never have enough space for the toolbar above. 47160 if (!isSticky && (hasSpaceForToolbarAbove || isBlockTallerThanViewport)) { 47161 return DEFAULT_PROPS; 47162 } 47163 return RESTRICTED_HEIGHT_PROPS; 47164 } 47165 47166 /** 47167 * Determines the desired popover positioning behavior, returning a set of appropriate props. 47168 * 47169 * @param {Object} elements 47170 * @param {Element} elements.contentElement The DOM element that represents the editor content or canvas. 47171 * @param {string} elements.clientId The clientId of the first selected block. 47172 * 47173 * @return {Object} The popover props used to determine the position of the toolbar. 47174 */ 47175 function useBlockToolbarPopoverProps({ 47176 contentElement, 47177 clientId 47178 }) { 47179 const selectedBlockElement = useBlockElement(clientId); 47180 const [toolbarHeight, setToolbarHeight] = (0,external_wp_element_namespaceObject.useState)(0); 47181 const { 47182 blockIndex, 47183 isSticky 47184 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 47185 const { 47186 getBlockIndex, 47187 getBlockAttributes 47188 } = select(store); 47189 return { 47190 blockIndex: getBlockIndex(clientId), 47191 isSticky: hasStickyOrFixedPositionValue(getBlockAttributes(clientId)) 47192 }; 47193 }, [clientId]); 47194 const scrollContainer = (0,external_wp_element_namespaceObject.useMemo)(() => { 47195 if (!contentElement) { 47196 return; 47197 } 47198 return (0,external_wp_dom_namespaceObject.getScrollContainer)(contentElement); 47199 }, [contentElement]); 47200 const [props, setProps] = (0,external_wp_element_namespaceObject.useState)(() => getProps(contentElement, selectedBlockElement, scrollContainer, toolbarHeight, isSticky)); 47201 const popoverRef = (0,external_wp_compose_namespaceObject.useRefEffect)(popoverNode => { 47202 setToolbarHeight(popoverNode.offsetHeight); 47203 }, []); 47204 const updateProps = (0,external_wp_element_namespaceObject.useCallback)(() => setProps(getProps(contentElement, selectedBlockElement, scrollContainer, toolbarHeight, isSticky)), [contentElement, selectedBlockElement, scrollContainer, toolbarHeight]); 47205 47206 // Update props when the block is moved. This also ensures the props are 47207 // correct on initial mount, and when the selected block or content element 47208 // changes (since the callback ref will update). 47209 (0,external_wp_element_namespaceObject.useLayoutEffect)(updateProps, [blockIndex, updateProps]); 47210 47211 // Update props when the viewport is resized or the block is resized. 47212 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 47213 if (!contentElement || !selectedBlockElement) { 47214 return; 47215 } 47216 47217 // Update the toolbar props on viewport resize. 47218 const contentView = contentElement?.ownerDocument?.defaultView; 47219 contentView?.addEventHandler?.('resize', updateProps); 47220 47221 // Update the toolbar props on block resize. 47222 let resizeObserver; 47223 const blockView = selectedBlockElement?.ownerDocument?.defaultView; 47224 if (blockView.ResizeObserver) { 47225 resizeObserver = new blockView.ResizeObserver(updateProps); 47226 resizeObserver.observe(selectedBlockElement); 47227 } 47228 return () => { 47229 contentView?.removeEventHandler?.('resize', updateProps); 47230 if (resizeObserver) { 47231 resizeObserver.disconnect(); 47232 } 47233 }; 47234 }, [updateProps, contentElement, selectedBlockElement]); 47235 return { 47236 ...props, 47237 ref: popoverRef 47238 }; 47239 } 47240 47241 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-tools/use-selected-block-tool-props.js 47242 /** 47243 * WordPress dependencies 47244 */ 47245 47246 47247 /** 47248 * Internal dependencies 47249 */ 47250 47251 47252 /** 47253 * Returns props for the selected block tools and empty block inserter. 47254 * 47255 * @param {string} clientId Selected block client ID. 47256 */ 47257 function useSelectedBlockToolProps(clientId) { 47258 const selectedBlockProps = (0,external_wp_data_namespaceObject.useSelect)(select => { 47259 const { 47260 getBlockRootClientId, 47261 getBlockParents, 47262 __experimentalGetBlockListSettingsForBlocks, 47263 isBlockInsertionPointVisible, 47264 getBlockInsertionPoint, 47265 getBlockOrder, 47266 hasMultiSelection, 47267 getLastMultiSelectedBlockClientId 47268 } = select(store); 47269 const blockParentsClientIds = getBlockParents(clientId); 47270 47271 // Get Block List Settings for all ancestors of the current Block clientId. 47272 const parentBlockListSettings = __experimentalGetBlockListSettingsForBlocks(blockParentsClientIds); 47273 47274 // Get the clientId of the topmost parent with the capture toolbars setting. 47275 const capturingClientId = blockParentsClientIds.find(parentClientId => parentBlockListSettings[parentClientId]?.__experimentalCaptureToolbars); 47276 let isInsertionPointVisible = false; 47277 if (isBlockInsertionPointVisible()) { 47278 const insertionPoint = getBlockInsertionPoint(); 47279 const order = getBlockOrder(insertionPoint.rootClientId); 47280 isInsertionPointVisible = order[insertionPoint.index] === clientId; 47281 } 47282 return { 47283 capturingClientId, 47284 isInsertionPointVisible, 47285 lastClientId: hasMultiSelection() ? getLastMultiSelectedBlockClientId() : null, 47286 rootClientId: getBlockRootClientId(clientId) 47287 }; 47288 }, [clientId]); 47289 return selectedBlockProps; 47290 } 47291 47292 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-tools/empty-block-inserter.js 47293 47294 /** 47295 * External dependencies 47296 */ 47297 47298 47299 /** 47300 * Internal dependencies 47301 */ 47302 47303 47304 47305 47306 function EmptyBlockInserter({ 47307 clientId, 47308 __unstableContentRef 47309 }) { 47310 const { 47311 capturingClientId, 47312 isInsertionPointVisible, 47313 lastClientId, 47314 rootClientId 47315 } = useSelectedBlockToolProps(clientId); 47316 const popoverProps = useBlockToolbarPopoverProps({ 47317 contentElement: __unstableContentRef?.current, 47318 clientId 47319 }); 47320 return (0,external_React_.createElement)(block_popover, { 47321 clientId: capturingClientId || clientId, 47322 __unstableCoverTarget: true, 47323 bottomClientId: lastClientId, 47324 className: classnames_default()('block-editor-block-list__block-side-inserter-popover', { 47325 'is-insertion-point-visible': isInsertionPointVisible 47326 }), 47327 __unstableContentRef: __unstableContentRef, 47328 resize: false, 47329 shift: false, 47330 ...popoverProps 47331 }, (0,external_React_.createElement)("div", { 47332 className: "block-editor-block-list__empty-block-inserter" 47333 }, (0,external_React_.createElement)(inserter, { 47334 position: "bottom right", 47335 rootClientId: rootClientId, 47336 clientId: clientId, 47337 __experimentalIsQuick: true 47338 }))); 47339 } 47340 47341 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-draggable/use-scroll-when-dragging.js 47342 /** 47343 * WordPress dependencies 47344 */ 47345 47346 47347 const SCROLL_INACTIVE_DISTANCE_PX = 50; 47348 const SCROLL_INTERVAL_MS = 25; 47349 const PIXELS_PER_SECOND_PER_PERCENTAGE = 1000; 47350 const VELOCITY_MULTIPLIER = PIXELS_PER_SECOND_PER_PERCENTAGE * (SCROLL_INTERVAL_MS / 1000); 47351 47352 /** 47353 * React hook that scrolls the scroll container when a block is being dragged. 47354 * 47355 * @return {Function[]} `startScrolling`, `scrollOnDragOver`, `stopScrolling` 47356 * functions to be called in `onDragStart`, `onDragOver` 47357 * and `onDragEnd` events respectively. 47358 */ 47359 function useScrollWhenDragging() { 47360 const dragStartY = (0,external_wp_element_namespaceObject.useRef)(null); 47361 const velocityY = (0,external_wp_element_namespaceObject.useRef)(null); 47362 const scrollParentY = (0,external_wp_element_namespaceObject.useRef)(null); 47363 const scrollEditorInterval = (0,external_wp_element_namespaceObject.useRef)(null); 47364 47365 // Clear interval when unmounting. 47366 (0,external_wp_element_namespaceObject.useEffect)(() => () => { 47367 if (scrollEditorInterval.current) { 47368 clearInterval(scrollEditorInterval.current); 47369 scrollEditorInterval.current = null; 47370 } 47371 }, []); 47372 const startScrolling = (0,external_wp_element_namespaceObject.useCallback)(event => { 47373 dragStartY.current = event.clientY; 47374 47375 // Find nearest parent(s) to scroll. 47376 scrollParentY.current = (0,external_wp_dom_namespaceObject.getScrollContainer)(event.target); 47377 scrollEditorInterval.current = setInterval(() => { 47378 if (scrollParentY.current && velocityY.current) { 47379 const newTop = scrollParentY.current.scrollTop + velocityY.current; 47380 47381 // Setting `behavior: 'smooth'` as a scroll property seems to hurt performance. 47382 // Better to use a small scroll interval. 47383 scrollParentY.current.scroll({ 47384 top: newTop 47385 }); 47386 } 47387 }, SCROLL_INTERVAL_MS); 47388 }, []); 47389 const scrollOnDragOver = (0,external_wp_element_namespaceObject.useCallback)(event => { 47390 if (!scrollParentY.current) { 47391 return; 47392 } 47393 const scrollParentHeight = scrollParentY.current.offsetHeight; 47394 const offsetDragStartPosition = dragStartY.current - scrollParentY.current.offsetTop; 47395 const offsetDragPosition = event.clientY - scrollParentY.current.offsetTop; 47396 if (event.clientY > offsetDragStartPosition) { 47397 // User is dragging downwards. 47398 const moveableDistance = Math.max(scrollParentHeight - offsetDragStartPosition - SCROLL_INACTIVE_DISTANCE_PX, 0); 47399 const dragDistance = Math.max(offsetDragPosition - offsetDragStartPosition - SCROLL_INACTIVE_DISTANCE_PX, 0); 47400 const distancePercentage = moveableDistance === 0 || dragDistance === 0 ? 0 : dragDistance / moveableDistance; 47401 velocityY.current = VELOCITY_MULTIPLIER * distancePercentage; 47402 } else if (event.clientY < offsetDragStartPosition) { 47403 // User is dragging upwards. 47404 const moveableDistance = Math.max(offsetDragStartPosition - SCROLL_INACTIVE_DISTANCE_PX, 0); 47405 const dragDistance = Math.max(offsetDragStartPosition - offsetDragPosition - SCROLL_INACTIVE_DISTANCE_PX, 0); 47406 const distancePercentage = moveableDistance === 0 || dragDistance === 0 ? 0 : dragDistance / moveableDistance; 47407 velocityY.current = -VELOCITY_MULTIPLIER * distancePercentage; 47408 } else { 47409 velocityY.current = 0; 47410 } 47411 }, []); 47412 const stopScrolling = () => { 47413 dragStartY.current = null; 47414 scrollParentY.current = null; 47415 if (scrollEditorInterval.current) { 47416 clearInterval(scrollEditorInterval.current); 47417 scrollEditorInterval.current = null; 47418 } 47419 }; 47420 return [startScrolling, scrollOnDragOver, stopScrolling]; 47421 } 47422 47423 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-draggable/index.js 47424 47425 /** 47426 * WordPress dependencies 47427 */ 47428 47429 47430 47431 47432 47433 47434 /** 47435 * Internal dependencies 47436 */ 47437 47438 47439 47440 47441 47442 const BlockDraggable = ({ 47443 appendToOwnerDocument, 47444 children, 47445 clientIds, 47446 cloneClassname, 47447 elementId, 47448 onDragStart, 47449 onDragEnd, 47450 fadeWhenDisabled = false, 47451 dragComponent 47452 }) => { 47453 const { 47454 srcRootClientId, 47455 isDraggable, 47456 icon, 47457 visibleInserter, 47458 getBlockType 47459 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 47460 const { 47461 canMoveBlocks, 47462 getBlockRootClientId, 47463 getBlockName, 47464 getBlockAttributes, 47465 isBlockInsertionPointVisible 47466 } = select(store); 47467 const { 47468 getBlockType: _getBlockType, 47469 getActiveBlockVariation 47470 } = select(external_wp_blocks_namespaceObject.store); 47471 const rootClientId = getBlockRootClientId(clientIds[0]); 47472 const blockName = getBlockName(clientIds[0]); 47473 const variation = getActiveBlockVariation(blockName, getBlockAttributes(clientIds[0])); 47474 return { 47475 srcRootClientId: rootClientId, 47476 isDraggable: canMoveBlocks(clientIds, rootClientId), 47477 icon: variation?.icon || _getBlockType(blockName)?.icon, 47478 visibleInserter: isBlockInsertionPointVisible(), 47479 getBlockType: _getBlockType 47480 }; 47481 }, [clientIds]); 47482 const isDragging = (0,external_wp_element_namespaceObject.useRef)(false); 47483 const [startScrolling, scrollOnDragOver, stopScrolling] = useScrollWhenDragging(); 47484 const { 47485 getAllowedBlocks, 47486 getBlockNamesByClientId, 47487 getBlockRootClientId 47488 } = (0,external_wp_data_namespaceObject.useSelect)(store); 47489 const { 47490 startDraggingBlocks, 47491 stopDraggingBlocks 47492 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 47493 47494 // Stop dragging blocks if the block draggable is unmounted. 47495 (0,external_wp_element_namespaceObject.useEffect)(() => { 47496 return () => { 47497 if (isDragging.current) { 47498 stopDraggingBlocks(); 47499 } 47500 }; 47501 }, []); 47502 47503 // Find the root of the editor iframe. 47504 const blockRef = useBlockRef(clientIds[0]); 47505 const editorRoot = blockRef.current?.closest('body'); 47506 47507 /* 47508 * Add a dragover event listener to the editor root to track the blocks being dragged over. 47509 * The listener has to be inside the editor iframe otherwise the target isn't accessible. 47510 */ 47511 (0,external_wp_element_namespaceObject.useEffect)(() => { 47512 if (!editorRoot || !fadeWhenDisabled) { 47513 return; 47514 } 47515 const onDragOver = event => { 47516 if (!event.target.closest('[data-block]')) { 47517 return; 47518 } 47519 const draggedBlockNames = getBlockNamesByClientId(clientIds); 47520 const targetClientId = event.target.closest('[data-block]').getAttribute('data-block'); 47521 const allowedBlocks = getAllowedBlocks(targetClientId); 47522 const targetBlockName = getBlockNamesByClientId([targetClientId])[0]; 47523 47524 /* 47525 * Check if the target is valid to drop in. 47526 * If the target's allowedBlocks is an empty array, 47527 * it isn't a container block, in which case we check 47528 * its parent's validity instead. 47529 */ 47530 let dropTargetValid; 47531 if (allowedBlocks?.length === 0) { 47532 const targetRootClientId = getBlockRootClientId(targetClientId); 47533 const targetRootBlockName = getBlockNamesByClientId([targetRootClientId])[0]; 47534 const rootAllowedBlocks = getAllowedBlocks(targetRootClientId); 47535 dropTargetValid = isDropTargetValid(getBlockType, rootAllowedBlocks, draggedBlockNames, targetRootBlockName); 47536 } else { 47537 dropTargetValid = isDropTargetValid(getBlockType, allowedBlocks, draggedBlockNames, targetBlockName); 47538 } 47539 47540 /* 47541 * Update the body class to reflect if drop target is valid. 47542 * This has to be done on the document body because the draggable 47543 * chip is rendered outside of the editor iframe. 47544 */ 47545 if (!dropTargetValid && !visibleInserter) { 47546 window?.document?.body?.classList?.add('block-draggable-invalid-drag-token'); 47547 } else { 47548 window?.document?.body?.classList?.remove('block-draggable-invalid-drag-token'); 47549 } 47550 }; 47551 const throttledOnDragOver = (0,external_wp_compose_namespaceObject.throttle)(onDragOver, 200); 47552 editorRoot.addEventListener('dragover', throttledOnDragOver); 47553 return () => { 47554 editorRoot.removeEventListener('dragover', throttledOnDragOver); 47555 }; 47556 }, [clientIds, editorRoot, fadeWhenDisabled, getAllowedBlocks, getBlockNamesByClientId, getBlockRootClientId, getBlockType, visibleInserter]); 47557 if (!isDraggable) { 47558 return children({ 47559 draggable: false 47560 }); 47561 } 47562 const transferData = { 47563 type: 'block', 47564 srcClientIds: clientIds, 47565 srcRootClientId 47566 }; 47567 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Draggable, { 47568 appendToOwnerDocument: appendToOwnerDocument, 47569 cloneClassname: cloneClassname, 47570 __experimentalTransferDataType: "wp-blocks", 47571 transferData: transferData, 47572 onDragStart: event => { 47573 // Defer hiding the dragged source element to the next 47574 // frame to enable dragging. 47575 window.requestAnimationFrame(() => { 47576 startDraggingBlocks(clientIds); 47577 isDragging.current = true; 47578 startScrolling(event); 47579 if (onDragStart) { 47580 onDragStart(); 47581 } 47582 }); 47583 }, 47584 onDragOver: scrollOnDragOver, 47585 onDragEnd: () => { 47586 stopDraggingBlocks(); 47587 isDragging.current = false; 47588 stopScrolling(); 47589 if (onDragEnd) { 47590 onDragEnd(); 47591 } 47592 }, 47593 __experimentalDragComponent: 47594 // Check against `undefined` so that `null` can be used to disable 47595 // the default drag component. 47596 dragComponent !== undefined ? dragComponent : (0,external_React_.createElement)(BlockDraggableChip, { 47597 count: clientIds.length, 47598 icon: icon, 47599 fadeWhenDisabled: true 47600 }), 47601 elementId: elementId 47602 }, ({ 47603 onDraggableStart, 47604 onDraggableEnd 47605 }) => { 47606 return children({ 47607 draggable: true, 47608 onDragStart: onDraggableStart, 47609 onDragEnd: onDraggableEnd 47610 }); 47611 }); 47612 }; 47613 /* harmony default export */ const block_draggable = (BlockDraggable); 47614 47615 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/chevron-up.js 47616 47617 /** 47618 * WordPress dependencies 47619 */ 47620 47621 const chevronUp = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 47622 viewBox: "0 0 24 24", 47623 xmlns: "http://www.w3.org/2000/svg" 47624 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 47625 d: "M6.5 12.4L12 8l5.5 4.4-.9 1.2L12 10l-4.5 3.6-1-1.2z" 47626 })); 47627 /* harmony default export */ const chevron_up = (chevronUp); 47628 47629 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/chevron-down.js 47630 47631 /** 47632 * WordPress dependencies 47633 */ 47634 47635 const chevronDown = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 47636 viewBox: "0 0 24 24", 47637 xmlns: "http://www.w3.org/2000/svg" 47638 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 47639 d: "M17.5 11.6L12 16l-5.5-4.4.9-1.2L12 14l4.5-3.6 1 1.2z" 47640 })); 47641 /* harmony default export */ const chevron_down = (chevronDown); 47642 47643 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-mover/mover-description.js 47644 /** 47645 * WordPress dependencies 47646 */ 47647 47648 const getMovementDirection = (moveDirection, orientation) => { 47649 if (moveDirection === 'up') { 47650 if (orientation === 'horizontal') { 47651 return (0,external_wp_i18n_namespaceObject.isRTL)() ? 'right' : 'left'; 47652 } 47653 return 'up'; 47654 } else if (moveDirection === 'down') { 47655 if (orientation === 'horizontal') { 47656 return (0,external_wp_i18n_namespaceObject.isRTL)() ? 'left' : 'right'; 47657 } 47658 return 'down'; 47659 } 47660 return null; 47661 }; 47662 47663 /** 47664 * Return a label for the block movement controls depending on block position. 47665 * 47666 * @param {number} selectedCount Number of blocks selected. 47667 * @param {string} type Block type - in the case of a single block, should 47668 * define its 'type'. I.e. 'Text', 'Heading', 'Image' etc. 47669 * @param {number} firstIndex The index (position - 1) of the first block selected. 47670 * @param {boolean} isFirst This is the first block. 47671 * @param {boolean} isLast This is the last block. 47672 * @param {number} dir Direction of movement (> 0 is considered to be going 47673 * down, < 0 is up). 47674 * @param {string} orientation The orientation of the block movers, vertical or 47675 * horizontal. 47676 * 47677 * @return {string | undefined} Label for the block movement controls. 47678 */ 47679 function getBlockMoverDescription(selectedCount, type, firstIndex, isFirst, isLast, dir, orientation) { 47680 const position = firstIndex + 1; 47681 if (selectedCount > 1) { 47682 return getMultiBlockMoverDescription(selectedCount, firstIndex, isFirst, isLast, dir, orientation); 47683 } 47684 if (isFirst && isLast) { 47685 return (0,external_wp_i18n_namespaceObject.sprintf)( 47686 // translators: %s: Type of block (i.e. Text, Image etc) 47687 (0,external_wp_i18n_namespaceObject.__)('Block %s is the only block, and cannot be moved'), type); 47688 } 47689 if (dir > 0 && !isLast) { 47690 // Moving down. 47691 const movementDirection = getMovementDirection('down', orientation); 47692 if (movementDirection === 'down') { 47693 return (0,external_wp_i18n_namespaceObject.sprintf)( 47694 // translators: 1: Type of block (i.e. Text, Image etc), 2: Position of selected block, 3: New position 47695 (0,external_wp_i18n_namespaceObject.__)('Move %1$s block from position %2$d down to position %3$d'), type, position, position + 1); 47696 } 47697 if (movementDirection === 'left') { 47698 return (0,external_wp_i18n_namespaceObject.sprintf)( 47699 // translators: 1: Type of block (i.e. Text, Image etc), 2: Position of selected block, 3: New position 47700 (0,external_wp_i18n_namespaceObject.__)('Move %1$s block from position %2$d left to position %3$d'), type, position, position + 1); 47701 } 47702 if (movementDirection === 'right') { 47703 return (0,external_wp_i18n_namespaceObject.sprintf)( 47704 // translators: 1: Type of block (i.e. Text, Image etc), 2: Position of selected block, 3: New position 47705 (0,external_wp_i18n_namespaceObject.__)('Move %1$s block from position %2$d right to position %3$d'), type, position, position + 1); 47706 } 47707 } 47708 if (dir > 0 && isLast) { 47709 // Moving down, and is the last item. 47710 const movementDirection = getMovementDirection('down', orientation); 47711 if (movementDirection === 'down') { 47712 return (0,external_wp_i18n_namespaceObject.sprintf)( 47713 // translators: 1: Type of block (i.e. Text, Image etc) 47714 (0,external_wp_i18n_namespaceObject.__)('Block %1$s is at the end of the content and can’t be moved down'), type); 47715 } 47716 if (movementDirection === 'left') { 47717 return (0,external_wp_i18n_namespaceObject.sprintf)( 47718 // translators: 1: Type of block (i.e. Text, Image etc) 47719 (0,external_wp_i18n_namespaceObject.__)('Block %1$s is at the end of the content and can’t be moved left'), type); 47720 } 47721 if (movementDirection === 'right') { 47722 return (0,external_wp_i18n_namespaceObject.sprintf)( 47723 // translators: 1: Type of block (i.e. Text, Image etc) 47724 (0,external_wp_i18n_namespaceObject.__)('Block %1$s is at the end of the content and can’t be moved right'), type); 47725 } 47726 } 47727 if (dir < 0 && !isFirst) { 47728 // Moving up. 47729 const movementDirection = getMovementDirection('up', orientation); 47730 if (movementDirection === 'up') { 47731 return (0,external_wp_i18n_namespaceObject.sprintf)( 47732 // translators: 1: Type of block (i.e. Text, Image etc), 2: Position of selected block, 3: New position 47733 (0,external_wp_i18n_namespaceObject.__)('Move %1$s block from position %2$d up to position %3$d'), type, position, position - 1); 47734 } 47735 if (movementDirection === 'left') { 47736 return (0,external_wp_i18n_namespaceObject.sprintf)( 47737 // translators: 1: Type of block (i.e. Text, Image etc), 2: Position of selected block, 3: New position 47738 (0,external_wp_i18n_namespaceObject.__)('Move %1$s block from position %2$d left to position %3$d'), type, position, position - 1); 47739 } 47740 if (movementDirection === 'right') { 47741 return (0,external_wp_i18n_namespaceObject.sprintf)( 47742 // translators: 1: Type of block (i.e. Text, Image etc), 2: Position of selected block, 3: New position 47743 (0,external_wp_i18n_namespaceObject.__)('Move %1$s block from position %2$d right to position %3$d'), type, position, position - 1); 47744 } 47745 } 47746 if (dir < 0 && isFirst) { 47747 // Moving up, and is the first item. 47748 const movementDirection = getMovementDirection('up', orientation); 47749 if (movementDirection === 'up') { 47750 return (0,external_wp_i18n_namespaceObject.sprintf)( 47751 // translators: 1: Type of block (i.e. Text, Image etc) 47752 (0,external_wp_i18n_namespaceObject.__)('Block %1$s is at the beginning of the content and can’t be moved up'), type); 47753 } 47754 if (movementDirection === 'left') { 47755 return (0,external_wp_i18n_namespaceObject.sprintf)( 47756 // translators: 1: Type of block (i.e. Text, Image etc) 47757 (0,external_wp_i18n_namespaceObject.__)('Block %1$s is at the beginning of the content and can’t be moved left'), type); 47758 } 47759 if (movementDirection === 'right') { 47760 return (0,external_wp_i18n_namespaceObject.sprintf)( 47761 // translators: 1: Type of block (i.e. Text, Image etc) 47762 (0,external_wp_i18n_namespaceObject.__)('Block %1$s is at the beginning of the content and can’t be moved right'), type); 47763 } 47764 } 47765 } 47766 47767 /** 47768 * Return a label for the block movement controls depending on block position. 47769 * 47770 * @param {number} selectedCount Number of blocks selected. 47771 * @param {number} firstIndex The index (position - 1) of the first block selected. 47772 * @param {boolean} isFirst This is the first block. 47773 * @param {boolean} isLast This is the last block. 47774 * @param {number} dir Direction of movement (> 0 is considered to be going 47775 * down, < 0 is up). 47776 * @param {string} orientation The orientation of the block movers, vertical or 47777 * horizontal. 47778 * 47779 * @return {string | undefined} Label for the block movement controls. 47780 */ 47781 function getMultiBlockMoverDescription(selectedCount, firstIndex, isFirst, isLast, dir, orientation) { 47782 const position = firstIndex + 1; 47783 if (isFirst && isLast) { 47784 // All blocks are selected 47785 return (0,external_wp_i18n_namespaceObject.__)('All blocks are selected, and cannot be moved'); 47786 } 47787 if (dir > 0 && !isLast) { 47788 // moving down 47789 const movementDirection = getMovementDirection('down', orientation); 47790 if (movementDirection === 'down') { 47791 return (0,external_wp_i18n_namespaceObject.sprintf)( 47792 // translators: 1: Number of selected blocks, 2: Position of selected blocks 47793 (0,external_wp_i18n_namespaceObject.__)('Move %1$d blocks from position %2$d down by one place'), selectedCount, position); 47794 } 47795 if (movementDirection === 'left') { 47796 return (0,external_wp_i18n_namespaceObject.sprintf)( 47797 // translators: 1: Number of selected blocks, 2: Position of selected blocks 47798 (0,external_wp_i18n_namespaceObject.__)('Move %1$d blocks from position %2$d left by one place'), selectedCount, position); 47799 } 47800 if (movementDirection === 'right') { 47801 return (0,external_wp_i18n_namespaceObject.sprintf)( 47802 // translators: 1: Number of selected blocks, 2: Position of selected blocks 47803 (0,external_wp_i18n_namespaceObject.__)('Move %1$d blocks from position %2$d right by one place'), selectedCount, position); 47804 } 47805 } 47806 if (dir > 0 && isLast) { 47807 // moving down, and the selected blocks are the last item 47808 const movementDirection = getMovementDirection('down', orientation); 47809 if (movementDirection === 'down') { 47810 return (0,external_wp_i18n_namespaceObject.__)('Blocks cannot be moved down as they are already at the bottom'); 47811 } 47812 if (movementDirection === 'left') { 47813 return (0,external_wp_i18n_namespaceObject.__)('Blocks cannot be moved left as they are already are at the leftmost position'); 47814 } 47815 if (movementDirection === 'right') { 47816 return (0,external_wp_i18n_namespaceObject.__)('Blocks cannot be moved right as they are already are at the rightmost position'); 47817 } 47818 } 47819 if (dir < 0 && !isFirst) { 47820 // moving up 47821 const movementDirection = getMovementDirection('up', orientation); 47822 if (movementDirection === 'up') { 47823 return (0,external_wp_i18n_namespaceObject.sprintf)( 47824 // translators: 1: Number of selected blocks, 2: Position of selected blocks 47825 (0,external_wp_i18n_namespaceObject.__)('Move %1$d blocks from position %2$d up by one place'), selectedCount, position); 47826 } 47827 if (movementDirection === 'left') { 47828 return (0,external_wp_i18n_namespaceObject.sprintf)( 47829 // translators: 1: Number of selected blocks, 2: Position of selected blocks 47830 (0,external_wp_i18n_namespaceObject.__)('Move %1$d blocks from position %2$d left by one place'), selectedCount, position); 47831 } 47832 if (movementDirection === 'right') { 47833 return (0,external_wp_i18n_namespaceObject.sprintf)( 47834 // translators: 1: Number of selected blocks, 2: Position of selected blocks 47835 (0,external_wp_i18n_namespaceObject.__)('Move %1$d blocks from position %2$d right by one place'), selectedCount, position); 47836 } 47837 } 47838 if (dir < 0 && isFirst) { 47839 // moving up, and the selected blocks are the first item 47840 const movementDirection = getMovementDirection('up', orientation); 47841 if (movementDirection === 'up') { 47842 return (0,external_wp_i18n_namespaceObject.__)('Blocks cannot be moved up as they are already at the top'); 47843 } 47844 if (movementDirection === 'left') { 47845 return (0,external_wp_i18n_namespaceObject.__)('Blocks cannot be moved left as they are already are at the leftmost position'); 47846 } 47847 if (movementDirection === 'right') { 47848 return (0,external_wp_i18n_namespaceObject.__)('Blocks cannot be moved right as they are already are at the rightmost position'); 47849 } 47850 } 47851 } 47852 47853 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-mover/button.js 47854 47855 /** 47856 * External dependencies 47857 */ 47858 47859 47860 /** 47861 * WordPress dependencies 47862 */ 47863 47864 47865 47866 47867 47868 47869 47870 /** 47871 * Internal dependencies 47872 */ 47873 47874 47875 47876 const getArrowIcon = (direction, orientation) => { 47877 if (direction === 'up') { 47878 if (orientation === 'horizontal') { 47879 return (0,external_wp_i18n_namespaceObject.isRTL)() ? chevron_right : chevron_left; 47880 } 47881 return chevron_up; 47882 } else if (direction === 'down') { 47883 if (orientation === 'horizontal') { 47884 return (0,external_wp_i18n_namespaceObject.isRTL)() ? chevron_left : chevron_right; 47885 } 47886 return chevron_down; 47887 } 47888 return null; 47889 }; 47890 const getMovementDirectionLabel = (moveDirection, orientation) => { 47891 if (moveDirection === 'up') { 47892 if (orientation === 'horizontal') { 47893 return (0,external_wp_i18n_namespaceObject.isRTL)() ? (0,external_wp_i18n_namespaceObject.__)('Move right') : (0,external_wp_i18n_namespaceObject.__)('Move left'); 47894 } 47895 return (0,external_wp_i18n_namespaceObject.__)('Move up'); 47896 } else if (moveDirection === 'down') { 47897 if (orientation === 'horizontal') { 47898 return (0,external_wp_i18n_namespaceObject.isRTL)() ? (0,external_wp_i18n_namespaceObject.__)('Move left') : (0,external_wp_i18n_namespaceObject.__)('Move right'); 47899 } 47900 return (0,external_wp_i18n_namespaceObject.__)('Move down'); 47901 } 47902 return null; 47903 }; 47904 const BlockMoverButton = (0,external_wp_element_namespaceObject.forwardRef)(({ 47905 clientIds, 47906 direction, 47907 orientation: moverOrientation, 47908 ...props 47909 }, ref) => { 47910 const instanceId = (0,external_wp_compose_namespaceObject.useInstanceId)(BlockMoverButton); 47911 const normalizedClientIds = Array.isArray(clientIds) ? clientIds : [clientIds]; 47912 const blocksCount = normalizedClientIds.length; 47913 const { 47914 blockType, 47915 isDisabled, 47916 rootClientId, 47917 isFirst, 47918 isLast, 47919 firstIndex, 47920 orientation = 'vertical' 47921 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 47922 const { 47923 getBlockIndex, 47924 getBlockRootClientId, 47925 getBlockOrder, 47926 getBlock, 47927 getBlockListSettings 47928 } = select(store); 47929 const firstClientId = normalizedClientIds[0]; 47930 const blockRootClientId = getBlockRootClientId(firstClientId); 47931 const firstBlockIndex = getBlockIndex(firstClientId); 47932 const lastBlockIndex = getBlockIndex(normalizedClientIds[normalizedClientIds.length - 1]); 47933 const blockOrder = getBlockOrder(blockRootClientId); 47934 const block = getBlock(firstClientId); 47935 const isFirstBlock = firstBlockIndex === 0; 47936 const isLastBlock = lastBlockIndex === blockOrder.length - 1; 47937 const { 47938 orientation: blockListOrientation 47939 } = getBlockListSettings(blockRootClientId) || {}; 47940 return { 47941 blockType: block ? (0,external_wp_blocks_namespaceObject.getBlockType)(block.name) : null, 47942 isDisabled: direction === 'up' ? isFirstBlock : isLastBlock, 47943 rootClientId: blockRootClientId, 47944 firstIndex: firstBlockIndex, 47945 isFirst: isFirstBlock, 47946 isLast: isLastBlock, 47947 orientation: moverOrientation || blockListOrientation 47948 }; 47949 }, [clientIds, direction]); 47950 const { 47951 moveBlocksDown, 47952 moveBlocksUp 47953 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 47954 const moverFunction = direction === 'up' ? moveBlocksUp : moveBlocksDown; 47955 const onClick = event => { 47956 moverFunction(clientIds, rootClientId); 47957 if (props.onClick) { 47958 props.onClick(event); 47959 } 47960 }; 47961 const descriptionId = `block-editor-block-mover-button__description-$instanceId}`; 47962 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 47963 ref: ref, 47964 className: classnames_default()('block-editor-block-mover-button', `is-$direction}-button`), 47965 icon: getArrowIcon(direction, orientation), 47966 label: getMovementDirectionLabel(direction, orientation), 47967 "aria-describedby": descriptionId, 47968 ...props, 47969 onClick: isDisabled ? null : onClick, 47970 disabled: isDisabled, 47971 __experimentalIsFocusable: true 47972 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.VisuallyHidden, { 47973 id: descriptionId 47974 }, getBlockMoverDescription(blocksCount, blockType && blockType.title, firstIndex, isFirst, isLast, direction === 'up' ? -1 : 1, orientation))); 47975 }); 47976 const BlockMoverUpButton = (0,external_wp_element_namespaceObject.forwardRef)((props, ref) => { 47977 return (0,external_React_.createElement)(BlockMoverButton, { 47978 direction: "up", 47979 ref: ref, 47980 ...props 47981 }); 47982 }); 47983 const BlockMoverDownButton = (0,external_wp_element_namespaceObject.forwardRef)((props, ref) => { 47984 return (0,external_React_.createElement)(BlockMoverButton, { 47985 direction: "down", 47986 ref: ref, 47987 ...props 47988 }); 47989 }); 47990 47991 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-mover/index.js 47992 47993 /** 47994 * External dependencies 47995 */ 47996 47997 47998 /** 47999 * WordPress dependencies 48000 */ 48001 48002 48003 48004 48005 48006 48007 /** 48008 * Internal dependencies 48009 */ 48010 48011 48012 48013 function BlockMover({ 48014 clientIds, 48015 hideDragHandle 48016 }) { 48017 const { 48018 canMove, 48019 rootClientId, 48020 isFirst, 48021 isLast, 48022 orientation 48023 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 48024 const { 48025 getBlockIndex, 48026 getBlockListSettings, 48027 canMoveBlocks, 48028 getBlockOrder, 48029 getBlockRootClientId 48030 } = select(store); 48031 const normalizedClientIds = Array.isArray(clientIds) ? clientIds : [clientIds]; 48032 const firstClientId = normalizedClientIds[0]; 48033 const _rootClientId = getBlockRootClientId(firstClientId); 48034 const firstIndex = getBlockIndex(firstClientId); 48035 const lastIndex = getBlockIndex(normalizedClientIds[normalizedClientIds.length - 1]); 48036 const blockOrder = getBlockOrder(_rootClientId); 48037 return { 48038 canMove: canMoveBlocks(clientIds, _rootClientId), 48039 rootClientId: _rootClientId, 48040 isFirst: firstIndex === 0, 48041 isLast: lastIndex === blockOrder.length - 1, 48042 orientation: getBlockListSettings(_rootClientId)?.orientation 48043 }; 48044 }, [clientIds]); 48045 if (!canMove || isFirst && isLast && !rootClientId) { 48046 return null; 48047 } 48048 const dragHandleLabel = (0,external_wp_i18n_namespaceObject.__)('Drag'); 48049 return (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarGroup, { 48050 className: classnames_default()('block-editor-block-mover', { 48051 'is-horizontal': orientation === 'horizontal' 48052 }) 48053 }, !hideDragHandle && (0,external_React_.createElement)(block_draggable, { 48054 clientIds: clientIds, 48055 fadeWhenDisabled: true 48056 }, draggableProps => (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 48057 icon: drag_handle, 48058 className: "block-editor-block-mover__drag-handle", 48059 "aria-hidden": "true", 48060 label: dragHandleLabel 48061 // Should not be able to tab to drag handle as this 48062 // button can only be used with a pointer device. 48063 , 48064 tabIndex: "-1", 48065 ...draggableProps 48066 })), (0,external_React_.createElement)("div", { 48067 className: "block-editor-block-mover__move-button-container" 48068 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarItem, null, itemProps => (0,external_React_.createElement)(BlockMoverUpButton, { 48069 clientIds: clientIds, 48070 ...itemProps 48071 })), (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarItem, null, itemProps => (0,external_React_.createElement)(BlockMoverDownButton, { 48072 clientIds: clientIds, 48073 ...itemProps 48074 })))); 48075 } 48076 48077 /** 48078 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-mover/README.md 48079 */ 48080 /* harmony default export */ const block_mover = (BlockMover); 48081 48082 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-toolbar/utils.js 48083 /** 48084 * WordPress dependencies 48085 */ 48086 48087 48088 48089 /** 48090 * Internal dependencies 48091 */ 48092 48093 const { 48094 clearTimeout: utils_clearTimeout, 48095 setTimeout: utils_setTimeout 48096 } = window; 48097 const DEBOUNCE_TIMEOUT = 200; 48098 48099 /** 48100 * Hook that creates debounced callbacks when the node is hovered or focused. 48101 * 48102 * @param {Object} props Component props. 48103 * @param {Object} props.ref Element reference. 48104 * @param {boolean} props.isFocused Whether the component has current focus. 48105 * @param {number} props.highlightParent Whether to highlight the parent block. It defaults in highlighting the selected block. 48106 * @param {number} [props.debounceTimeout=250] Debounce timeout in milliseconds. 48107 */ 48108 function useDebouncedShowGestures({ 48109 ref, 48110 isFocused, 48111 highlightParent, 48112 debounceTimeout = DEBOUNCE_TIMEOUT 48113 }) { 48114 const { 48115 getSelectedBlockClientId, 48116 getBlockRootClientId 48117 } = (0,external_wp_data_namespaceObject.useSelect)(store); 48118 const { 48119 toggleBlockHighlight 48120 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 48121 const timeoutRef = (0,external_wp_element_namespaceObject.useRef)(); 48122 const isDistractionFree = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getSettings().isDistractionFree, []); 48123 const handleOnChange = nextIsFocused => { 48124 if (nextIsFocused && isDistractionFree) { 48125 return; 48126 } 48127 const selectedBlockClientId = getSelectedBlockClientId(); 48128 const clientId = highlightParent ? getBlockRootClientId(selectedBlockClientId) : selectedBlockClientId; 48129 toggleBlockHighlight(clientId, nextIsFocused); 48130 }; 48131 const getIsHovered = () => { 48132 return ref?.current && ref.current.matches(':hover'); 48133 }; 48134 const shouldHideGestures = () => { 48135 const isHovered = getIsHovered(); 48136 return !isFocused && !isHovered; 48137 }; 48138 const clearTimeoutRef = () => { 48139 const timeout = timeoutRef.current; 48140 if (timeout && utils_clearTimeout) { 48141 utils_clearTimeout(timeout); 48142 } 48143 }; 48144 const debouncedShowGestures = event => { 48145 if (event) { 48146 event.stopPropagation(); 48147 } 48148 clearTimeoutRef(); 48149 handleOnChange(true); 48150 }; 48151 const debouncedHideGestures = event => { 48152 if (event) { 48153 event.stopPropagation(); 48154 } 48155 clearTimeoutRef(); 48156 timeoutRef.current = utils_setTimeout(() => { 48157 if (shouldHideGestures()) { 48158 handleOnChange(false); 48159 } 48160 }, debounceTimeout); 48161 }; 48162 (0,external_wp_element_namespaceObject.useEffect)(() => () => { 48163 /** 48164 * We need to call the change handler with `isFocused` 48165 * set to false on unmount because we also clear the 48166 * timeout that would handle that. 48167 */ 48168 handleOnChange(false); 48169 clearTimeoutRef(); 48170 }, []); 48171 return { 48172 debouncedShowGestures, 48173 debouncedHideGestures 48174 }; 48175 } 48176 48177 /** 48178 * Hook that provides gesture events for DOM elements 48179 * that interact with the isFocused state. 48180 * 48181 * @param {Object} props Component props. 48182 * @param {Object} props.ref Element reference. 48183 * @param {number} [props.highlightParent=false] Whether to highlight the parent block. It defaults to highlighting the selected block. 48184 * @param {number} [props.debounceTimeout=250] Debounce timeout in milliseconds. 48185 */ 48186 function useShowHoveredOrFocusedGestures({ 48187 ref, 48188 highlightParent = false, 48189 debounceTimeout = DEBOUNCE_TIMEOUT 48190 }) { 48191 const [isFocused, setIsFocused] = (0,external_wp_element_namespaceObject.useState)(false); 48192 const { 48193 debouncedShowGestures, 48194 debouncedHideGestures 48195 } = useDebouncedShowGestures({ 48196 ref, 48197 debounceTimeout, 48198 isFocused, 48199 highlightParent 48200 }); 48201 const registerRef = (0,external_wp_element_namespaceObject.useRef)(false); 48202 const isFocusedWithin = () => { 48203 return ref?.current && ref.current.contains(ref.current.ownerDocument.activeElement); 48204 }; 48205 (0,external_wp_element_namespaceObject.useEffect)(() => { 48206 const node = ref.current; 48207 const handleOnFocus = () => { 48208 if (isFocusedWithin()) { 48209 setIsFocused(true); 48210 debouncedShowGestures(); 48211 } 48212 }; 48213 const handleOnBlur = () => { 48214 if (!isFocusedWithin()) { 48215 setIsFocused(false); 48216 debouncedHideGestures(); 48217 } 48218 }; 48219 48220 /** 48221 * Events are added via DOM events (vs. React synthetic events), 48222 * as the child React components swallow mouse events. 48223 */ 48224 if (node && !registerRef.current) { 48225 node.addEventListener('focus', handleOnFocus, true); 48226 node.addEventListener('blur', handleOnBlur, true); 48227 registerRef.current = true; 48228 } 48229 return () => { 48230 if (node) { 48231 node.removeEventListener('focus', handleOnFocus); 48232 node.removeEventListener('blur', handleOnBlur); 48233 } 48234 }; 48235 }, [ref, registerRef, setIsFocused, debouncedShowGestures, debouncedHideGestures]); 48236 return { 48237 onMouseMove: debouncedShowGestures, 48238 onMouseLeave: debouncedHideGestures 48239 }; 48240 } 48241 48242 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-parent-selector/index.js 48243 48244 /** 48245 * WordPress dependencies 48246 */ 48247 48248 48249 48250 48251 48252 48253 /** 48254 * Internal dependencies 48255 */ 48256 48257 48258 48259 48260 48261 /** 48262 * Block parent selector component, displaying the hierarchy of the 48263 * current block selection as a single icon to "go up" a level. 48264 * 48265 * @return {Component} Parent block selector. 48266 */ 48267 function BlockParentSelector() { 48268 const { 48269 selectBlock 48270 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 48271 const { 48272 firstParentClientId, 48273 isVisible 48274 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 48275 const { 48276 getBlockName, 48277 getBlockParents, 48278 getSelectedBlockClientId, 48279 getBlockEditingMode 48280 } = select(store); 48281 const { 48282 hasBlockSupport 48283 } = select(external_wp_blocks_namespaceObject.store); 48284 const selectedBlockClientId = getSelectedBlockClientId(); 48285 const parents = getBlockParents(selectedBlockClientId); 48286 const _firstParentClientId = parents[parents.length - 1]; 48287 const parentBlockName = getBlockName(_firstParentClientId); 48288 const _parentBlockType = (0,external_wp_blocks_namespaceObject.getBlockType)(parentBlockName); 48289 return { 48290 firstParentClientId: _firstParentClientId, 48291 isVisible: _firstParentClientId && getBlockEditingMode(_firstParentClientId) === 'default' && hasBlockSupport(_parentBlockType, '__experimentalParentSelector', true) 48292 }; 48293 }, []); 48294 const blockInformation = useBlockDisplayInformation(firstParentClientId); 48295 48296 // Allows highlighting the parent block outline when focusing or hovering 48297 // the parent block selector within the child. 48298 const nodeRef = (0,external_wp_element_namespaceObject.useRef)(); 48299 const showHoveredOrFocusedGestures = useShowHoveredOrFocusedGestures({ 48300 ref: nodeRef, 48301 highlightParent: true 48302 }); 48303 if (!isVisible) { 48304 return null; 48305 } 48306 return (0,external_React_.createElement)("div", { 48307 className: "block-editor-block-parent-selector", 48308 key: firstParentClientId, 48309 ref: nodeRef, 48310 ...showHoveredOrFocusedGestures 48311 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarButton, { 48312 className: "block-editor-block-parent-selector__button", 48313 onClick: () => selectBlock(firstParentClientId), 48314 label: (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: Name of the block's parent. */ 48315 (0,external_wp_i18n_namespaceObject.__)('Select parent block: %s'), blockInformation?.title), 48316 showTooltip: true, 48317 icon: (0,external_React_.createElement)(block_icon, { 48318 icon: blockInformation?.icon 48319 }) 48320 })); 48321 } 48322 48323 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/copy.js 48324 48325 /** 48326 * WordPress dependencies 48327 */ 48328 48329 const copy_copy = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 48330 xmlns: "http://www.w3.org/2000/svg", 48331 viewBox: "0 0 24 24" 48332 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 48333 fillRule: "evenodd", 48334 clipRule: "evenodd", 48335 d: "M5 4.5h11a.5.5 0 0 1 .5.5v11a.5.5 0 0 1-.5.5H5a.5.5 0 0 1-.5-.5V5a.5.5 0 0 1 .5-.5ZM3 5a2 2 0 0 1 2-2h11a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5Zm17 3v10.75c0 .69-.56 1.25-1.25 1.25H6v1.5h12.75a2.75 2.75 0 0 0 2.75-2.75V8H20Z" 48336 })); 48337 /* harmony default export */ const library_copy = (copy_copy); 48338 48339 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-switcher/preview-block-popover.js 48340 48341 /** 48342 * WordPress dependencies 48343 */ 48344 48345 48346 48347 /** 48348 * Internal dependencies 48349 */ 48350 48351 function PreviewBlockPopover({ 48352 blocks 48353 }) { 48354 return (0,external_React_.createElement)("div", { 48355 className: "block-editor-block-switcher__popover__preview__parent" 48356 }, (0,external_React_.createElement)("div", { 48357 className: "block-editor-block-switcher__popover__preview__container" 48358 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Popover, { 48359 className: "block-editor-block-switcher__preview__popover", 48360 placement: "bottom-start", 48361 focusOnMount: false 48362 }, (0,external_React_.createElement)("div", { 48363 className: "block-editor-block-switcher__preview" 48364 }, (0,external_React_.createElement)("div", { 48365 className: "block-editor-block-switcher__preview-title" 48366 }, (0,external_wp_i18n_namespaceObject.__)('Preview')), (0,external_React_.createElement)(block_preview, { 48367 viewportWidth: 500, 48368 blocks: blocks 48369 }))))); 48370 } 48371 48372 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-switcher/block-variation-transformations.js 48373 48374 /** 48375 * WordPress dependencies 48376 */ 48377 48378 48379 48380 48381 48382 /** 48383 * Internal dependencies 48384 */ 48385 48386 48387 48388 const block_variation_transformations_EMPTY_OBJECT = {}; 48389 function useBlockVariationTransforms({ 48390 clientIds, 48391 blocks 48392 }) { 48393 const { 48394 activeBlockVariation, 48395 blockVariationTransformations 48396 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 48397 const { 48398 getBlockRootClientId, 48399 getBlockAttributes, 48400 canRemoveBlocks 48401 } = select(store); 48402 const { 48403 getActiveBlockVariation, 48404 getBlockVariations 48405 } = select(external_wp_blocks_namespaceObject.store); 48406 const rootClientId = getBlockRootClientId(Array.isArray(clientIds) ? clientIds[0] : clientIds); 48407 const canRemove = canRemoveBlocks(clientIds, rootClientId); 48408 // Only handle single selected blocks for now. 48409 if (blocks.length !== 1 || !canRemove) { 48410 return block_variation_transformations_EMPTY_OBJECT; 48411 } 48412 const [firstBlock] = blocks; 48413 return { 48414 blockVariationTransformations: getBlockVariations(firstBlock.name, 'transform'), 48415 activeBlockVariation: getActiveBlockVariation(firstBlock.name, getBlockAttributes(firstBlock.clientId)) 48416 }; 48417 }, [clientIds, blocks]); 48418 const transformations = (0,external_wp_element_namespaceObject.useMemo)(() => { 48419 return blockVariationTransformations?.filter(({ 48420 name 48421 }) => name !== activeBlockVariation?.name); 48422 }, [blockVariationTransformations, activeBlockVariation]); 48423 return transformations; 48424 } 48425 const BlockVariationTransformations = ({ 48426 transformations, 48427 onSelect, 48428 blocks 48429 }) => { 48430 const [hoveredTransformItemName, setHoveredTransformItemName] = (0,external_wp_element_namespaceObject.useState)(); 48431 return (0,external_React_.createElement)(external_React_.Fragment, null, hoveredTransformItemName && (0,external_React_.createElement)(PreviewBlockPopover, { 48432 blocks: (0,external_wp_blocks_namespaceObject.cloneBlock)(blocks[0], transformations.find(({ 48433 name 48434 }) => name === hoveredTransformItemName).attributes) 48435 }), transformations?.map(item => (0,external_React_.createElement)(BlockVariationTranformationItem, { 48436 key: item.name, 48437 item: item, 48438 onSelect: onSelect, 48439 setHoveredTransformItemName: setHoveredTransformItemName 48440 }))); 48441 }; 48442 function BlockVariationTranformationItem({ 48443 item, 48444 onSelect, 48445 setHoveredTransformItemName 48446 }) { 48447 const { 48448 name, 48449 icon, 48450 title 48451 } = item; 48452 return (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 48453 className: (0,external_wp_blocks_namespaceObject.getBlockMenuDefaultClassName)(name), 48454 onClick: event => { 48455 event.preventDefault(); 48456 onSelect(name); 48457 }, 48458 onMouseLeave: () => setHoveredTransformItemName(null), 48459 onMouseEnter: () => setHoveredTransformItemName(name) 48460 }, (0,external_React_.createElement)(block_icon, { 48461 icon: icon, 48462 showColors: true 48463 }), title); 48464 } 48465 /* harmony default export */ const block_variation_transformations = (BlockVariationTransformations); 48466 48467 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-switcher/block-transformations-menu.js 48468 48469 /** 48470 * WordPress dependencies 48471 */ 48472 48473 48474 48475 48476 48477 /** 48478 * Internal dependencies 48479 */ 48480 48481 48482 48483 48484 /** 48485 * Helper hook to group transformations to display them in a specific order in the UI. 48486 * For now we group only priority content driven transformations(ex. paragraph -> heading). 48487 * 48488 * Later on we could also group 'layout' transformations(ex. paragraph -> group) and 48489 * display them in different sections. 48490 * 48491 * @param {Object[]} possibleBlockTransformations The available block transformations. 48492 * @return {Record<string, Object[]>} The grouped block transformations. 48493 */ 48494 function useGroupedTransforms(possibleBlockTransformations) { 48495 const priorityContentTranformationBlocks = { 48496 'core/paragraph': 1, 48497 'core/heading': 2, 48498 'core/list': 3, 48499 'core/quote': 4 48500 }; 48501 const transformations = (0,external_wp_element_namespaceObject.useMemo)(() => { 48502 const priorityTextTranformsNames = Object.keys(priorityContentTranformationBlocks); 48503 const groupedPossibleTransforms = possibleBlockTransformations.reduce((accumulator, item) => { 48504 const { 48505 name 48506 } = item; 48507 if (priorityTextTranformsNames.includes(name)) { 48508 accumulator.priorityTextTransformations.push(item); 48509 } else { 48510 accumulator.restTransformations.push(item); 48511 } 48512 return accumulator; 48513 }, { 48514 priorityTextTransformations: [], 48515 restTransformations: [] 48516 }); 48517 /** 48518 * If there is only one priority text transformation and it's a Quote, 48519 * is should move to the rest transformations. This is because Quote can 48520 * be a container for any block type, so in multi-block selection it will 48521 * always be suggested, even for non-text blocks. 48522 */ 48523 if (groupedPossibleTransforms.priorityTextTransformations.length === 1 && groupedPossibleTransforms.priorityTextTransformations[0].name === 'core/quote') { 48524 const singleQuote = groupedPossibleTransforms.priorityTextTransformations.pop(); 48525 groupedPossibleTransforms.restTransformations.push(singleQuote); 48526 } 48527 return groupedPossibleTransforms; 48528 }, [possibleBlockTransformations]); 48529 48530 // Order the priority text transformations. 48531 transformations.priorityTextTransformations.sort(({ 48532 name: currentName 48533 }, { 48534 name: nextName 48535 }) => { 48536 return priorityContentTranformationBlocks[currentName] < priorityContentTranformationBlocks[nextName] ? -1 : 1; 48537 }); 48538 return transformations; 48539 } 48540 const BlockTransformationsMenu = ({ 48541 className, 48542 possibleBlockTransformations, 48543 possibleBlockVariationTransformations, 48544 onSelect, 48545 onSelectVariation, 48546 blocks 48547 }) => { 48548 const [hoveredTransformItemName, setHoveredTransformItemName] = (0,external_wp_element_namespaceObject.useState)(); 48549 const { 48550 priorityTextTransformations, 48551 restTransformations 48552 } = useGroupedTransforms(possibleBlockTransformations); 48553 // We have to check if both content transformations(priority and rest) are set 48554 // in order to create a separate MenuGroup for them. 48555 const hasBothContentTransformations = priorityTextTransformations.length && restTransformations.length; 48556 const restTransformItems = !!restTransformations.length && (0,external_React_.createElement)(RestTransformationItems, { 48557 restTransformations: restTransformations, 48558 onSelect: onSelect, 48559 setHoveredTransformItemName: setHoveredTransformItemName 48560 }); 48561 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuGroup, { 48562 label: (0,external_wp_i18n_namespaceObject.__)('Transform to'), 48563 className: className 48564 }, hoveredTransformItemName && (0,external_React_.createElement)(PreviewBlockPopover, { 48565 blocks: (0,external_wp_blocks_namespaceObject.switchToBlockType)(blocks, hoveredTransformItemName) 48566 }), !!possibleBlockVariationTransformations?.length && (0,external_React_.createElement)(block_variation_transformations, { 48567 transformations: possibleBlockVariationTransformations, 48568 blocks: blocks, 48569 onSelect: onSelectVariation 48570 }), priorityTextTransformations.map(item => (0,external_React_.createElement)(BlockTranformationItem, { 48571 key: item.name, 48572 item: item, 48573 onSelect: onSelect, 48574 setHoveredTransformItemName: setHoveredTransformItemName 48575 })), !hasBothContentTransformations && restTransformItems), !!hasBothContentTransformations && (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuGroup, { 48576 className: className 48577 }, restTransformItems)); 48578 }; 48579 function RestTransformationItems({ 48580 restTransformations, 48581 onSelect, 48582 setHoveredTransformItemName 48583 }) { 48584 return restTransformations.map(item => (0,external_React_.createElement)(BlockTranformationItem, { 48585 key: item.name, 48586 item: item, 48587 onSelect: onSelect, 48588 setHoveredTransformItemName: setHoveredTransformItemName 48589 })); 48590 } 48591 function BlockTranformationItem({ 48592 item, 48593 onSelect, 48594 setHoveredTransformItemName 48595 }) { 48596 const { 48597 name, 48598 icon, 48599 title, 48600 isDisabled 48601 } = item; 48602 return (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 48603 className: (0,external_wp_blocks_namespaceObject.getBlockMenuDefaultClassName)(name), 48604 onClick: event => { 48605 event.preventDefault(); 48606 onSelect(name); 48607 }, 48608 disabled: isDisabled, 48609 onMouseLeave: () => setHoveredTransformItemName(null), 48610 onMouseEnter: () => setHoveredTransformItemName(name) 48611 }, (0,external_React_.createElement)(block_icon, { 48612 icon: icon, 48613 showColors: true 48614 }), title); 48615 } 48616 /* harmony default export */ const block_transformations_menu = (BlockTransformationsMenu); 48617 48618 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-styles/utils.js 48619 /** 48620 * WordPress dependencies 48621 */ 48622 48623 48624 48625 /** 48626 * Returns the active style from the given className. 48627 * 48628 * @param {Array} styles Block styles. 48629 * @param {string} className Class name 48630 * 48631 * @return {Object?} The active style. 48632 */ 48633 function getActiveStyle(styles, className) { 48634 for (const style of new (external_wp_tokenList_default())(className).values()) { 48635 if (style.indexOf('is-style-') === -1) { 48636 continue; 48637 } 48638 const potentialStyleName = style.substring(9); 48639 const activeStyle = styles?.find(({ 48640 name 48641 }) => name === potentialStyleName); 48642 if (activeStyle) { 48643 return activeStyle; 48644 } 48645 } 48646 return getDefaultStyle(styles); 48647 } 48648 48649 /** 48650 * Replaces the active style in the block's className. 48651 * 48652 * @param {string} className Class name. 48653 * @param {Object?} activeStyle The replaced style. 48654 * @param {Object} newStyle The replacing style. 48655 * 48656 * @return {string} The updated className. 48657 */ 48658 function replaceActiveStyle(className, activeStyle, newStyle) { 48659 const list = new (external_wp_tokenList_default())(className); 48660 if (activeStyle) { 48661 list.remove('is-style-' + activeStyle.name); 48662 } 48663 list.add('is-style-' + newStyle.name); 48664 return list.value; 48665 } 48666 48667 /** 48668 * Returns a collection of styles that can be represented on the frontend. 48669 * The function checks a style collection for a default style. If none is found, it adds one to 48670 * act as a fallback for when there is no active style applied to a block. The default item also serves 48671 * as a switch on the frontend to deactivate non-default styles. 48672 * 48673 * @param {Array} styles Block styles. 48674 * 48675 * @return {Array<Object?>} The style collection. 48676 */ 48677 function getRenderedStyles(styles) { 48678 if (!styles || styles.length === 0) { 48679 return []; 48680 } 48681 return getDefaultStyle(styles) ? styles : [{ 48682 name: 'default', 48683 label: (0,external_wp_i18n_namespaceObject._x)('Default', 'block style'), 48684 isDefault: true 48685 }, ...styles]; 48686 } 48687 48688 /** 48689 * Returns a style object from a collection of styles where that style object is the default block style. 48690 * 48691 * @param {Array} styles Block styles. 48692 * 48693 * @return {Object?} The default style object, if found. 48694 */ 48695 function getDefaultStyle(styles) { 48696 return styles?.find(style => style.isDefault); 48697 } 48698 48699 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-styles/use-styles-for-block.js 48700 /** 48701 * WordPress dependencies 48702 */ 48703 48704 48705 48706 48707 /** 48708 * Internal dependencies 48709 */ 48710 48711 48712 48713 /** 48714 * 48715 * @param {WPBlock} block Block object. 48716 * @param {WPBlockType} type Block type settings. 48717 * @return {WPBlock} A generic block ready for styles preview. 48718 */ 48719 function useGenericPreviewBlock(block, type) { 48720 return (0,external_wp_element_namespaceObject.useMemo)(() => { 48721 const example = type?.example; 48722 const blockName = type?.name; 48723 if (example && blockName) { 48724 return (0,external_wp_blocks_namespaceObject.getBlockFromExample)(blockName, { 48725 attributes: example.attributes, 48726 innerBlocks: example.innerBlocks 48727 }); 48728 } 48729 if (block) { 48730 return (0,external_wp_blocks_namespaceObject.cloneBlock)(block); 48731 } 48732 }, [type?.example ? block?.name : block, type]); 48733 } 48734 48735 /** 48736 * @typedef useStylesForBlocksArguments 48737 * @property {string} clientId Block client ID. 48738 * @property {() => void} onSwitch Block style switch callback function. 48739 */ 48740 48741 /** 48742 * 48743 * @param {useStylesForBlocksArguments} useStylesForBlocks arguments. 48744 * @return {Object} Results of the select methods. 48745 */ 48746 function useStylesForBlocks({ 48747 clientId, 48748 onSwitch 48749 }) { 48750 const selector = select => { 48751 const { 48752 getBlock 48753 } = select(store); 48754 const block = getBlock(clientId); 48755 if (!block) { 48756 return {}; 48757 } 48758 const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(block.name); 48759 const { 48760 getBlockStyles 48761 } = select(external_wp_blocks_namespaceObject.store); 48762 return { 48763 block, 48764 blockType, 48765 styles: getBlockStyles(block.name), 48766 className: block.attributes.className || '' 48767 }; 48768 }; 48769 const { 48770 styles, 48771 block, 48772 blockType, 48773 className 48774 } = (0,external_wp_data_namespaceObject.useSelect)(selector, [clientId]); 48775 const { 48776 updateBlockAttributes 48777 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 48778 const stylesToRender = getRenderedStyles(styles); 48779 const activeStyle = getActiveStyle(stylesToRender, className); 48780 const genericPreviewBlock = useGenericPreviewBlock(block, blockType); 48781 const onSelect = style => { 48782 const styleClassName = replaceActiveStyle(className, activeStyle, style); 48783 updateBlockAttributes(clientId, { 48784 className: styleClassName 48785 }); 48786 onSwitch(); 48787 }; 48788 return { 48789 onSelect, 48790 stylesToRender, 48791 activeStyle, 48792 genericPreviewBlock, 48793 className 48794 }; 48795 } 48796 48797 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-styles/menu-items.js 48798 48799 /** 48800 * WordPress dependencies 48801 */ 48802 48803 48804 48805 /** 48806 * Internal dependencies 48807 */ 48808 48809 const menu_items_noop = () => {}; 48810 function BlockStylesMenuItems({ 48811 clientId, 48812 onSwitch = menu_items_noop 48813 }) { 48814 const { 48815 onSelect, 48816 stylesToRender, 48817 activeStyle 48818 } = useStylesForBlocks({ 48819 clientId, 48820 onSwitch 48821 }); 48822 if (!stylesToRender || stylesToRender.length === 0) { 48823 return null; 48824 } 48825 return (0,external_React_.createElement)(external_React_.Fragment, null, stylesToRender.map(style => { 48826 const menuItemText = style.label || style.name; 48827 return (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 48828 key: style.name, 48829 icon: activeStyle.name === style.name ? library_check : null, 48830 onClick: () => onSelect(style) 48831 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalText, { 48832 as: "span", 48833 limit: 18, 48834 ellipsizeMode: "tail", 48835 truncate: true 48836 }, menuItemText)); 48837 })); 48838 } 48839 48840 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-switcher/block-styles-menu.js 48841 48842 /** 48843 * WordPress dependencies 48844 */ 48845 48846 48847 48848 /** 48849 * Internal dependencies 48850 */ 48851 48852 function BlockStylesMenu({ 48853 hoveredBlock, 48854 onSwitch 48855 }) { 48856 const { 48857 clientId 48858 } = hoveredBlock; 48859 return (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuGroup, { 48860 label: (0,external_wp_i18n_namespaceObject.__)('Styles'), 48861 className: "block-editor-block-switcher__styles__menugroup" 48862 }, (0,external_React_.createElement)(BlockStylesMenuItems, { 48863 clientId: clientId, 48864 onSwitch: onSwitch 48865 })); 48866 } 48867 48868 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-switcher/utils.js 48869 /** 48870 * WordPress dependencies 48871 */ 48872 48873 48874 /** 48875 * Try to find a matching block by a block's name in a provided 48876 * block. We recurse through InnerBlocks and return the reference 48877 * of the matched block (it could be an InnerBlock). 48878 * If no match is found return nothing. 48879 * 48880 * @param {WPBlock} block The block to try to find a match. 48881 * @param {string} selectedBlockName The block's name to use for matching condition. 48882 * @param {Set} consumedBlocks A set holding the previously matched/consumed blocks. 48883 * 48884 * @return {WPBlock | undefined} The matched block if found or nothing(`undefined`). 48885 */ 48886 const getMatchingBlockByName = (block, selectedBlockName, consumedBlocks = new Set()) => { 48887 const { 48888 clientId, 48889 name, 48890 innerBlocks = [] 48891 } = block; 48892 // Check if block has been consumed already. 48893 if (consumedBlocks.has(clientId)) return; 48894 if (name === selectedBlockName) return block; 48895 // Try to find a matching block from InnerBlocks recursively. 48896 for (const innerBlock of innerBlocks) { 48897 const match = getMatchingBlockByName(innerBlock, selectedBlockName, consumedBlocks); 48898 if (match) return match; 48899 } 48900 }; 48901 48902 /** 48903 * Find and return the block attributes to retain through 48904 * the transformation, based on Block Type's `role:content` 48905 * attributes. If no `role:content` attributes exist, 48906 * return selected block's attributes. 48907 * 48908 * @param {string} name Block type's namespaced name. 48909 * @param {Object} attributes Selected block's attributes. 48910 * @return {Object} The block's attributes to retain. 48911 */ 48912 const getRetainedBlockAttributes = (name, attributes) => { 48913 const contentAttributes = (0,external_wp_blocks_namespaceObject.__experimentalGetBlockAttributesNamesByRole)(name, 'content'); 48914 if (!contentAttributes?.length) return attributes; 48915 return contentAttributes.reduce((_accumulator, attribute) => { 48916 if (attributes[attribute]) _accumulator[attribute] = attributes[attribute]; 48917 return _accumulator; 48918 }, {}); 48919 }; 48920 48921 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-switcher/use-transformed-patterns.js 48922 /** 48923 * WordPress dependencies 48924 */ 48925 48926 48927 48928 /** 48929 * Internal dependencies 48930 */ 48931 48932 48933 /** 48934 * Mutate the matched block's attributes by getting 48935 * which block type's attributes to retain and prioritize 48936 * them in the merging of the attributes. 48937 * 48938 * @param {WPBlock} match The matched block. 48939 * @param {WPBlock} selectedBlock The selected block. 48940 * @return {void} 48941 */ 48942 const transformMatchingBlock = (match, selectedBlock) => { 48943 // Get the block attributes to retain through the transformation. 48944 const retainedBlockAttributes = getRetainedBlockAttributes(selectedBlock.name, selectedBlock.attributes); 48945 match.attributes = { 48946 ...match.attributes, 48947 ...retainedBlockAttributes 48948 }; 48949 }; 48950 48951 /** 48952 * By providing the selected blocks and pattern's blocks 48953 * find the matching blocks, transform them and return them. 48954 * If not all selected blocks are matched, return nothing. 48955 * 48956 * @param {WPBlock[]} selectedBlocks The selected blocks. 48957 * @param {WPBlock[]} patternBlocks The pattern's blocks. 48958 * @return {WPBlock[]|void} The transformed pattern's blocks or undefined if not all selected blocks have been matched. 48959 */ 48960 const getPatternTransformedBlocks = (selectedBlocks, patternBlocks) => { 48961 // Clone Pattern's blocks to produce new clientIds and be able to mutate the matches. 48962 const _patternBlocks = patternBlocks.map(block => (0,external_wp_blocks_namespaceObject.cloneBlock)(block)); 48963 /** 48964 * Keep track of the consumed pattern blocks. 48965 * This is needed because we loop the selected blocks 48966 * and for example we may have selected two paragraphs and 48967 * the pattern's blocks could have more `paragraphs`. 48968 */ 48969 const consumedBlocks = new Set(); 48970 for (const selectedBlock of selectedBlocks) { 48971 let isMatch = false; 48972 for (const patternBlock of _patternBlocks) { 48973 const match = getMatchingBlockByName(patternBlock, selectedBlock.name, consumedBlocks); 48974 if (!match) continue; 48975 isMatch = true; 48976 consumedBlocks.add(match.clientId); 48977 // We update (mutate) the matching pattern block. 48978 transformMatchingBlock(match, selectedBlock); 48979 // No need to loop through other pattern's blocks. 48980 break; 48981 } 48982 // Bail eary if a selected block has not been matched. 48983 if (!isMatch) return; 48984 } 48985 return _patternBlocks; 48986 }; 48987 48988 /** 48989 * @typedef {WPBlockPattern & {transformedBlocks: WPBlock[]}} TransformedBlockPattern 48990 */ 48991 48992 /** 48993 * Custom hook that accepts patterns from state and the selected 48994 * blocks and tries to match these with the pattern's blocks. 48995 * If all selected blocks are matched with a Pattern's block, 48996 * we transform them by retaining block's attributes with `role:content`. 48997 * The transformed pattern's blocks are set to a new pattern 48998 * property `transformedBlocks`. 48999 * 49000 * @param {WPBlockPattern[]} patterns Patterns from state. 49001 * @param {WPBlock[]} selectedBlocks The currently selected blocks. 49002 * @return {TransformedBlockPattern[]} Returns the eligible matched patterns with all the selected blocks. 49003 */ 49004 const useTransformedPatterns = (patterns, selectedBlocks) => { 49005 return (0,external_wp_element_namespaceObject.useMemo)(() => patterns.reduce((accumulator, _pattern) => { 49006 const transformedBlocks = getPatternTransformedBlocks(selectedBlocks, _pattern.blocks); 49007 if (transformedBlocks) { 49008 accumulator.push({ 49009 ..._pattern, 49010 transformedBlocks 49011 }); 49012 } 49013 return accumulator; 49014 }, []), [patterns, selectedBlocks]); 49015 }; 49016 /* harmony default export */ const use_transformed_patterns = (useTransformedPatterns); 49017 49018 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-switcher/pattern-transformations-menu.js 49019 49020 /** 49021 * WordPress dependencies 49022 */ 49023 49024 49025 49026 49027 49028 49029 /** 49030 * Internal dependencies 49031 */ 49032 49033 49034 49035 const { 49036 CompositeV2: pattern_transformations_menu_Composite, 49037 CompositeItemV2: pattern_transformations_menu_CompositeItem, 49038 useCompositeStoreV2: pattern_transformations_menu_useCompositeStore 49039 } = unlock(external_wp_components_namespaceObject.privateApis); 49040 function PatternTransformationsMenu({ 49041 blocks, 49042 patterns: statePatterns, 49043 onSelect 49044 }) { 49045 const [showTransforms, setShowTransforms] = (0,external_wp_element_namespaceObject.useState)(false); 49046 const patterns = use_transformed_patterns(statePatterns, blocks); 49047 if (!patterns.length) return null; 49048 return (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuGroup, { 49049 className: "block-editor-block-switcher__pattern__transforms__menugroup" 49050 }, showTransforms && (0,external_React_.createElement)(PreviewPatternsPopover, { 49051 patterns: patterns, 49052 onSelect: onSelect 49053 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 49054 onClick: event => { 49055 event.preventDefault(); 49056 setShowTransforms(!showTransforms); 49057 }, 49058 icon: chevron_right 49059 }, (0,external_wp_i18n_namespaceObject.__)('Patterns'))); 49060 } 49061 function PreviewPatternsPopover({ 49062 patterns, 49063 onSelect 49064 }) { 49065 return (0,external_React_.createElement)("div", { 49066 className: "block-editor-block-switcher__popover__preview__parent" 49067 }, (0,external_React_.createElement)("div", { 49068 className: "block-editor-block-switcher__popover__preview__container" 49069 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Popover, { 49070 className: "block-editor-block-switcher__preview__popover", 49071 position: "bottom right" 49072 }, (0,external_React_.createElement)("div", { 49073 className: "block-editor-block-switcher__preview is-pattern-list-preview" 49074 }, (0,external_React_.createElement)(pattern_transformations_menu_BlockPatternsList, { 49075 patterns: patterns, 49076 onSelect: onSelect 49077 }))))); 49078 } 49079 function pattern_transformations_menu_BlockPatternsList({ 49080 patterns, 49081 onSelect 49082 }) { 49083 const composite = pattern_transformations_menu_useCompositeStore(); 49084 return (0,external_React_.createElement)(pattern_transformations_menu_Composite, { 49085 store: composite, 49086 role: "listbox", 49087 className: "block-editor-block-switcher__preview-patterns-container", 49088 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Patterns list') 49089 }, patterns.map(pattern => (0,external_React_.createElement)(pattern_transformations_menu_BlockPattern, { 49090 key: pattern.name, 49091 pattern: pattern, 49092 onSelect: onSelect 49093 }))); 49094 } 49095 function pattern_transformations_menu_BlockPattern({ 49096 pattern, 49097 onSelect 49098 }) { 49099 // TODO check pattern/preview width... 49100 const baseClassName = 'block-editor-block-switcher__preview-patterns-container'; 49101 const descriptionId = (0,external_wp_compose_namespaceObject.useInstanceId)(pattern_transformations_menu_BlockPattern, `$baseClassName}-list__item-description`); 49102 return (0,external_React_.createElement)("div", { 49103 className: `$baseClassName}-list__list-item` 49104 }, (0,external_React_.createElement)(pattern_transformations_menu_CompositeItem, { 49105 render: (0,external_React_.createElement)("div", { 49106 role: "option", 49107 "aria-label": pattern.title, 49108 "aria-describedby": pattern.description ? descriptionId : undefined, 49109 className: `$baseClassName}-list__item` 49110 }), 49111 onClick: () => onSelect(pattern.transformedBlocks) 49112 }, (0,external_React_.createElement)(block_preview, { 49113 blocks: pattern.transformedBlocks, 49114 viewportWidth: pattern.viewportWidth || 500 49115 }), (0,external_React_.createElement)("div", { 49116 className: `$baseClassName}-list__item-title` 49117 }, pattern.title)), !!pattern.description && (0,external_React_.createElement)(external_wp_components_namespaceObject.VisuallyHidden, { 49118 id: descriptionId 49119 }, pattern.description)); 49120 } 49121 /* harmony default export */ const pattern_transformations_menu = (PatternTransformationsMenu); 49122 49123 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-switcher/index.js 49124 49125 /** 49126 * WordPress dependencies 49127 */ 49128 49129 49130 49131 49132 49133 49134 /** 49135 * Internal dependencies 49136 */ 49137 49138 49139 49140 49141 49142 49143 49144 function BlockSwitcherDropdownMenuContents({ 49145 onClose, 49146 clientIds, 49147 hasBlockStyles, 49148 canRemove 49149 }) { 49150 const { 49151 replaceBlocks, 49152 multiSelect, 49153 updateBlockAttributes 49154 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 49155 const { 49156 possibleBlockTransformations, 49157 patterns, 49158 blocks 49159 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 49160 const { 49161 getBlocksByClientId, 49162 getBlockRootClientId, 49163 getBlockTransformItems, 49164 __experimentalGetPatternTransformItems 49165 } = select(store); 49166 const rootClientId = getBlockRootClientId(Array.isArray(clientIds) ? clientIds[0] : clientIds); 49167 const _blocks = getBlocksByClientId(clientIds); 49168 return { 49169 blocks: _blocks, 49170 possibleBlockTransformations: getBlockTransformItems(_blocks, rootClientId), 49171 patterns: __experimentalGetPatternTransformItems(_blocks, rootClientId) 49172 }; 49173 }, [clientIds]); 49174 const blockVariationTransformations = useBlockVariationTransforms({ 49175 clientIds, 49176 blocks 49177 }); 49178 function selectForMultipleBlocks(insertedBlocks) { 49179 if (insertedBlocks.length > 1) { 49180 multiSelect(insertedBlocks[0].clientId, insertedBlocks[insertedBlocks.length - 1].clientId); 49181 } 49182 } 49183 // Simple block tranformation based on the `Block Transforms` API. 49184 function onBlockTransform(name) { 49185 const newBlocks = (0,external_wp_blocks_namespaceObject.switchToBlockType)(blocks, name); 49186 replaceBlocks(clientIds, newBlocks); 49187 selectForMultipleBlocks(newBlocks); 49188 } 49189 function onBlockVariationTransform(name) { 49190 updateBlockAttributes(blocks[0].clientId, { 49191 ...blockVariationTransformations.find(({ 49192 name: variationName 49193 }) => variationName === name).attributes 49194 }); 49195 } 49196 // Pattern transformation through the `Patterns` API. 49197 function onPatternTransform(transformedBlocks) { 49198 replaceBlocks(clientIds, transformedBlocks); 49199 selectForMultipleBlocks(transformedBlocks); 49200 } 49201 /** 49202 * The `isTemplate` check is a stopgap solution here. 49203 * Ideally, the Transforms API should handle this 49204 * by allowing to exclude blocks from wildcard transformations. 49205 */ 49206 const isSingleBlock = blocks.length === 1; 49207 const isTemplate = isSingleBlock && (0,external_wp_blocks_namespaceObject.isTemplatePart)(blocks[0]); 49208 const hasPossibleBlockTransformations = !!possibleBlockTransformations.length && canRemove && !isTemplate; 49209 const hasPossibleBlockVariationTransformations = !!blockVariationTransformations?.length; 49210 const hasPatternTransformation = !!patterns?.length && canRemove; 49211 const hasBlockOrBlockVariationTransforms = hasPossibleBlockTransformations || hasPossibleBlockVariationTransformations; 49212 const hasContents = hasBlockStyles || hasBlockOrBlockVariationTransforms || hasPatternTransformation; 49213 if (!hasContents) { 49214 return (0,external_React_.createElement)("p", { 49215 className: "block-editor-block-switcher__no-transforms" 49216 }, (0,external_wp_i18n_namespaceObject.__)('No transforms.')); 49217 } 49218 return (0,external_React_.createElement)("div", { 49219 className: "block-editor-block-switcher__container" 49220 }, hasPatternTransformation && (0,external_React_.createElement)(pattern_transformations_menu, { 49221 blocks: blocks, 49222 patterns: patterns, 49223 onSelect: transformedBlocks => { 49224 onPatternTransform(transformedBlocks); 49225 onClose(); 49226 } 49227 }), hasBlockOrBlockVariationTransforms && (0,external_React_.createElement)(block_transformations_menu, { 49228 className: "block-editor-block-switcher__transforms__menugroup", 49229 possibleBlockTransformations: possibleBlockTransformations, 49230 possibleBlockVariationTransformations: blockVariationTransformations, 49231 blocks: blocks, 49232 onSelect: name => { 49233 onBlockTransform(name); 49234 onClose(); 49235 }, 49236 onSelectVariation: name => { 49237 onBlockVariationTransform(name); 49238 onClose(); 49239 } 49240 }), hasBlockStyles && (0,external_React_.createElement)(BlockStylesMenu, { 49241 hoveredBlock: blocks[0], 49242 onSwitch: onClose 49243 })); 49244 } 49245 const BlockSwitcher = ({ 49246 clientIds 49247 }) => { 49248 const { 49249 canRemove, 49250 hasBlockStyles, 49251 icon, 49252 invalidBlocks, 49253 isReusable, 49254 isTemplate 49255 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 49256 const { 49257 getBlockRootClientId, 49258 getBlocksByClientId, 49259 getBlockAttributes, 49260 canRemoveBlocks 49261 } = select(store); 49262 const { 49263 getBlockStyles, 49264 getBlockType, 49265 getActiveBlockVariation 49266 } = select(external_wp_blocks_namespaceObject.store); 49267 const _blocks = getBlocksByClientId(clientIds); 49268 if (!_blocks.length || _blocks.some(block => !block)) { 49269 return { 49270 invalidBlocks: true 49271 }; 49272 } 49273 const rootClientId = getBlockRootClientId(Array.isArray(clientIds) ? clientIds[0] : clientIds); 49274 const [{ 49275 name: firstBlockName 49276 }] = _blocks; 49277 const _isSingleBlockSelected = _blocks.length === 1; 49278 const blockType = getBlockType(firstBlockName); 49279 let _icon; 49280 if (_isSingleBlockSelected) { 49281 const match = getActiveBlockVariation(firstBlockName, getBlockAttributes(clientIds[0])); 49282 // Take into account active block variations. 49283 _icon = match?.icon || blockType.icon; 49284 } else { 49285 const isSelectionOfSameType = new Set(_blocks.map(({ 49286 name 49287 }) => name)).size === 1; 49288 // When selection consists of blocks of multiple types, display an 49289 // appropriate icon to communicate the non-uniformity. 49290 _icon = isSelectionOfSameType ? blockType.icon : library_copy; 49291 } 49292 return { 49293 canRemove: canRemoveBlocks(clientIds, rootClientId), 49294 hasBlockStyles: _isSingleBlockSelected && !!getBlockStyles(firstBlockName)?.length, 49295 icon: _icon, 49296 isReusable: _isSingleBlockSelected && (0,external_wp_blocks_namespaceObject.isReusableBlock)(_blocks[0]), 49297 isTemplate: _isSingleBlockSelected && (0,external_wp_blocks_namespaceObject.isTemplatePart)(_blocks[0]) 49298 }; 49299 }, [clientIds]); 49300 const blockTitle = useBlockDisplayTitle({ 49301 clientId: clientIds?.[0], 49302 maximumLength: 35 49303 }); 49304 if (invalidBlocks) { 49305 return null; 49306 } 49307 const isSingleBlock = clientIds.length === 1; 49308 const blockSwitcherLabel = isSingleBlock ? blockTitle : (0,external_wp_i18n_namespaceObject.__)('Multiple blocks selected'); 49309 const hideDropdown = !hasBlockStyles && !canRemove; 49310 if (hideDropdown) { 49311 return (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarGroup, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarButton, { 49312 disabled: true, 49313 className: "block-editor-block-switcher__no-switcher-icon", 49314 title: blockSwitcherLabel, 49315 icon: (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(block_icon, { 49316 icon: icon, 49317 showColors: true 49318 }), (isReusable || isTemplate) && (0,external_React_.createElement)("span", { 49319 className: "block-editor-block-switcher__toggle-text" 49320 }, blockTitle)) 49321 })); 49322 } 49323 const blockSwitcherDescription = isSingleBlock ? (0,external_wp_i18n_namespaceObject.__)('Change block type or style') : (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %d: number of blocks. */ 49324 (0,external_wp_i18n_namespaceObject._n)('Change type of %d block', 'Change type of %d blocks', clientIds.length), clientIds.length); 49325 return (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarGroup, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarItem, null, toggleProps => (0,external_React_.createElement)(external_wp_components_namespaceObject.DropdownMenu, { 49326 className: "block-editor-block-switcher", 49327 label: blockSwitcherLabel, 49328 popoverProps: { 49329 placement: 'bottom-start', 49330 className: 'block-editor-block-switcher__popover' 49331 }, 49332 icon: (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(block_icon, { 49333 icon: icon, 49334 className: "block-editor-block-switcher__toggle", 49335 showColors: true 49336 }), (isReusable || isTemplate) && (0,external_React_.createElement)("span", { 49337 className: "block-editor-block-switcher__toggle-text" 49338 }, blockTitle)), 49339 toggleProps: { 49340 describedBy: blockSwitcherDescription, 49341 ...toggleProps 49342 }, 49343 menuProps: { 49344 orientation: 'both' 49345 } 49346 }, ({ 49347 onClose 49348 }) => (0,external_React_.createElement)(BlockSwitcherDropdownMenuContents, { 49349 onClose: onClose, 49350 clientIds: clientIds, 49351 hasBlockStyles: hasBlockStyles, 49352 canRemove: canRemove 49353 })))); 49354 }; 49355 /* harmony default export */ const block_switcher = (BlockSwitcher); 49356 49357 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-toolbar/block-toolbar-last-item.js 49358 /** 49359 * WordPress dependencies 49360 */ 49361 49362 const { 49363 Fill: __unstableBlockToolbarLastItem, 49364 Slot: block_toolbar_last_item_Slot 49365 } = (0,external_wp_components_namespaceObject.createSlotFill)('__unstableBlockToolbarLastItem'); 49366 __unstableBlockToolbarLastItem.Slot = block_toolbar_last_item_Slot; 49367 /* harmony default export */ const block_toolbar_last_item = (__unstableBlockToolbarLastItem); 49368 49369 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/supports.js 49370 /** 49371 * WordPress dependencies 49372 */ 49373 49374 49375 const ALIGN_SUPPORT_KEY = 'align'; 49376 const ALIGN_WIDE_SUPPORT_KEY = 'alignWide'; 49377 const supports_BORDER_SUPPORT_KEY = '__experimentalBorder'; 49378 const supports_COLOR_SUPPORT_KEY = 'color'; 49379 const CUSTOM_CLASS_NAME_SUPPORT_KEY = 'customClassName'; 49380 const supports_FONT_FAMILY_SUPPORT_KEY = 'typography.__experimentalFontFamily'; 49381 const supports_FONT_SIZE_SUPPORT_KEY = 'typography.fontSize'; 49382 const supports_LINE_HEIGHT_SUPPORT_KEY = 'typography.lineHeight'; 49383 /** 49384 * Key within block settings' support array indicating support for font style. 49385 */ 49386 const supports_FONT_STYLE_SUPPORT_KEY = 'typography.__experimentalFontStyle'; 49387 /** 49388 * Key within block settings' support array indicating support for font weight. 49389 */ 49390 const supports_FONT_WEIGHT_SUPPORT_KEY = 'typography.__experimentalFontWeight'; 49391 /** 49392 * Key within block settings' supports array indicating support for text 49393 * columns e.g. settings found in `block.json`. 49394 */ 49395 const supports_TEXT_COLUMNS_SUPPORT_KEY = 'typography.textColumns'; 49396 /** 49397 * Key within block settings' supports array indicating support for text 49398 * decorations e.g. settings found in `block.json`. 49399 */ 49400 const supports_TEXT_DECORATION_SUPPORT_KEY = 'typography.__experimentalTextDecoration'; 49401 /** 49402 * Key within block settings' supports array indicating support for writing mode 49403 * e.g. settings found in `block.json`. 49404 */ 49405 const supports_WRITING_MODE_SUPPORT_KEY = 'typography.__experimentalWritingMode'; 49406 /** 49407 * Key within block settings' supports array indicating support for text 49408 * transforms e.g. settings found in `block.json`. 49409 */ 49410 const supports_TEXT_TRANSFORM_SUPPORT_KEY = 'typography.__experimentalTextTransform'; 49411 49412 /** 49413 * Key within block settings' supports array indicating support for letter-spacing 49414 * e.g. settings found in `block.json`. 49415 */ 49416 const supports_LETTER_SPACING_SUPPORT_KEY = 'typography.__experimentalLetterSpacing'; 49417 const LAYOUT_SUPPORT_KEY = 'layout'; 49418 const supports_TYPOGRAPHY_SUPPORT_KEYS = [supports_LINE_HEIGHT_SUPPORT_KEY, supports_FONT_SIZE_SUPPORT_KEY, supports_FONT_STYLE_SUPPORT_KEY, supports_FONT_WEIGHT_SUPPORT_KEY, supports_FONT_FAMILY_SUPPORT_KEY, supports_TEXT_COLUMNS_SUPPORT_KEY, supports_TEXT_DECORATION_SUPPORT_KEY, supports_TEXT_TRANSFORM_SUPPORT_KEY, supports_WRITING_MODE_SUPPORT_KEY, supports_LETTER_SPACING_SUPPORT_KEY]; 49419 const EFFECTS_SUPPORT_KEYS = ['shadow']; 49420 const supports_SPACING_SUPPORT_KEY = 'spacing'; 49421 const supports_styleSupportKeys = [...EFFECTS_SUPPORT_KEYS, ...supports_TYPOGRAPHY_SUPPORT_KEYS, supports_BORDER_SUPPORT_KEY, supports_COLOR_SUPPORT_KEY, supports_SPACING_SUPPORT_KEY]; 49422 49423 /** 49424 * Returns true if the block defines support for align. 49425 * 49426 * @param {string|Object} nameOrType Block name or type object. 49427 * @return {boolean} Whether the block supports the feature. 49428 */ 49429 const hasAlignSupport = nameOrType => (0,external_wp_blocks_namespaceObject.hasBlockSupport)(nameOrType, ALIGN_SUPPORT_KEY); 49430 49431 /** 49432 * Returns the block support value for align, if defined. 49433 * 49434 * @param {string|Object} nameOrType Block name or type object. 49435 * @return {unknown} The block support value. 49436 */ 49437 const getAlignSupport = nameOrType => getBlockSupport(nameOrType, ALIGN_SUPPORT_KEY); 49438 49439 /** 49440 * Returns true if the block defines support for align wide. 49441 * 49442 * @param {string|Object} nameOrType Block name or type object. 49443 * @return {boolean} Whether the block supports the feature. 49444 */ 49445 const hasAlignWideSupport = nameOrType => hasBlockSupport(nameOrType, ALIGN_WIDE_SUPPORT_KEY); 49446 49447 /** 49448 * Returns the block support value for align wide, if defined. 49449 * 49450 * @param {string|Object} nameOrType Block name or type object. 49451 * @return {unknown} The block support value. 49452 */ 49453 const getAlignWideSupport = nameOrType => getBlockSupport(nameOrType, ALIGN_WIDE_SUPPORT_KEY); 49454 49455 /** 49456 * Determine whether there is block support for border properties. 49457 * 49458 * @param {string|Object} nameOrType Block name or type object. 49459 * @param {string} feature Border feature to check support for. 49460 * 49461 * @return {boolean} Whether there is support. 49462 */ 49463 function supports_hasBorderSupport(nameOrType, feature = 'any') { 49464 if (external_wp_element_namespaceObject.Platform.OS !== 'web') { 49465 return false; 49466 } 49467 const support = (0,external_wp_blocks_namespaceObject.getBlockSupport)(nameOrType, supports_BORDER_SUPPORT_KEY); 49468 if (support === true) { 49469 return true; 49470 } 49471 if (feature === 'any') { 49472 return !!(support?.color || support?.radius || support?.width || support?.style); 49473 } 49474 return !!support?.[feature]; 49475 } 49476 49477 /** 49478 * Get block support for border properties. 49479 * 49480 * @param {string|Object} nameOrType Block name or type object. 49481 * @param {string} feature Border feature to get. 49482 * 49483 * @return {unknown} The block support. 49484 */ 49485 const getBorderSupport = (nameOrType, feature) => getBlockSupport(nameOrType, [supports_BORDER_SUPPORT_KEY, feature]); 49486 49487 /** 49488 * Returns true if the block defines support for color. 49489 * 49490 * @param {string|Object} nameOrType Block name or type object. 49491 * @return {boolean} Whether the block supports the feature. 49492 */ 49493 const supports_hasColorSupport = nameOrType => { 49494 const colorSupport = getBlockSupport(nameOrType, supports_COLOR_SUPPORT_KEY); 49495 return colorSupport && (colorSupport.link === true || colorSupport.gradient === true || colorSupport.background !== false || colorSupport.text !== false); 49496 }; 49497 49498 /** 49499 * Returns true if the block defines support for link color. 49500 * 49501 * @param {string|Object} nameOrType Block name or type object. 49502 * @return {boolean} Whether the block supports the feature. 49503 */ 49504 const supports_hasLinkColorSupport = nameOrType => { 49505 if (Platform.OS !== 'web') { 49506 return false; 49507 } 49508 const colorSupport = getBlockSupport(nameOrType, supports_COLOR_SUPPORT_KEY); 49509 return colorSupport !== null && typeof colorSupport === 'object' && !!colorSupport.link; 49510 }; 49511 49512 /** 49513 * Returns true if the block defines support for gradient color. 49514 * 49515 * @param {string|Object} nameOrType Block name or type object. 49516 * @return {boolean} Whether the block supports the feature. 49517 */ 49518 const supports_hasGradientSupport = nameOrType => { 49519 const colorSupport = (0,external_wp_blocks_namespaceObject.getBlockSupport)(nameOrType, supports_COLOR_SUPPORT_KEY); 49520 return colorSupport !== null && typeof colorSupport === 'object' && !!colorSupport.gradients; 49521 }; 49522 49523 /** 49524 * Returns true if the block defines support for background color. 49525 * 49526 * @param {string|Object} nameOrType Block name or type object. 49527 * @return {boolean} Whether the block supports the feature. 49528 */ 49529 const supports_hasBackgroundColorSupport = nameOrType => { 49530 const colorSupport = (0,external_wp_blocks_namespaceObject.getBlockSupport)(nameOrType, supports_COLOR_SUPPORT_KEY); 49531 return colorSupport && colorSupport.background !== false; 49532 }; 49533 49534 /** 49535 * Returns true if the block defines support for background color. 49536 * 49537 * @param {string|Object} nameOrType Block name or type object. 49538 * @return {boolean} Whether the block supports the feature. 49539 */ 49540 const supports_hasTextColorSupport = nameOrType => { 49541 const colorSupport = (0,external_wp_blocks_namespaceObject.getBlockSupport)(nameOrType, supports_COLOR_SUPPORT_KEY); 49542 return colorSupport && colorSupport.text !== false; 49543 }; 49544 49545 /** 49546 * Get block support for color properties. 49547 * 49548 * @param {string|Object} nameOrType Block name or type object. 49549 * @param {string} feature Color feature to get. 49550 * 49551 * @return {unknown} The block support. 49552 */ 49553 const getColorSupport = (nameOrType, feature) => getBlockSupport(nameOrType, [supports_COLOR_SUPPORT_KEY, feature]); 49554 49555 /** 49556 * Returns true if the block defines support for custom class name. 49557 * 49558 * @param {string|Object} nameOrType Block name or type object. 49559 * @return {boolean} Whether the block supports the feature. 49560 */ 49561 const hasCustomClassNameSupport = nameOrType => (0,external_wp_blocks_namespaceObject.hasBlockSupport)(nameOrType, CUSTOM_CLASS_NAME_SUPPORT_KEY, true); 49562 49563 /** 49564 * Returns the block support value for custom class name, if defined. 49565 * 49566 * @param {string|Object} nameOrType Block name or type object. 49567 * @return {unknown} The block support value. 49568 */ 49569 const getCustomClassNameSupport = nameOrType => getBlockSupport(nameOrType, CUSTOM_CLASS_NAME_SUPPORT_KEY, true); 49570 49571 /** 49572 * Returns true if the block defines support for font family. 49573 * 49574 * @param {string|Object} nameOrType Block name or type object. 49575 * @return {boolean} Whether the block supports the feature. 49576 */ 49577 const hasFontFamilySupport = nameOrType => (0,external_wp_blocks_namespaceObject.hasBlockSupport)(nameOrType, supports_FONT_FAMILY_SUPPORT_KEY); 49578 49579 /** 49580 * Returns the block support value for font family, if defined. 49581 * 49582 * @param {string|Object} nameOrType Block name or type object. 49583 * @return {unknown} The block support value. 49584 */ 49585 const getFontFamilySupport = nameOrType => getBlockSupport(nameOrType, supports_FONT_FAMILY_SUPPORT_KEY); 49586 49587 /** 49588 * Returns true if the block defines support for font size. 49589 * 49590 * @param {string|Object} nameOrType Block name or type object. 49591 * @return {boolean} Whether the block supports the feature. 49592 */ 49593 const hasFontSizeSupport = nameOrType => (0,external_wp_blocks_namespaceObject.hasBlockSupport)(nameOrType, supports_FONT_SIZE_SUPPORT_KEY); 49594 49595 /** 49596 * Returns the block support value for font size, if defined. 49597 * 49598 * @param {string|Object} nameOrType Block name or type object. 49599 * @return {unknown} The block support value. 49600 */ 49601 const getFontSizeSupport = nameOrType => getBlockSupport(nameOrType, supports_FONT_SIZE_SUPPORT_KEY); 49602 49603 /** 49604 * Returns true if the block defines support for layout. 49605 * 49606 * @param {string|Object} nameOrType Block name or type object. 49607 * @return {boolean} Whether the block supports the feature. 49608 */ 49609 const hasLayoutSupport = nameOrType => (0,external_wp_blocks_namespaceObject.hasBlockSupport)(nameOrType, LAYOUT_SUPPORT_KEY); 49610 49611 /** 49612 * Returns the block support value for layout, if defined. 49613 * 49614 * @param {string|Object} nameOrType Block name or type object. 49615 * @return {unknown} The block support value. 49616 */ 49617 const getLayoutSupport = nameOrType => getBlockSupport(nameOrType, LAYOUT_SUPPORT_KEY); 49618 49619 /** 49620 * Returns true if the block defines support for style. 49621 * 49622 * @param {string|Object} nameOrType Block name or type object. 49623 * @return {boolean} Whether the block supports the feature. 49624 */ 49625 const supports_hasStyleSupport = nameOrType => supports_styleSupportKeys.some(key => (0,external_wp_blocks_namespaceObject.hasBlockSupport)(nameOrType, key)); 49626 49627 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/use-paste-styles/index.js 49628 /** 49629 * WordPress dependencies 49630 */ 49631 49632 49633 49634 49635 49636 49637 /** 49638 * Internal dependencies 49639 */ 49640 49641 49642 49643 /** 49644 * Determine if the copied text looks like serialized blocks or not. 49645 * Since plain text will always get parsed into a freeform block, 49646 * we check that if the parsed blocks is anything other than that. 49647 * 49648 * @param {string} text The copied text. 49649 * @return {boolean} True if the text looks like serialized blocks, false otherwise. 49650 */ 49651 function hasSerializedBlocks(text) { 49652 try { 49653 const blocks = (0,external_wp_blocks_namespaceObject.parse)(text, { 49654 __unstableSkipMigrationLogs: true, 49655 __unstableSkipAutop: true 49656 }); 49657 if (blocks.length === 1 && blocks[0].name === 'core/freeform') { 49658 // It's likely that the text is just plain text and not serialized blocks. 49659 return false; 49660 } 49661 return true; 49662 } catch (err) { 49663 // Parsing error, the text is not serialized blocks. 49664 // (Even though that it technically won't happen) 49665 return false; 49666 } 49667 } 49668 49669 /** 49670 * Style attributes are attributes being added in `block-editor/src/hooks/*`. 49671 * (Except for some unrelated to style like `anchor` or `settings`.) 49672 * They generally represent the default block supports. 49673 */ 49674 const STYLE_ATTRIBUTES = { 49675 align: hasAlignSupport, 49676 borderColor: nameOrType => supports_hasBorderSupport(nameOrType, 'color'), 49677 backgroundColor: supports_hasBackgroundColorSupport, 49678 textColor: supports_hasTextColorSupport, 49679 gradient: supports_hasGradientSupport, 49680 className: hasCustomClassNameSupport, 49681 fontFamily: hasFontFamilySupport, 49682 fontSize: hasFontSizeSupport, 49683 layout: hasLayoutSupport, 49684 style: supports_hasStyleSupport 49685 }; 49686 49687 /** 49688 * Get the "style attributes" from a given block to a target block. 49689 * 49690 * @param {WPBlock} sourceBlock The source block. 49691 * @param {WPBlock} targetBlock The target block. 49692 * @return {Object} the filtered attributes object. 49693 */ 49694 function getStyleAttributes(sourceBlock, targetBlock) { 49695 return Object.entries(STYLE_ATTRIBUTES).reduce((attributes, [attributeKey, hasSupport]) => { 49696 // Only apply the attribute if both blocks support it. 49697 if (hasSupport(sourceBlock.name) && hasSupport(targetBlock.name)) { 49698 // Override attributes that are not present in the block to their defaults. 49699 attributes[attributeKey] = sourceBlock.attributes[attributeKey]; 49700 } 49701 return attributes; 49702 }, {}); 49703 } 49704 49705 /** 49706 * Update the target blocks with style attributes recursively. 49707 * 49708 * @param {WPBlock[]} targetBlocks The target blocks to be updated. 49709 * @param {WPBlock[]} sourceBlocks The source blocks to get th style attributes from. 49710 * @param {Function} updateBlockAttributes The function to update the attributes. 49711 */ 49712 function recursivelyUpdateBlockAttributes(targetBlocks, sourceBlocks, updateBlockAttributes) { 49713 for (let index = 0; index < Math.min(sourceBlocks.length, targetBlocks.length); index += 1) { 49714 updateBlockAttributes(targetBlocks[index].clientId, getStyleAttributes(sourceBlocks[index], targetBlocks[index])); 49715 recursivelyUpdateBlockAttributes(targetBlocks[index].innerBlocks, sourceBlocks[index].innerBlocks, updateBlockAttributes); 49716 } 49717 } 49718 49719 /** 49720 * A hook to return a pasteStyles event function for handling pasting styles to blocks. 49721 * 49722 * @return {Function} A function to update the styles to the blocks. 49723 */ 49724 function usePasteStyles() { 49725 const registry = (0,external_wp_data_namespaceObject.useRegistry)(); 49726 const { 49727 updateBlockAttributes 49728 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 49729 const { 49730 createSuccessNotice, 49731 createWarningNotice, 49732 createErrorNotice 49733 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_notices_namespaceObject.store); 49734 return (0,external_wp_element_namespaceObject.useCallback)(async targetBlocks => { 49735 let html = ''; 49736 try { 49737 // `http:` sites won't have the clipboard property on navigator. 49738 // (with the exception of localhost.) 49739 if (!window.navigator.clipboard) { 49740 createErrorNotice((0,external_wp_i18n_namespaceObject.__)('Unable to paste styles. This feature is only available on secure (https) sites in supporting browsers.'), { 49741 type: 'snackbar' 49742 }); 49743 return; 49744 } 49745 html = await window.navigator.clipboard.readText(); 49746 } catch (error) { 49747 // Possibly the permission is denied. 49748 createErrorNotice((0,external_wp_i18n_namespaceObject.__)('Unable to paste styles. Please allow browser clipboard permissions before continuing.'), { 49749 type: 'snackbar' 49750 }); 49751 return; 49752 } 49753 49754 // Abort if the copied text is empty or doesn't look like serialized blocks. 49755 if (!html || !hasSerializedBlocks(html)) { 49756 createWarningNotice((0,external_wp_i18n_namespaceObject.__)("Unable to paste styles. Block styles couldn't be found within the copied content."), { 49757 type: 'snackbar' 49758 }); 49759 return; 49760 } 49761 const copiedBlocks = (0,external_wp_blocks_namespaceObject.parse)(html); 49762 if (copiedBlocks.length === 1) { 49763 // Apply styles of the block to all the target blocks. 49764 registry.batch(() => { 49765 recursivelyUpdateBlockAttributes(targetBlocks, targetBlocks.map(() => copiedBlocks[0]), updateBlockAttributes); 49766 }); 49767 } else { 49768 registry.batch(() => { 49769 recursivelyUpdateBlockAttributes(targetBlocks, copiedBlocks, updateBlockAttributes); 49770 }); 49771 } 49772 if (targetBlocks.length === 1) { 49773 const title = (0,external_wp_blocks_namespaceObject.getBlockType)(targetBlocks[0].name)?.title; 49774 createSuccessNotice((0,external_wp_i18n_namespaceObject.sprintf)( 49775 // Translators: Name of the block being pasted, e.g. "Paragraph". 49776 (0,external_wp_i18n_namespaceObject.__)('Pasted styles to %s.'), title), { 49777 type: 'snackbar' 49778 }); 49779 } else { 49780 createSuccessNotice((0,external_wp_i18n_namespaceObject.sprintf)( 49781 // Translators: The number of the blocks. 49782 (0,external_wp_i18n_namespaceObject.__)('Pasted styles to %d blocks.'), targetBlocks.length), { 49783 type: 'snackbar' 49784 }); 49785 } 49786 }, [registry.batch, updateBlockAttributes, createSuccessNotice, createWarningNotice, createErrorNotice]); 49787 } 49788 49789 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-actions/index.js 49790 /** 49791 * WordPress dependencies 49792 */ 49793 49794 49795 49796 /** 49797 * Internal dependencies 49798 */ 49799 49800 49801 49802 function BlockActions({ 49803 clientIds, 49804 children, 49805 __experimentalUpdateSelection: updateSelection 49806 }) { 49807 const { 49808 getDefaultBlockName, 49809 getGroupingBlockName 49810 } = (0,external_wp_data_namespaceObject.useSelect)(external_wp_blocks_namespaceObject.store); 49811 const selected = (0,external_wp_data_namespaceObject.useSelect)(select => { 49812 const { 49813 canInsertBlockType, 49814 getBlockRootClientId, 49815 getBlocksByClientId, 49816 getDirectInsertBlock, 49817 canMoveBlocks, 49818 canRemoveBlocks 49819 } = select(store); 49820 const blocks = getBlocksByClientId(clientIds); 49821 const rootClientId = getBlockRootClientId(clientIds[0]); 49822 const canInsertDefaultBlock = canInsertBlockType(getDefaultBlockName(), rootClientId); 49823 const directInsertBlock = rootClientId ? getDirectInsertBlock(rootClientId) : null; 49824 return { 49825 canMove: canMoveBlocks(clientIds, rootClientId), 49826 canRemove: canRemoveBlocks(clientIds, rootClientId), 49827 canInsertBlock: canInsertDefaultBlock || !!directInsertBlock, 49828 canCopyStyles: blocks.every(block => { 49829 return !!block && ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(block.name, 'color') || (0,external_wp_blocks_namespaceObject.hasBlockSupport)(block.name, 'typography')); 49830 }), 49831 canDuplicate: blocks.every(block => { 49832 return !!block && (0,external_wp_blocks_namespaceObject.hasBlockSupport)(block.name, 'multiple', true) && canInsertBlockType(block.name, rootClientId); 49833 }) 49834 }; 49835 }, [clientIds, getDefaultBlockName]); 49836 const { 49837 getBlocksByClientId, 49838 getBlocks 49839 } = (0,external_wp_data_namespaceObject.useSelect)(store); 49840 const { 49841 canMove, 49842 canRemove, 49843 canInsertBlock, 49844 canCopyStyles, 49845 canDuplicate 49846 } = selected; 49847 const { 49848 removeBlocks, 49849 replaceBlocks, 49850 duplicateBlocks, 49851 insertAfterBlock, 49852 insertBeforeBlock, 49853 flashBlock, 49854 setBlockMovingClientId, 49855 setNavigationMode, 49856 selectBlock 49857 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 49858 const notifyCopy = useNotifyCopy(); 49859 const pasteStyles = usePasteStyles(); 49860 return children({ 49861 canCopyStyles, 49862 canDuplicate, 49863 canInsertBlock, 49864 canMove, 49865 canRemove, 49866 onDuplicate() { 49867 return duplicateBlocks(clientIds, updateSelection); 49868 }, 49869 onRemove() { 49870 return removeBlocks(clientIds, updateSelection); 49871 }, 49872 onInsertBefore() { 49873 const clientId = Array.isArray(clientIds) ? clientIds[0] : clientId; 49874 insertBeforeBlock(clientId); 49875 }, 49876 onInsertAfter() { 49877 const clientId = Array.isArray(clientIds) ? clientIds[clientIds.length - 1] : clientId; 49878 insertAfterBlock(clientId); 49879 }, 49880 onMoveTo() { 49881 setNavigationMode(true); 49882 selectBlock(clientIds[0]); 49883 setBlockMovingClientId(clientIds[0]); 49884 }, 49885 onGroup() { 49886 if (!clientIds.length) { 49887 return; 49888 } 49889 const groupingBlockName = getGroupingBlockName(); 49890 49891 // Activate the `transform` on `core/group` which does the conversion. 49892 const newBlocks = (0,external_wp_blocks_namespaceObject.switchToBlockType)(getBlocksByClientId(clientIds), groupingBlockName); 49893 if (!newBlocks) { 49894 return; 49895 } 49896 replaceBlocks(clientIds, newBlocks); 49897 }, 49898 onUngroup() { 49899 if (!clientIds.length) { 49900 return; 49901 } 49902 const innerBlocks = getBlocks(clientIds[0]); 49903 if (!innerBlocks.length) { 49904 return; 49905 } 49906 replaceBlocks(clientIds, innerBlocks); 49907 }, 49908 onCopy() { 49909 if (clientIds.length === 1) { 49910 flashBlock(clientIds[0]); 49911 } 49912 notifyCopy('copy', clientIds); 49913 }, 49914 async onPasteStyles() { 49915 await pasteStyles(getBlocksByClientId(clientIds)); 49916 } 49917 }); 49918 } 49919 49920 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-settings-menu/block-html-convert-button.js 49921 49922 /** 49923 * WordPress dependencies 49924 */ 49925 49926 49927 49928 49929 49930 /** 49931 * Internal dependencies 49932 */ 49933 49934 function BlockHTMLConvertButton({ 49935 clientId 49936 }) { 49937 const block = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getBlock(clientId), [clientId]); 49938 const { 49939 replaceBlocks 49940 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 49941 if (!block || block.name !== 'core/html') { 49942 return null; 49943 } 49944 return (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 49945 onClick: () => replaceBlocks(clientId, (0,external_wp_blocks_namespaceObject.rawHandler)({ 49946 HTML: (0,external_wp_blocks_namespaceObject.getBlockContent)(block) 49947 })) 49948 }, (0,external_wp_i18n_namespaceObject.__)('Convert to Blocks')); 49949 } 49950 /* harmony default export */ const block_html_convert_button = (BlockHTMLConvertButton); 49951 49952 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-settings-menu/block-settings-menu-first-item.js 49953 /** 49954 * WordPress dependencies 49955 */ 49956 49957 const { 49958 Fill: __unstableBlockSettingsMenuFirstItem, 49959 Slot: block_settings_menu_first_item_Slot 49960 } = (0,external_wp_components_namespaceObject.createSlotFill)('__unstableBlockSettingsMenuFirstItem'); 49961 __unstableBlockSettingsMenuFirstItem.Slot = block_settings_menu_first_item_Slot; 49962 /* harmony default export */ const block_settings_menu_first_item = (__unstableBlockSettingsMenuFirstItem); 49963 49964 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-settings-menu/block-settings-dropdown.js 49965 49966 /** 49967 * WordPress dependencies 49968 */ 49969 49970 49971 49972 49973 49974 49975 49976 49977 49978 /** 49979 * Internal dependencies 49980 */ 49981 49982 49983 49984 49985 49986 49987 49988 49989 const block_settings_dropdown_POPOVER_PROPS = { 49990 className: 'block-editor-block-settings-menu__popover', 49991 placement: 'bottom-start' 49992 }; 49993 function CopyMenuItem({ 49994 clientIds, 49995 onCopy, 49996 label 49997 }) { 49998 const { 49999 getBlocksByClientId 50000 } = (0,external_wp_data_namespaceObject.useSelect)(store); 50001 const ref = (0,external_wp_compose_namespaceObject.useCopyToClipboard)(() => (0,external_wp_blocks_namespaceObject.serialize)(getBlocksByClientId(clientIds)), onCopy); 50002 const copyMenuItemLabel = label ? label : (0,external_wp_i18n_namespaceObject.__)('Copy'); 50003 return (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 50004 ref: ref 50005 }, copyMenuItemLabel); 50006 } 50007 function ParentSelectorMenuItem({ 50008 parentClientId, 50009 parentBlockType 50010 }) { 50011 const isSmallViewport = (0,external_wp_compose_namespaceObject.useViewportMatch)('medium', '<'); 50012 const { 50013 selectBlock 50014 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 50015 50016 // Allows highlighting the parent block outline when focusing or hovering 50017 // the parent block selector within the child. 50018 const menuItemRef = (0,external_wp_element_namespaceObject.useRef)(); 50019 const gesturesProps = useShowHoveredOrFocusedGestures({ 50020 ref: menuItemRef, 50021 highlightParent: true 50022 }); 50023 if (!isSmallViewport) { 50024 return null; 50025 } 50026 return (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 50027 ...gesturesProps, 50028 ref: menuItemRef, 50029 icon: (0,external_React_.createElement)(block_icon, { 50030 icon: parentBlockType.icon 50031 }), 50032 onClick: () => selectBlock(parentClientId) 50033 }, (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: Name of the block's parent. */ 50034 (0,external_wp_i18n_namespaceObject.__)('Select parent block (%s)'), parentBlockType.title)); 50035 } 50036 function BlockSettingsDropdown({ 50037 block, 50038 clientIds, 50039 __experimentalSelectBlock, 50040 children, 50041 __unstableDisplayLocation, 50042 ...props 50043 }) { 50044 // Get the client id of the current block for this menu, if one is set. 50045 const currentClientId = block?.clientId; 50046 const blockClientIds = Array.isArray(clientIds) ? clientIds : [clientIds]; 50047 const count = blockClientIds.length; 50048 const firstBlockClientId = blockClientIds[0]; 50049 const { 50050 firstParentClientId, 50051 onlyBlock, 50052 parentBlockType, 50053 previousBlockClientId, 50054 selectedBlockClientIds 50055 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 50056 const { 50057 getBlockCount, 50058 getBlockName, 50059 getBlockRootClientId, 50060 getPreviousBlockClientId, 50061 getSelectedBlockClientIds, 50062 getBlockAttributes 50063 } = select(store); 50064 const { 50065 getActiveBlockVariation 50066 } = select(external_wp_blocks_namespaceObject.store); 50067 const _firstParentClientId = getBlockRootClientId(firstBlockClientId); 50068 const parentBlockName = _firstParentClientId && getBlockName(_firstParentClientId); 50069 return { 50070 firstParentClientId: _firstParentClientId, 50071 onlyBlock: 1 === getBlockCount(_firstParentClientId), 50072 parentBlockType: _firstParentClientId && (getActiveBlockVariation(parentBlockName, getBlockAttributes(_firstParentClientId)) || (0,external_wp_blocks_namespaceObject.getBlockType)(parentBlockName)), 50073 previousBlockClientId: getPreviousBlockClientId(firstBlockClientId), 50074 selectedBlockClientIds: getSelectedBlockClientIds() 50075 }; 50076 }, [firstBlockClientId]); 50077 const { 50078 getBlockOrder, 50079 getSelectedBlockClientIds 50080 } = (0,external_wp_data_namespaceObject.useSelect)(store); 50081 const openedBlockSettingsMenu = (0,external_wp_data_namespaceObject.useSelect)(select => unlock(select(store)).getOpenedBlockSettingsMenu(), []); 50082 const { 50083 setOpenedBlockSettingsMenu 50084 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store)); 50085 const shortcuts = (0,external_wp_data_namespaceObject.useSelect)(select => { 50086 const { 50087 getShortcutRepresentation 50088 } = select(external_wp_keyboardShortcuts_namespaceObject.store); 50089 return { 50090 duplicate: getShortcutRepresentation('core/block-editor/duplicate'), 50091 remove: getShortcutRepresentation('core/block-editor/remove'), 50092 insertAfter: getShortcutRepresentation('core/block-editor/insert-after'), 50093 insertBefore: getShortcutRepresentation('core/block-editor/insert-before') 50094 }; 50095 }, []); 50096 const isMatch = (0,external_wp_keyboardShortcuts_namespaceObject.__unstableUseShortcutEventMatch)(); 50097 const hasSelectedBlocks = selectedBlockClientIds.length > 0; 50098 const updateSelectionAfterDuplicate = (0,external_wp_element_namespaceObject.useCallback)(async clientIdsPromise => { 50099 if (__experimentalSelectBlock) { 50100 const ids = await clientIdsPromise; 50101 if (ids && ids[0]) { 50102 __experimentalSelectBlock(ids[0], false); 50103 } 50104 } 50105 }, [__experimentalSelectBlock]); 50106 const updateSelectionAfterRemove = (0,external_wp_element_namespaceObject.useCallback)(() => { 50107 if (__experimentalSelectBlock) { 50108 let blockToFocus = previousBlockClientId || firstParentClientId; 50109 50110 // Focus the first block if there's no previous block nor parent block. 50111 if (!blockToFocus) { 50112 blockToFocus = getBlockOrder()[0]; 50113 } 50114 50115 // Only update the selection if the original selection is removed. 50116 const shouldUpdateSelection = hasSelectedBlocks && getSelectedBlockClientIds().length === 0; 50117 __experimentalSelectBlock(blockToFocus, shouldUpdateSelection); 50118 } 50119 }, [__experimentalSelectBlock, previousBlockClientId, firstParentClientId, getBlockOrder, hasSelectedBlocks, getSelectedBlockClientIds]); 50120 50121 // This can occur when the selected block (the parent) 50122 // displays child blocks within a List View. 50123 const parentBlockIsSelected = selectedBlockClientIds?.includes(firstParentClientId); 50124 50125 // When a currentClientId is in use, treat the menu as a controlled component. 50126 // This ensures that only one block settings menu is open at a time. 50127 // This is a temporary solution to work around an issue with `onFocusOutside` 50128 // where it does not allow a dropdown to be closed if focus was never within 50129 // the dropdown to begin with. Examples include a user either CMD+Clicking or 50130 // right clicking into an inactive window. 50131 // See: https://github.com/WordPress/gutenberg/pull/54083 50132 const open = !currentClientId ? undefined : openedBlockSettingsMenu === currentClientId || false; 50133 const onToggle = (0,external_wp_element_namespaceObject.useCallback)(localOpen => { 50134 if (localOpen && openedBlockSettingsMenu !== currentClientId) { 50135 setOpenedBlockSettingsMenu(currentClientId); 50136 } else if (!localOpen && openedBlockSettingsMenu && openedBlockSettingsMenu === currentClientId) { 50137 setOpenedBlockSettingsMenu(undefined); 50138 } 50139 }, [currentClientId, openedBlockSettingsMenu, setOpenedBlockSettingsMenu]); 50140 return (0,external_React_.createElement)(BlockActions, { 50141 clientIds: clientIds, 50142 __experimentalUpdateSelection: !__experimentalSelectBlock 50143 }, ({ 50144 canCopyStyles, 50145 canDuplicate, 50146 canInsertBlock, 50147 canMove, 50148 canRemove, 50149 onDuplicate, 50150 onInsertAfter, 50151 onInsertBefore, 50152 onRemove, 50153 onCopy, 50154 onPasteStyles, 50155 onMoveTo 50156 }) => (0,external_React_.createElement)(external_wp_components_namespaceObject.DropdownMenu, { 50157 icon: more_vertical, 50158 label: (0,external_wp_i18n_namespaceObject.__)('Options'), 50159 className: "block-editor-block-settings-menu", 50160 popoverProps: block_settings_dropdown_POPOVER_PROPS, 50161 open: open, 50162 onToggle: onToggle, 50163 noIcons: true, 50164 menuProps: { 50165 /** 50166 * @param {KeyboardEvent} event 50167 */ 50168 onKeyDown(event) { 50169 if (event.defaultPrevented) return; 50170 if (isMatch('core/block-editor/remove', event) && canRemove) { 50171 event.preventDefault(); 50172 updateSelectionAfterRemove(onRemove()); 50173 } else if (isMatch('core/block-editor/duplicate', event) && canDuplicate) { 50174 event.preventDefault(); 50175 updateSelectionAfterDuplicate(onDuplicate()); 50176 } else if (isMatch('core/block-editor/insert-after', event) && canInsertBlock) { 50177 event.preventDefault(); 50178 setOpenedBlockSettingsMenu(undefined); 50179 onInsertAfter(); 50180 } else if (isMatch('core/block-editor/insert-before', event) && canInsertBlock) { 50181 event.preventDefault(); 50182 setOpenedBlockSettingsMenu(undefined); 50183 onInsertBefore(); 50184 } 50185 } 50186 }, 50187 ...props 50188 }, ({ 50189 onClose 50190 }) => (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuGroup, null, (0,external_React_.createElement)(block_settings_menu_first_item.Slot, { 50191 fillProps: { 50192 onClose 50193 } 50194 }), !parentBlockIsSelected && !!firstParentClientId && (0,external_React_.createElement)(ParentSelectorMenuItem, { 50195 parentClientId: firstParentClientId, 50196 parentBlockType: parentBlockType 50197 }), count === 1 && (0,external_React_.createElement)(block_html_convert_button, { 50198 clientId: firstBlockClientId 50199 }), (0,external_React_.createElement)(CopyMenuItem, { 50200 clientIds: clientIds, 50201 onCopy: onCopy 50202 }), canDuplicate && (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 50203 onClick: (0,external_wp_compose_namespaceObject.pipe)(onClose, onDuplicate, updateSelectionAfterDuplicate), 50204 shortcut: shortcuts.duplicate 50205 }, (0,external_wp_i18n_namespaceObject.__)('Duplicate')), canInsertBlock && (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 50206 onClick: (0,external_wp_compose_namespaceObject.pipe)(onClose, onInsertBefore), 50207 shortcut: shortcuts.insertBefore 50208 }, (0,external_wp_i18n_namespaceObject.__)('Add before')), (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 50209 onClick: (0,external_wp_compose_namespaceObject.pipe)(onClose, onInsertAfter), 50210 shortcut: shortcuts.insertAfter 50211 }, (0,external_wp_i18n_namespaceObject.__)('Add after')))), canCopyStyles && (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuGroup, null, (0,external_React_.createElement)(CopyMenuItem, { 50212 clientIds: clientIds, 50213 onCopy: onCopy, 50214 label: (0,external_wp_i18n_namespaceObject.__)('Copy styles') 50215 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 50216 onClick: onPasteStyles 50217 }, (0,external_wp_i18n_namespaceObject.__)('Paste styles'))), (0,external_React_.createElement)(block_settings_menu_controls.Slot, { 50218 fillProps: { 50219 onClose, 50220 canMove, 50221 onMoveTo, 50222 onlyBlock, 50223 count, 50224 firstBlockClientId 50225 }, 50226 clientIds: clientIds, 50227 __unstableDisplayLocation: __unstableDisplayLocation 50228 }), typeof children === 'function' ? children({ 50229 onClose 50230 }) : external_wp_element_namespaceObject.Children.map(child => (0,external_wp_element_namespaceObject.cloneElement)(child, { 50231 onClose 50232 })), canRemove && (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuGroup, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 50233 onClick: (0,external_wp_compose_namespaceObject.pipe)(onClose, onRemove, updateSelectionAfterRemove), 50234 shortcut: shortcuts.remove 50235 }, (0,external_wp_i18n_namespaceObject.__)('Delete')))))); 50236 } 50237 /* harmony default export */ const block_settings_dropdown = (BlockSettingsDropdown); 50238 50239 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-settings-menu/index.js 50240 50241 /** 50242 * WordPress dependencies 50243 */ 50244 50245 50246 /** 50247 * Internal dependencies 50248 */ 50249 50250 function BlockSettingsMenu({ 50251 clientIds, 50252 ...props 50253 }) { 50254 return (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarGroup, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarItem, null, toggleProps => (0,external_React_.createElement)(block_settings_dropdown, { 50255 clientIds: clientIds, 50256 toggleProps: toggleProps, 50257 ...props 50258 }))); 50259 } 50260 /* harmony default export */ const block_settings_menu = (BlockSettingsMenu); 50261 50262 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-lock/toolbar.js 50263 50264 /** 50265 * WordPress dependencies 50266 */ 50267 50268 50269 50270 50271 50272 /** 50273 * Internal dependencies 50274 */ 50275 50276 50277 function BlockLockToolbar({ 50278 clientId 50279 }) { 50280 const { 50281 canLock, 50282 isLocked 50283 } = useBlockLock(clientId); 50284 const [isModalOpen, toggleModal] = (0,external_wp_element_namespaceObject.useReducer)(isActive => !isActive, false); 50285 const hasLockButtonShown = (0,external_wp_element_namespaceObject.useRef)(false); 50286 50287 // If the block lock button has been shown, we don't want to remove it 50288 // from the toolbar until the toolbar is rendered again without it. 50289 // Removing it beforehand can cause focus loss issues, such as when 50290 // unlocking the block from the modal. It needs to return focus from 50291 // whence it came, and to do that, we need to leave the button in the toolbar. 50292 (0,external_wp_element_namespaceObject.useEffect)(() => { 50293 if (isLocked) { 50294 hasLockButtonShown.current = true; 50295 } 50296 }, [isLocked]); 50297 if (!isLocked && !hasLockButtonShown.current) { 50298 return null; 50299 } 50300 let label = isLocked ? (0,external_wp_i18n_namespaceObject.__)('Unlock') : (0,external_wp_i18n_namespaceObject.__)('Lock'); 50301 if (!canLock && isLocked) { 50302 label = (0,external_wp_i18n_namespaceObject.__)('Locked'); 50303 } 50304 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarGroup, { 50305 className: "block-editor-block-lock-toolbar" 50306 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarButton, { 50307 accessibleWhenDisabled: true, 50308 disabled: !canLock, 50309 icon: isLocked ? library_lock : library_unlock, 50310 label: label, 50311 onClick: toggleModal, 50312 "aria-expanded": isModalOpen, 50313 "aria-haspopup": "dialog" 50314 })), isModalOpen && (0,external_React_.createElement)(BlockLockModal, { 50315 clientId: clientId, 50316 onClose: toggleModal 50317 })); 50318 } 50319 50320 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/group.js 50321 50322 /** 50323 * WordPress dependencies 50324 */ 50325 50326 const group_group = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 50327 viewBox: "0 0 24 24", 50328 xmlns: "http://www.w3.org/2000/svg" 50329 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 50330 d: "M18 4h-7c-1.1 0-2 .9-2 2v3H6c-1.1 0-2 .9-2 2v7c0 1.1.9 2 2 2h7c1.1 0 2-.9 2-2v-3h3c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-4.5 14c0 .3-.2.5-.5.5H6c-.3 0-.5-.2-.5-.5v-7c0-.3.2-.5.5-.5h3V13c0 1.1.9 2 2 2h2.5v3zm0-4.5H11c-.3 0-.5-.2-.5-.5v-2.5H13c.3 0 .5.2.5.5v2.5zm5-.5c0 .3-.2.5-.5.5h-3V11c0-1.1-.9-2-2-2h-2.5V6c0-.3.2-.5.5-.5h7c.3 0 .5.2.5.5v7z" 50331 })); 50332 /* harmony default export */ const library_group = (group_group); 50333 50334 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/row.js 50335 50336 /** 50337 * WordPress dependencies 50338 */ 50339 50340 const row = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 50341 xmlns: "http://www.w3.org/2000/svg", 50342 viewBox: "0 0 24 24" 50343 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 50344 d: "M4 6.5h5a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H4V16h5a.5.5 0 0 0 .5-.5v-7A.5.5 0 0 0 9 8H4V6.5Zm16 0h-5a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h5V16h-5a.5.5 0 0 1-.5-.5v-7A.5.5 0 0 1 15 8h5V6.5Z" 50345 })); 50346 /* harmony default export */ const library_row = (row); 50347 50348 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/stack.js 50349 50350 /** 50351 * WordPress dependencies 50352 */ 50353 50354 const stack = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 50355 xmlns: "http://www.w3.org/2000/svg", 50356 viewBox: "0 0 24 24" 50357 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 50358 d: "M17.5 4v5a2 2 0 0 1-2 2h-7a2 2 0 0 1-2-2V4H8v5a.5.5 0 0 0 .5.5h7A.5.5 0 0 0 16 9V4h1.5Zm0 16v-5a2 2 0 0 0-2-2h-7a2 2 0 0 0-2 2v5H8v-5a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 .5.5v5h1.5Z" 50359 })); 50360 /* harmony default export */ const library_stack = (stack); 50361 50362 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/convert-to-group-buttons/toolbar.js 50363 50364 /** 50365 * WordPress dependencies 50366 */ 50367 50368 50369 50370 50371 50372 50373 /** 50374 * Internal dependencies 50375 */ 50376 50377 50378 const layouts = { 50379 group: { 50380 type: 'constrained' 50381 }, 50382 row: { 50383 type: 'flex', 50384 flexWrap: 'nowrap' 50385 }, 50386 stack: { 50387 type: 'flex', 50388 orientation: 'vertical' 50389 } 50390 }; 50391 function BlockGroupToolbar() { 50392 const { 50393 blocksSelection, 50394 clientIds, 50395 groupingBlockName, 50396 isGroupable 50397 } = useConvertToGroupButtonProps(); 50398 const { 50399 replaceBlocks 50400 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 50401 const { 50402 canRemove, 50403 variations 50404 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 50405 const { 50406 canRemoveBlocks 50407 } = select(store); 50408 const { 50409 getBlockVariations 50410 } = select(external_wp_blocks_namespaceObject.store); 50411 return { 50412 canRemove: canRemoveBlocks(clientIds), 50413 variations: getBlockVariations(groupingBlockName, 'transform') 50414 }; 50415 }, [clientIds, groupingBlockName]); 50416 const onConvertToGroup = layout => { 50417 const newBlocks = (0,external_wp_blocks_namespaceObject.switchToBlockType)(blocksSelection, groupingBlockName); 50418 if (typeof layout !== 'string') { 50419 layout = 'group'; 50420 } 50421 if (newBlocks && newBlocks.length > 0) { 50422 // Because the block is not in the store yet we can't use 50423 // updateBlockAttributes so need to manually update attributes. 50424 newBlocks[0].attributes.layout = layouts[layout]; 50425 replaceBlocks(clientIds, newBlocks); 50426 } 50427 }; 50428 const onConvertToRow = () => onConvertToGroup('row'); 50429 const onConvertToStack = () => onConvertToGroup('stack'); 50430 50431 // Don't render the button if the current selection cannot be grouped. 50432 // A good example is selecting multiple button blocks within a Buttons block: 50433 // The group block is not a valid child of Buttons, so we should not show the button. 50434 // Any blocks that are locked against removal also cannot be grouped. 50435 if (!isGroupable || !canRemove) { 50436 return null; 50437 } 50438 const canInsertRow = !!variations.find(({ 50439 name 50440 }) => name === 'group-row'); 50441 const canInsertStack = !!variations.find(({ 50442 name 50443 }) => name === 'group-stack'); 50444 return (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarGroup, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarButton, { 50445 icon: library_group, 50446 label: (0,external_wp_i18n_namespaceObject._x)('Group', 'verb'), 50447 onClick: onConvertToGroup 50448 }), canInsertRow && (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarButton, { 50449 icon: library_row, 50450 label: (0,external_wp_i18n_namespaceObject._x)('Row', 'single horizontal line'), 50451 onClick: onConvertToRow 50452 }), canInsertStack && (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarButton, { 50453 icon: library_stack, 50454 label: (0,external_wp_i18n_namespaceObject._x)('Stack', 'verb'), 50455 onClick: onConvertToStack 50456 })); 50457 } 50458 /* harmony default export */ const toolbar = (BlockGroupToolbar); 50459 50460 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-edit-visually-button/index.js 50461 50462 /** 50463 * WordPress dependencies 50464 */ 50465 50466 50467 50468 50469 /** 50470 * Internal dependencies 50471 */ 50472 50473 function BlockEditVisuallyButton({ 50474 clientIds 50475 }) { 50476 // Edit visually only works for single block selection. 50477 const clientId = clientIds.length === 1 ? clientIds[0] : undefined; 50478 const canEditVisually = (0,external_wp_data_namespaceObject.useSelect)(select => !!clientId && select(store).getBlockMode(clientId) === 'html', [clientId]); 50479 const { 50480 toggleBlockMode 50481 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 50482 if (!canEditVisually) { 50483 return null; 50484 } 50485 return (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarGroup, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarButton, { 50486 onClick: () => { 50487 toggleBlockMode(clientId); 50488 } 50489 }, (0,external_wp_i18n_namespaceObject.__)('Edit visually'))); 50490 } 50491 50492 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-toolbar/block-name-context.js 50493 /** 50494 * WordPress dependencies 50495 */ 50496 50497 const __unstableBlockNameContext = (0,external_wp_element_namespaceObject.createContext)(''); 50498 /* harmony default export */ const block_name_context = (__unstableBlockNameContext); 50499 50500 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/navigable-toolbar/index.js 50501 50502 /** 50503 * WordPress dependencies 50504 */ 50505 50506 50507 50508 50509 50510 50511 50512 50513 /** 50514 * Internal dependencies 50515 */ 50516 50517 50518 function hasOnlyToolbarItem(elements) { 50519 const dataProp = 'toolbarItem'; 50520 return !elements.some(element => !(dataProp in element.dataset)); 50521 } 50522 function getAllFocusableToolbarItemsIn(container) { 50523 return Array.from(container.querySelectorAll('[data-toolbar-item]:not([disabled])')); 50524 } 50525 function hasFocusWithin(container) { 50526 return container.contains(container.ownerDocument.activeElement); 50527 } 50528 function focusFirstTabbableIn(container) { 50529 const [firstTabbable] = external_wp_dom_namespaceObject.focus.tabbable.find(container); 50530 if (firstTabbable) { 50531 firstTabbable.focus({ 50532 // When focusing newly mounted toolbars, 50533 // the position of the popover is often not right on the first render 50534 // This prevents the layout shifts when focusing the dialogs. 50535 preventScroll: true 50536 }); 50537 } 50538 } 50539 function useIsAccessibleToolbar(toolbarRef) { 50540 /* 50541 * By default, we'll assume the starting accessible state of the Toolbar 50542 * is true, as it seems to be the most common case. 50543 * 50544 * Transitioning from an (initial) false to true state causes the 50545 * <Toolbar /> component to mount twice, which is causing undesired 50546 * side-effects. These side-effects appear to only affect certain 50547 * E2E tests. 50548 * 50549 * This was initial discovered in this pull-request: 50550 * https://github.com/WordPress/gutenberg/pull/23425 50551 */ 50552 const initialAccessibleToolbarState = true; 50553 50554 // By default, it's gonna render NavigableMenu. If all the tabbable elements 50555 // inside the toolbar are ToolbarItem components (or derived components like 50556 // ToolbarButton), then we can wrap them with the accessible Toolbar 50557 // component. 50558 const [isAccessibleToolbar, setIsAccessibleToolbar] = (0,external_wp_element_namespaceObject.useState)(initialAccessibleToolbarState); 50559 const determineIsAccessibleToolbar = (0,external_wp_element_namespaceObject.useCallback)(() => { 50560 const tabbables = external_wp_dom_namespaceObject.focus.tabbable.find(toolbarRef.current); 50561 const onlyToolbarItem = hasOnlyToolbarItem(tabbables); 50562 if (!onlyToolbarItem) { 50563 external_wp_deprecated_default()('Using custom components as toolbar controls', { 50564 since: '5.6', 50565 alternative: 'ToolbarItem, ToolbarButton or ToolbarDropdownMenu components', 50566 link: 'https://developer.wordpress.org/block-editor/components/toolbar-button/#inside-blockcontrols' 50567 }); 50568 } 50569 setIsAccessibleToolbar(onlyToolbarItem); 50570 }, [toolbarRef]); 50571 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 50572 // Toolbar buttons may be rendered asynchronously, so we use 50573 // MutationObserver to check if the toolbar subtree has been modified. 50574 const observer = new window.MutationObserver(determineIsAccessibleToolbar); 50575 observer.observe(toolbarRef.current, { 50576 childList: true, 50577 subtree: true 50578 }); 50579 return () => observer.disconnect(); 50580 }, [determineIsAccessibleToolbar, isAccessibleToolbar, toolbarRef]); 50581 return isAccessibleToolbar; 50582 } 50583 function useToolbarFocus({ 50584 toolbarRef, 50585 focusOnMount, 50586 isAccessibleToolbar, 50587 defaultIndex, 50588 onIndexChange, 50589 shouldUseKeyboardFocusShortcut, 50590 focusEditorOnEscape 50591 }) { 50592 // Make sure we don't use modified versions of this prop. 50593 const [initialFocusOnMount] = (0,external_wp_element_namespaceObject.useState)(focusOnMount); 50594 const [initialIndex] = (0,external_wp_element_namespaceObject.useState)(defaultIndex); 50595 const focusToolbar = (0,external_wp_element_namespaceObject.useCallback)(() => { 50596 focusFirstTabbableIn(toolbarRef.current); 50597 }, [toolbarRef]); 50598 const focusToolbarViaShortcut = () => { 50599 if (shouldUseKeyboardFocusShortcut) { 50600 focusToolbar(); 50601 } 50602 }; 50603 50604 // Focus on toolbar when pressing alt+F10 when the toolbar is visible. 50605 (0,external_wp_keyboardShortcuts_namespaceObject.useShortcut)('core/block-editor/focus-toolbar', focusToolbarViaShortcut); 50606 (0,external_wp_element_namespaceObject.useEffect)(() => { 50607 if (initialFocusOnMount) { 50608 focusToolbar(); 50609 } 50610 }, [isAccessibleToolbar, initialFocusOnMount, focusToolbar]); 50611 (0,external_wp_element_namespaceObject.useEffect)(() => { 50612 // Store ref so we have access on useEffect cleanup: https://legacy.reactjs.org/blog/2020/08/10/react-v17-rc.html#effect-cleanup-timing 50613 const navigableToolbarRef = toolbarRef.current; 50614 // If initialIndex is passed, we focus on that toolbar item when the 50615 // toolbar gets mounted and initial focus is not forced. 50616 // We have to wait for the next browser paint because block controls aren't 50617 // rendered right away when the toolbar gets mounted. 50618 let raf = 0; 50619 50620 // If the toolbar already had focus before the render, we don't want to move it. 50621 // https://github.com/WordPress/gutenberg/issues/58511 50622 if (!initialFocusOnMount && !hasFocusWithin(navigableToolbarRef)) { 50623 raf = window.requestAnimationFrame(() => { 50624 const items = getAllFocusableToolbarItemsIn(navigableToolbarRef); 50625 const index = initialIndex || 0; 50626 if (items[index] && hasFocusWithin(navigableToolbarRef)) { 50627 items[index].focus({ 50628 // When focusing newly mounted toolbars, 50629 // the position of the popover is often not right on the first render 50630 // This prevents the layout shifts when focusing the dialogs. 50631 preventScroll: true 50632 }); 50633 } 50634 }); 50635 } 50636 return () => { 50637 window.cancelAnimationFrame(raf); 50638 if (!onIndexChange || !navigableToolbarRef) return; 50639 // When the toolbar element is unmounted and onIndexChange is passed, we 50640 // pass the focused toolbar item index so it can be hydrated later. 50641 const items = getAllFocusableToolbarItemsIn(navigableToolbarRef); 50642 const index = items.findIndex(item => item.tabIndex === 0); 50643 onIndexChange(index); 50644 }; 50645 }, [initialIndex, initialFocusOnMount, onIndexChange, toolbarRef]); 50646 const { 50647 getLastFocus 50648 } = unlock((0,external_wp_data_namespaceObject.useSelect)(store)); 50649 /** 50650 * Handles returning focus to the block editor canvas when pressing escape. 50651 */ 50652 (0,external_wp_element_namespaceObject.useEffect)(() => { 50653 const navigableToolbarRef = toolbarRef.current; 50654 if (focusEditorOnEscape) { 50655 const handleKeyDown = event => { 50656 const lastFocus = getLastFocus(); 50657 if (event.keyCode === external_wp_keycodes_namespaceObject.ESCAPE && lastFocus?.current) { 50658 // Focus the last focused element when pressing escape. 50659 event.preventDefault(); 50660 lastFocus.current.focus(); 50661 } 50662 }; 50663 navigableToolbarRef.addEventListener('keydown', handleKeyDown); 50664 return () => { 50665 navigableToolbarRef.removeEventListener('keydown', handleKeyDown); 50666 }; 50667 } 50668 }, [focusEditorOnEscape, getLastFocus, toolbarRef]); 50669 } 50670 function NavigableToolbar({ 50671 children, 50672 focusOnMount, 50673 focusEditorOnEscape = false, 50674 shouldUseKeyboardFocusShortcut = true, 50675 __experimentalInitialIndex: initialIndex, 50676 __experimentalOnIndexChange: onIndexChange, 50677 ...props 50678 }) { 50679 const toolbarRef = (0,external_wp_element_namespaceObject.useRef)(); 50680 const isAccessibleToolbar = useIsAccessibleToolbar(toolbarRef); 50681 useToolbarFocus({ 50682 toolbarRef, 50683 focusOnMount, 50684 defaultIndex: initialIndex, 50685 onIndexChange, 50686 isAccessibleToolbar, 50687 shouldUseKeyboardFocusShortcut, 50688 focusEditorOnEscape 50689 }); 50690 if (isAccessibleToolbar) { 50691 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Toolbar, { 50692 label: props['aria-label'], 50693 ref: toolbarRef, 50694 ...props 50695 }, children); 50696 } 50697 return (0,external_React_.createElement)(external_wp_components_namespaceObject.NavigableMenu, { 50698 orientation: "horizontal", 50699 role: "toolbar", 50700 ref: toolbarRef, 50701 ...props 50702 }, children); 50703 } 50704 50705 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-controls/use-has-block-controls.js 50706 /** 50707 * WordPress dependencies 50708 */ 50709 50710 50711 50712 /** 50713 * Internal dependencies 50714 */ 50715 50716 function useHasAnyBlockControls() { 50717 let hasAnyBlockControls = false; 50718 for (const group in block_controls_groups) { 50719 // It is safe to violate the rules of hooks here as the `groups` object 50720 // is static and will not change length between renders. Do not return 50721 // early as that will cause the hook to be called a different number of 50722 // times between renders. 50723 // eslint-disable-next-line react-hooks/rules-of-hooks 50724 if (useHasBlockControls(group)) { 50725 hasAnyBlockControls = true; 50726 } 50727 } 50728 return hasAnyBlockControls; 50729 } 50730 function useHasBlockControls(group = 'default') { 50731 const Slot = block_controls_groups[group]?.Slot; 50732 const fills = (0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(Slot?.__unstableName); 50733 if (!Slot) { 50734 true ? external_wp_warning_default()(`Unknown BlockControls group "$group}" provided.`) : 0; 50735 return null; 50736 } 50737 return !!fills?.length; 50738 } 50739 50740 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/connection.js 50741 50742 /** 50743 * WordPress dependencies 50744 */ 50745 50746 const connection = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 50747 width: "24", 50748 height: "24", 50749 viewBox: "0 0 24 24", 50750 xmlns: "http://www.w3.org/2000/svg", 50751 fillRule: "evenodd" 50752 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 50753 d: "M5 19L8 16L5 19Z" 50754 }), (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 50755 d: "M16 8L19 5L16 8Z" 50756 }), (0,external_React_.createElement)(external_wp_primitives_namespaceObject.G, null, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 50757 d: "M5 19L8 16" 50758 }), (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 50759 d: "M9.30003 17.3C9.523 17.5237 9.78794 17.7013 10.0797 17.8224C10.3714 17.9435 10.6842 18.0059 11 18.0059C11.3159 18.0059 11.6287 17.9435 11.9204 17.8224C12.2121 17.7013 12.4771 17.5237 12.7 17.3L15 15L9.00003 9L6.70003 11.3C6.47629 11.523 6.29876 11.7879 6.17763 12.0796C6.05649 12.3714 5.99414 12.6841 5.99414 13C5.99414 13.3159 6.05649 13.6286 6.17763 13.9204C6.29876 14.2121 6.47629 14.477 6.70003 14.7L9.30003 17.3Z" 50760 }), (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 50761 d: "M16 8L19 5" 50762 }), (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 50763 d: "M9 9.00003L15 15L17.3 12.7C17.5237 12.4771 17.7013 12.2121 17.8224 11.9204C17.9435 11.6287 18.0059 11.3159 18.0059 11C18.0059 10.6842 17.9435 10.3714 17.8224 10.0797C17.7013 9.78794 17.5237 9.523 17.3 9.30003L14.7 6.70003C14.477 6.47629 14.2121 6.29876 13.9204 6.17763C13.6286 6.05649 13.3159 5.99414 13 5.99414C12.6841 5.99414 12.3714 6.05649 12.0796 6.17763C11.7879 6.29876 11.523 6.47629 11.3 6.70003L9 9.00003Z" 50764 }))); 50765 /* harmony default export */ const library_connection = (connection); 50766 50767 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-bindings-toolbar-indicator/index.js 50768 50769 /** 50770 * WordPress dependencies 50771 */ 50772 50773 50774 50775 function BlockBindingsToolbarIndicator() { 50776 return (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarGroup, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarItem, { 50777 as: 'div', 50778 "aria-label": (0,external_wp_i18n_namespaceObject._x)('Connected', 'block toolbar button label'), 50779 className: "block-editor-block-bindings-toolbar-indicator" 50780 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Icon, { 50781 icon: library_connection, 50782 size: 24 50783 }))); 50784 } 50785 50786 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-toolbar/index.js 50787 50788 /** 50789 * External dependencies 50790 */ 50791 50792 50793 /** 50794 * WordPress dependencies 50795 */ 50796 50797 50798 50799 50800 50801 50802 50803 /** 50804 * Internal dependencies 50805 */ 50806 50807 50808 50809 50810 50811 50812 50813 50814 50815 50816 50817 50818 50819 50820 50821 50822 50823 /** 50824 * Renders the block toolbar. 50825 * 50826 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-toolbar/README.md 50827 * 50828 * @param {Object} props Components props. 50829 * @param {boolean} props.hideDragHandle Show or hide the Drag Handle for drag and drop functionality. 50830 * @param {boolean} props.focusOnMount Focus the toolbar when mounted. 50831 * @param {number} props.__experimentalInitialIndex The initial index of the toolbar item to focus. 50832 * @param {Function} props.__experimentalOnIndexChange Callback function to be called when the index of the focused toolbar item changes. 50833 * @param {string} props.variant Style variant of the toolbar, also passed to the Dropdowns rendered from Block Toolbar Buttons. 50834 */ 50835 function PrivateBlockToolbar({ 50836 hideDragHandle, 50837 focusOnMount, 50838 __experimentalInitialIndex, 50839 __experimentalOnIndexChange, 50840 variant = 'unstyled' 50841 }) { 50842 const { 50843 blockClientId, 50844 blockClientIds, 50845 isDefaultEditingMode, 50846 blockType, 50847 blockName, 50848 shouldShowVisualToolbar, 50849 showParentSelector, 50850 isUsingBindings 50851 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 50852 const { 50853 getBlockName, 50854 getBlockMode, 50855 getBlockParents, 50856 getSelectedBlockClientIds, 50857 isBlockValid, 50858 getBlockRootClientId, 50859 getBlockEditingMode, 50860 getBlockAttributes 50861 } = select(store); 50862 const selectedBlockClientIds = getSelectedBlockClientIds(); 50863 const selectedBlockClientId = selectedBlockClientIds[0]; 50864 const blockRootClientId = getBlockRootClientId(selectedBlockClientId); 50865 const parents = getBlockParents(selectedBlockClientId); 50866 const firstParentClientId = parents[parents.length - 1]; 50867 const parentBlockName = getBlockName(firstParentClientId); 50868 const parentBlockType = (0,external_wp_blocks_namespaceObject.getBlockType)(parentBlockName); 50869 const _isDefaultEditingMode = getBlockEditingMode(selectedBlockClientId) === 'default'; 50870 const _blockName = getBlockName(selectedBlockClientId); 50871 const isValid = selectedBlockClientIds.every(id => isBlockValid(id)); 50872 const isVisual = selectedBlockClientIds.every(id => getBlockMode(id) === 'visual'); 50873 const _isUsingBindings = !!getBlockAttributes(selectedBlockClientId)?.metadata?.bindings; 50874 return { 50875 blockClientId: selectedBlockClientId, 50876 blockClientIds: selectedBlockClientIds, 50877 isDefaultEditingMode: _isDefaultEditingMode, 50878 blockName: _blockName, 50879 blockType: selectedBlockClientId && (0,external_wp_blocks_namespaceObject.getBlockType)(_blockName), 50880 shouldShowVisualToolbar: isValid && isVisual, 50881 rootClientId: blockRootClientId, 50882 showParentSelector: parentBlockType && getBlockEditingMode(firstParentClientId) === 'default' && (0,external_wp_blocks_namespaceObject.hasBlockSupport)(parentBlockType, '__experimentalParentSelector', true) && selectedBlockClientIds.length === 1 && _isDefaultEditingMode, 50883 isUsingBindings: _isUsingBindings 50884 }; 50885 }, []); 50886 const toolbarWrapperRef = (0,external_wp_element_namespaceObject.useRef)(null); 50887 50888 // Handles highlighting the current block outline on hover or focus of the 50889 // block type toolbar area. 50890 const nodeRef = (0,external_wp_element_namespaceObject.useRef)(); 50891 const showHoveredOrFocusedGestures = useShowHoveredOrFocusedGestures({ 50892 ref: nodeRef 50893 }); 50894 const isLargeViewport = !(0,external_wp_compose_namespaceObject.useViewportMatch)('medium', '<'); 50895 const isToolbarEnabled = blockType && (0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, '__experimentalToolbar', true); 50896 const hasAnyBlockControls = useHasAnyBlockControls(); 50897 if (!isToolbarEnabled || !isDefaultEditingMode && !hasAnyBlockControls) { 50898 return null; 50899 } 50900 const isMultiToolbar = blockClientIds.length > 1; 50901 const isSynced = (0,external_wp_blocks_namespaceObject.isReusableBlock)(blockType) || (0,external_wp_blocks_namespaceObject.isTemplatePart)(blockType); 50902 50903 // Shifts the toolbar to make room for the parent block selector. 50904 const classes = classnames_default()('block-editor-block-contextual-toolbar', { 50905 'has-parent': showParentSelector 50906 }); 50907 const innerClasses = classnames_default()('block-editor-block-toolbar', { 50908 'is-synced': isSynced 50909 }); 50910 return (0,external_React_.createElement)(NavigableToolbar, { 50911 focusEditorOnEscape: true, 50912 className: classes 50913 /* translators: accessibility text for the block toolbar */, 50914 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Block tools') 50915 // The variant is applied as "toolbar" when undefined, which is the black border style of the dropdown from the toolbar popover. 50916 , 50917 variant: variant === 'toolbar' ? undefined : variant, 50918 focusOnMount: focusOnMount, 50919 __experimentalInitialIndex: __experimentalInitialIndex, 50920 __experimentalOnIndexChange: __experimentalOnIndexChange 50921 // Resets the index whenever the active block changes so 50922 // this is not persisted. See https://github.com/WordPress/gutenberg/pull/25760#issuecomment-717906169 50923 , 50924 key: blockClientId 50925 }, (0,external_React_.createElement)("div", { 50926 ref: toolbarWrapperRef, 50927 className: innerClasses 50928 }, !isMultiToolbar && isLargeViewport && isDefaultEditingMode && (0,external_React_.createElement)(BlockParentSelector, null), isUsingBindings && canBindBlock(blockName) && (0,external_React_.createElement)(BlockBindingsToolbarIndicator, null), (shouldShowVisualToolbar || isMultiToolbar) && isDefaultEditingMode && (0,external_React_.createElement)("div", { 50929 ref: nodeRef, 50930 ...showHoveredOrFocusedGestures 50931 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarGroup, { 50932 className: "block-editor-block-toolbar__block-controls" 50933 }, (0,external_React_.createElement)(block_switcher, { 50934 clientIds: blockClientIds 50935 }), !isMultiToolbar && (0,external_React_.createElement)(BlockLockToolbar, { 50936 clientId: blockClientId 50937 }), (0,external_React_.createElement)(block_mover, { 50938 clientIds: blockClientIds, 50939 hideDragHandle: hideDragHandle 50940 }))), shouldShowVisualToolbar && isMultiToolbar && (0,external_React_.createElement)(toolbar, null), shouldShowVisualToolbar && (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(block_controls.Slot, { 50941 group: "parent", 50942 className: "block-editor-block-toolbar__slot" 50943 }), (0,external_React_.createElement)(block_controls.Slot, { 50944 group: "block", 50945 className: "block-editor-block-toolbar__slot" 50946 }), (0,external_React_.createElement)(block_controls.Slot, { 50947 className: "block-editor-block-toolbar__slot" 50948 }), (0,external_React_.createElement)(block_controls.Slot, { 50949 group: "inline", 50950 className: "block-editor-block-toolbar__slot" 50951 }), (0,external_React_.createElement)(block_controls.Slot, { 50952 group: "other", 50953 className: "block-editor-block-toolbar__slot" 50954 }), (0,external_React_.createElement)(block_name_context.Provider, { 50955 value: blockType?.name 50956 }, (0,external_React_.createElement)(block_toolbar_last_item.Slot, null))), (0,external_React_.createElement)(BlockEditVisuallyButton, { 50957 clientIds: blockClientIds 50958 }), isDefaultEditingMode && (0,external_React_.createElement)(block_settings_menu, { 50959 clientIds: blockClientIds 50960 }))); 50961 } 50962 50963 /** 50964 * Renders the block toolbar. 50965 * 50966 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-toolbar/README.md 50967 * 50968 * @param {Object} props Components props. 50969 * @param {boolean} props.hideDragHandle Show or hide the Drag Handle for drag and drop functionality. 50970 * @param {string} props.variant Style variant of the toolbar, also passed to the Dropdowns rendered from Block Toolbar Buttons. 50971 */ 50972 function BlockToolbar({ 50973 hideDragHandle, 50974 variant 50975 }) { 50976 return (0,external_React_.createElement)(PrivateBlockToolbar, { 50977 hideDragHandle: hideDragHandle, 50978 variant: variant, 50979 focusOnMount: undefined, 50980 __experimentalInitialIndex: undefined, 50981 __experimentalOnIndexChange: undefined 50982 }); 50983 } 50984 50985 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-tools/block-toolbar-popover.js 50986 50987 /** 50988 * External dependencies 50989 */ 50990 50991 /** 50992 * WordPress dependencies 50993 */ 50994 50995 50996 50997 /** 50998 * Internal dependencies 50999 */ 51000 51001 51002 51003 51004 51005 function BlockToolbarPopover({ 51006 clientId, 51007 isTyping, 51008 __unstableContentRef 51009 }) { 51010 const { 51011 capturingClientId, 51012 isInsertionPointVisible, 51013 lastClientId 51014 } = useSelectedBlockToolProps(clientId); 51015 51016 // Stores the active toolbar item index so the block toolbar can return focus 51017 // to it when re-mounting. 51018 const initialToolbarItemIndexRef = (0,external_wp_element_namespaceObject.useRef)(); 51019 (0,external_wp_element_namespaceObject.useEffect)(() => { 51020 // Resets the index whenever the active block changes so this is not 51021 // persisted. See https://github.com/WordPress/gutenberg/pull/25760#issuecomment-717906169 51022 initialToolbarItemIndexRef.current = undefined; 51023 }, [clientId]); 51024 const { 51025 stopTyping 51026 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 51027 const isToolbarForced = (0,external_wp_element_namespaceObject.useRef)(false); 51028 (0,external_wp_keyboardShortcuts_namespaceObject.useShortcut)('core/block-editor/focus-toolbar', () => { 51029 isToolbarForced.current = true; 51030 stopTyping(true); 51031 }); 51032 (0,external_wp_element_namespaceObject.useEffect)(() => { 51033 isToolbarForced.current = false; 51034 }); 51035 const popoverProps = useBlockToolbarPopoverProps({ 51036 contentElement: __unstableContentRef?.current, 51037 clientId 51038 }); 51039 return !isTyping && (0,external_React_.createElement)(block_popover, { 51040 clientId: capturingClientId || clientId, 51041 bottomClientId: lastClientId, 51042 className: classnames_default()('block-editor-block-list__block-popover', { 51043 'is-insertion-point-visible': isInsertionPointVisible 51044 }), 51045 resize: false, 51046 ...popoverProps 51047 }, (0,external_React_.createElement)(PrivateBlockToolbar 51048 // If the toolbar is being shown because of being forced 51049 // it should focus the toolbar right after the mount. 51050 , { 51051 focusOnMount: isToolbarForced.current, 51052 __experimentalInitialIndex: initialToolbarItemIndexRef.current, 51053 __experimentalOnIndexChange: index => { 51054 initialToolbarItemIndexRef.current = index; 51055 }, 51056 variant: "toolbar" 51057 })); 51058 } 51059 51060 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-tools/block-selection-button.js 51061 51062 /** 51063 * External dependencies 51064 */ 51065 51066 51067 /** 51068 * WordPress dependencies 51069 */ 51070 51071 51072 51073 51074 51075 51076 51077 51078 51079 51080 /** 51081 * Internal dependencies 51082 */ 51083 51084 51085 51086 51087 51088 51089 51090 /** 51091 * Block selection button component, displaying the label of the block. If the block 51092 * descends from a root block, a button is displayed enabling the user to select 51093 * the root block. 51094 * 51095 * @param {string} props Component props. 51096 * @param {string} props.clientId Client ID of block. 51097 * 51098 * @return {Component} The component to be rendered. 51099 */ 51100 function BlockSelectionButton({ 51101 clientId, 51102 rootClientId 51103 }) { 51104 const selected = (0,external_wp_data_namespaceObject.useSelect)(select => { 51105 const { 51106 getBlock, 51107 getBlockIndex, 51108 hasBlockMovingClientId, 51109 getBlockListSettings, 51110 __unstableGetEditorMode 51111 } = select(store); 51112 const { 51113 getActiveBlockVariation, 51114 getBlockType 51115 } = select(external_wp_blocks_namespaceObject.store); 51116 const index = getBlockIndex(clientId); 51117 const { 51118 name, 51119 attributes 51120 } = getBlock(clientId); 51121 const blockType = getBlockType(name); 51122 const orientation = getBlockListSettings(rootClientId)?.orientation; 51123 const match = getActiveBlockVariation(name, attributes); 51124 return { 51125 blockMovingMode: hasBlockMovingClientId(), 51126 editorMode: __unstableGetEditorMode(), 51127 icon: match?.icon || blockType.icon, 51128 label: (0,external_wp_blocks_namespaceObject.__experimentalGetAccessibleBlockLabel)(blockType, attributes, index + 1, orientation) 51129 }; 51130 }, [clientId, rootClientId]); 51131 const { 51132 label, 51133 icon, 51134 blockMovingMode, 51135 editorMode 51136 } = selected; 51137 const { 51138 setNavigationMode, 51139 removeBlock 51140 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 51141 const ref = (0,external_wp_element_namespaceObject.useRef)(); 51142 51143 // Focus the breadcrumb in navigation mode. 51144 (0,external_wp_element_namespaceObject.useEffect)(() => { 51145 ref.current.focus(); 51146 (0,external_wp_a11y_namespaceObject.speak)(label); 51147 }, [label]); 51148 const blockElement = useBlockElement(clientId); 51149 const { 51150 hasBlockMovingClientId, 51151 getBlockIndex, 51152 getBlockRootClientId, 51153 getClientIdsOfDescendants, 51154 getSelectedBlockClientId, 51155 getMultiSelectedBlocksEndClientId, 51156 getPreviousBlockClientId, 51157 getNextBlockClientId 51158 } = (0,external_wp_data_namespaceObject.useSelect)(store); 51159 const { 51160 selectBlock, 51161 clearSelectedBlock, 51162 setBlockMovingClientId, 51163 moveBlockToPosition 51164 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 51165 function onKeyDown(event) { 51166 const { 51167 keyCode 51168 } = event; 51169 const isUp = keyCode === external_wp_keycodes_namespaceObject.UP; 51170 const isDown = keyCode === external_wp_keycodes_namespaceObject.DOWN; 51171 const isLeft = keyCode === external_wp_keycodes_namespaceObject.LEFT; 51172 const isRight = keyCode === external_wp_keycodes_namespaceObject.RIGHT; 51173 const isTab = keyCode === external_wp_keycodes_namespaceObject.TAB; 51174 const isEscape = keyCode === external_wp_keycodes_namespaceObject.ESCAPE; 51175 const isEnter = keyCode === external_wp_keycodes_namespaceObject.ENTER; 51176 const isSpace = keyCode === external_wp_keycodes_namespaceObject.SPACE; 51177 const isShift = event.shiftKey; 51178 if (isEscape && editorMode === 'navigation') { 51179 setNavigationMode(false); 51180 event.preventDefault(); 51181 return; 51182 } 51183 if (keyCode === external_wp_keycodes_namespaceObject.BACKSPACE || keyCode === external_wp_keycodes_namespaceObject.DELETE) { 51184 removeBlock(clientId); 51185 event.preventDefault(); 51186 return; 51187 } 51188 const selectedBlockClientId = getSelectedBlockClientId(); 51189 const selectionEndClientId = getMultiSelectedBlocksEndClientId(); 51190 const selectionBeforeEndClientId = getPreviousBlockClientId(selectionEndClientId || selectedBlockClientId); 51191 const selectionAfterEndClientId = getNextBlockClientId(selectionEndClientId || selectedBlockClientId); 51192 const navigateUp = isTab && isShift || isUp; 51193 const navigateDown = isTab && !isShift || isDown; 51194 // Move out of current nesting level (no effect if at root level). 51195 const navigateOut = isLeft; 51196 // Move into next nesting level (no effect if the current block has no innerBlocks). 51197 const navigateIn = isRight; 51198 let focusedBlockUid; 51199 if (navigateUp) { 51200 focusedBlockUid = selectionBeforeEndClientId; 51201 } else if (navigateDown) { 51202 focusedBlockUid = selectionAfterEndClientId; 51203 } else if (navigateOut) { 51204 var _getBlockRootClientId; 51205 focusedBlockUid = (_getBlockRootClientId = getBlockRootClientId(selectedBlockClientId)) !== null && _getBlockRootClientId !== void 0 ? _getBlockRootClientId : selectedBlockClientId; 51206 } else if (navigateIn) { 51207 var _getClientIdsOfDescen; 51208 focusedBlockUid = (_getClientIdsOfDescen = getClientIdsOfDescendants(selectedBlockClientId)[0]) !== null && _getClientIdsOfDescen !== void 0 ? _getClientIdsOfDescen : selectedBlockClientId; 51209 } 51210 const startingBlockClientId = hasBlockMovingClientId(); 51211 if (isEscape && startingBlockClientId && !event.defaultPrevented) { 51212 setBlockMovingClientId(null); 51213 event.preventDefault(); 51214 } 51215 if ((isEnter || isSpace) && startingBlockClientId) { 51216 const sourceRoot = getBlockRootClientId(startingBlockClientId); 51217 const destRoot = getBlockRootClientId(selectedBlockClientId); 51218 const sourceBlockIndex = getBlockIndex(startingBlockClientId); 51219 let destinationBlockIndex = getBlockIndex(selectedBlockClientId); 51220 if (sourceBlockIndex < destinationBlockIndex && sourceRoot === destRoot) { 51221 destinationBlockIndex -= 1; 51222 } 51223 moveBlockToPosition(startingBlockClientId, sourceRoot, destRoot, destinationBlockIndex); 51224 selectBlock(startingBlockClientId); 51225 setBlockMovingClientId(null); 51226 } 51227 // Prevent the block from being moved into itself. 51228 if (startingBlockClientId && selectedBlockClientId === startingBlockClientId && navigateIn) { 51229 return; 51230 } 51231 if (navigateDown || navigateUp || navigateOut || navigateIn) { 51232 if (focusedBlockUid) { 51233 event.preventDefault(); 51234 selectBlock(focusedBlockUid); 51235 } else if (isTab && selectedBlockClientId) { 51236 let nextTabbable; 51237 if (navigateDown) { 51238 nextTabbable = blockElement; 51239 do { 51240 nextTabbable = external_wp_dom_namespaceObject.focus.tabbable.findNext(nextTabbable); 51241 } while (nextTabbable && blockElement.contains(nextTabbable)); 51242 if (!nextTabbable) { 51243 nextTabbable = blockElement.ownerDocument.defaultView.frameElement; 51244 nextTabbable = external_wp_dom_namespaceObject.focus.tabbable.findNext(nextTabbable); 51245 } 51246 } else { 51247 nextTabbable = external_wp_dom_namespaceObject.focus.tabbable.findPrevious(blockElement); 51248 } 51249 if (nextTabbable) { 51250 event.preventDefault(); 51251 nextTabbable.focus(); 51252 clearSelectedBlock(); 51253 } 51254 } 51255 } 51256 } 51257 const classNames = classnames_default()('block-editor-block-list__block-selection-button', { 51258 'is-block-moving-mode': !!blockMovingMode 51259 }); 51260 const dragHandleLabel = (0,external_wp_i18n_namespaceObject.__)('Drag'); 51261 return (0,external_React_.createElement)("div", { 51262 className: classNames 51263 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Flex, { 51264 justify: "center", 51265 className: "block-editor-block-list__block-selection-button__content" 51266 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexItem, null, (0,external_React_.createElement)(block_icon, { 51267 icon: icon, 51268 showColors: true 51269 })), (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexItem, null, editorMode === 'zoom-out' && (0,external_React_.createElement)(block_mover, { 51270 clientIds: [clientId], 51271 hideDragHandle: true 51272 }), editorMode === 'navigation' && (0,external_React_.createElement)(block_draggable, { 51273 clientIds: [clientId] 51274 }, draggableProps => (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 51275 icon: drag_handle, 51276 className: "block-selection-button_drag-handle", 51277 "aria-hidden": "true", 51278 label: dragHandleLabel 51279 // Should not be able to tab to drag handle as this 51280 // button can only be used with a pointer device. 51281 , 51282 tabIndex: "-1", 51283 ...draggableProps 51284 }))), (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexItem, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 51285 ref: ref, 51286 onClick: editorMode === 'navigation' ? () => setNavigationMode(false) : undefined, 51287 onKeyDown: onKeyDown, 51288 label: label, 51289 showTooltip: false, 51290 className: "block-selection-button_select-button" 51291 }, (0,external_React_.createElement)(BlockTitle, { 51292 clientId: clientId, 51293 maximumLength: 35 51294 }))))); 51295 } 51296 /* harmony default export */ const block_selection_button = (BlockSelectionButton); 51297 51298 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-tools/block-toolbar-breadcrumb.js 51299 51300 /** 51301 * External dependencies 51302 */ 51303 51304 51305 /** 51306 * Internal dependencies 51307 */ 51308 51309 51310 51311 51312 function BlockToolbarBreadcrumb({ 51313 clientId, 51314 __unstableContentRef 51315 }) { 51316 const { 51317 capturingClientId, 51318 isInsertionPointVisible, 51319 lastClientId, 51320 rootClientId 51321 } = useSelectedBlockToolProps(clientId); 51322 const popoverProps = useBlockToolbarPopoverProps({ 51323 contentElement: __unstableContentRef?.current, 51324 clientId 51325 }); 51326 return (0,external_React_.createElement)(block_popover, { 51327 clientId: capturingClientId || clientId, 51328 bottomClientId: lastClientId, 51329 className: classnames_default()('block-editor-block-list__block-popover', { 51330 'is-insertion-point-visible': isInsertionPointVisible 51331 }), 51332 resize: false, 51333 ...popoverProps 51334 }, (0,external_React_.createElement)(block_selection_button, { 51335 clientId: clientId, 51336 rootClientId: rootClientId 51337 })); 51338 } 51339 51340 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-tools/zoom-out-mode-inserters.js 51341 51342 /** 51343 * WordPress dependencies 51344 */ 51345 51346 51347 51348 /** 51349 * Internal dependencies 51350 */ 51351 51352 51353 51354 function ZoomOutModeInserters({ 51355 __unstableContentRef 51356 }) { 51357 const [isReady, setIsReady] = (0,external_wp_element_namespaceObject.useState)(false); 51358 const blockOrder = (0,external_wp_data_namespaceObject.useSelect)(select => { 51359 return select(store).getBlockOrder(); 51360 }, []); 51361 51362 // Defer the initial rendering to avoid the jumps due to the animation. 51363 (0,external_wp_element_namespaceObject.useEffect)(() => { 51364 const timeout = setTimeout(() => { 51365 setIsReady(true); 51366 }, 500); 51367 return () => { 51368 clearTimeout(timeout); 51369 }; 51370 }, []); 51371 if (!isReady) { 51372 return null; 51373 } 51374 return blockOrder.map((clientId, index) => { 51375 if (index === blockOrder.length - 1) { 51376 return null; 51377 } 51378 return (0,external_React_.createElement)(inbetween, { 51379 key: clientId, 51380 previousClientId: clientId, 51381 nextClientId: blockOrder[index + 1], 51382 __unstableContentRef: __unstableContentRef 51383 }, (0,external_React_.createElement)("div", { 51384 className: "block-editor-block-list__insertion-point-inserter is-with-inserter" 51385 }, (0,external_React_.createElement)(inserter, { 51386 position: "bottom center", 51387 clientId: blockOrder[index + 1], 51388 __experimentalIsQuick: true 51389 }))); 51390 }); 51391 } 51392 /* harmony default export */ const zoom_out_mode_inserters = (ZoomOutModeInserters); 51393 51394 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-tools/index.js 51395 51396 /** 51397 * WordPress dependencies 51398 */ 51399 51400 51401 51402 51403 51404 51405 /** 51406 * Internal dependencies 51407 */ 51408 51409 51410 51411 51412 51413 51414 51415 function block_tools_selector(select) { 51416 const { 51417 getSelectedBlockClientId, 51418 getFirstMultiSelectedBlockClientId, 51419 getBlock, 51420 getSettings, 51421 hasMultiSelection, 51422 __unstableGetEditorMode, 51423 isTyping 51424 } = select(store); 51425 const clientId = getSelectedBlockClientId() || getFirstMultiSelectedBlockClientId(); 51426 const { 51427 name = '', 51428 attributes = {} 51429 } = getBlock(clientId) || {}; 51430 const editorMode = __unstableGetEditorMode(); 51431 const hasSelectedBlock = clientId && name; 51432 const isEmptyDefaultBlock = (0,external_wp_blocks_namespaceObject.isUnmodifiedDefaultBlock)({ 51433 name, 51434 attributes 51435 }); 51436 const _showEmptyBlockSideInserter = clientId && !isTyping() && editorMode === 'edit' && (0,external_wp_blocks_namespaceObject.isUnmodifiedDefaultBlock)({ 51437 name, 51438 attributes 51439 }); 51440 const maybeShowBreadcrumb = hasSelectedBlock && !hasMultiSelection() && (editorMode === 'navigation' || editorMode === 'zoom-out'); 51441 return { 51442 clientId, 51443 hasFixedToolbar: getSettings().hasFixedToolbar, 51444 isTyping: isTyping(), 51445 isZoomOutMode: editorMode === 'zoom-out', 51446 showEmptyBlockSideInserter: _showEmptyBlockSideInserter, 51447 showBreadcrumb: !_showEmptyBlockSideInserter && maybeShowBreadcrumb, 51448 showBlockToolbar: !getSettings().hasFixedToolbar && !_showEmptyBlockSideInserter && hasSelectedBlock && !isEmptyDefaultBlock && !maybeShowBreadcrumb 51449 }; 51450 } 51451 51452 /** 51453 * Renders block tools (the block toolbar, select/navigation mode toolbar, the 51454 * insertion point and a slot for the inline rich text toolbar). Must be wrapped 51455 * around the block content and editor styles wrapper or iframe. 51456 * 51457 * @param {Object} $0 Props. 51458 * @param {Object} $0.children The block content and style container. 51459 * @param {Object} $0.__unstableContentRef Ref holding the content scroll container. 51460 */ 51461 function BlockTools({ 51462 children, 51463 __unstableContentRef, 51464 ...props 51465 }) { 51466 const { 51467 clientId, 51468 hasFixedToolbar, 51469 isTyping, 51470 isZoomOutMode, 51471 showEmptyBlockSideInserter, 51472 showBreadcrumb, 51473 showBlockToolbar 51474 } = (0,external_wp_data_namespaceObject.useSelect)(block_tools_selector, []); 51475 const isMatch = (0,external_wp_keyboardShortcuts_namespaceObject.__unstableUseShortcutEventMatch)(); 51476 const { 51477 getSelectedBlockClientIds, 51478 getBlockRootClientId 51479 } = (0,external_wp_data_namespaceObject.useSelect)(store); 51480 const { 51481 duplicateBlocks, 51482 removeBlocks, 51483 insertAfterBlock, 51484 insertBeforeBlock, 51485 selectBlock, 51486 moveBlocksUp, 51487 moveBlocksDown 51488 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 51489 function onKeyDown(event) { 51490 if (event.defaultPrevented) return; 51491 if (isMatch('core/block-editor/move-up', event)) { 51492 const clientIds = getSelectedBlockClientIds(); 51493 if (clientIds.length) { 51494 event.preventDefault(); 51495 const rootClientId = getBlockRootClientId(clientIds[0]); 51496 moveBlocksUp(clientIds, rootClientId); 51497 } 51498 } else if (isMatch('core/block-editor/move-down', event)) { 51499 const clientIds = getSelectedBlockClientIds(); 51500 if (clientIds.length) { 51501 event.preventDefault(); 51502 const rootClientId = getBlockRootClientId(clientIds[0]); 51503 moveBlocksDown(clientIds, rootClientId); 51504 } 51505 } else if (isMatch('core/block-editor/duplicate', event)) { 51506 const clientIds = getSelectedBlockClientIds(); 51507 if (clientIds.length) { 51508 event.preventDefault(); 51509 duplicateBlocks(clientIds); 51510 } 51511 } else if (isMatch('core/block-editor/remove', event)) { 51512 const clientIds = getSelectedBlockClientIds(); 51513 if (clientIds.length) { 51514 event.preventDefault(); 51515 removeBlocks(clientIds); 51516 } 51517 } else if (isMatch('core/block-editor/insert-after', event)) { 51518 const clientIds = getSelectedBlockClientIds(); 51519 if (clientIds.length) { 51520 event.preventDefault(); 51521 insertAfterBlock(clientIds[clientIds.length - 1]); 51522 } 51523 } else if (isMatch('core/block-editor/insert-before', event)) { 51524 const clientIds = getSelectedBlockClientIds(); 51525 if (clientIds.length) { 51526 event.preventDefault(); 51527 insertBeforeBlock(clientIds[0]); 51528 } 51529 } else if (isMatch('core/block-editor/unselect', event)) { 51530 if (event.target.closest('[role=toolbar]')) { 51531 // This shouldn't be necessary, but we have a combination of a few things all combining to create a situation where: 51532 // - Because the block toolbar uses createPortal to populate the block toolbar fills, we can't rely on the React event bubbling to hit the onKeyDown listener for the block toolbar 51533 // - Since we can't use the React tree, we use the DOM tree which _should_ handle the event bubbling correctly from a `createPortal` element. 51534 // - This bubbles via the React tree, which hits this `unselect` escape keypress before the block toolbar DOM event listener has access to it. 51535 // An alternative would be to remove the addEventListener on the navigableToolbar and use this event to handle it directly right here. That feels hacky too though. 51536 return; 51537 } 51538 const clientIds = getSelectedBlockClientIds(); 51539 if (clientIds.length > 1) { 51540 event.preventDefault(); 51541 // If there is more than one block selected, select the first 51542 // block so that focus is directed back to the beginning of the selection. 51543 // In effect, to the user this feels like deselecting the multi-selection. 51544 selectBlock(clientIds[0]); 51545 } 51546 } 51547 } 51548 const blockToolbarRef = use_popover_scroll(__unstableContentRef); 51549 const blockToolbarAfterRef = use_popover_scroll(__unstableContentRef); 51550 return ( 51551 // eslint-disable-next-line jsx-a11y/no-static-element-interactions 51552 (0,external_React_.createElement)("div", { 51553 ...props, 51554 onKeyDown: onKeyDown 51555 }, (0,external_React_.createElement)(insertion_point_InsertionPointOpenRef.Provider, { 51556 value: (0,external_wp_element_namespaceObject.useRef)(false) 51557 }, !isTyping && (0,external_React_.createElement)(InsertionPoint, { 51558 __unstableContentRef: __unstableContentRef 51559 }), showEmptyBlockSideInserter && (0,external_React_.createElement)(EmptyBlockInserter, { 51560 __unstableContentRef: __unstableContentRef, 51561 clientId: clientId 51562 }), showBlockToolbar && (0,external_React_.createElement)(BlockToolbarPopover, { 51563 __unstableContentRef: __unstableContentRef, 51564 clientId: clientId, 51565 isTyping: isTyping 51566 }), showBreadcrumb && (0,external_React_.createElement)(BlockToolbarBreadcrumb, { 51567 __unstableContentRef: __unstableContentRef, 51568 clientId: clientId 51569 }), !isZoomOutMode && !hasFixedToolbar && (0,external_React_.createElement)(external_wp_components_namespaceObject.Popover.Slot, { 51570 name: "block-toolbar", 51571 ref: blockToolbarRef 51572 }), children, (0,external_React_.createElement)(external_wp_components_namespaceObject.Popover.Slot, { 51573 name: "__unstable-block-tools-after", 51574 ref: blockToolbarAfterRef 51575 }), isZoomOutMode && (0,external_React_.createElement)(zoom_out_mode_inserters, { 51576 __unstableContentRef: __unstableContentRef 51577 }))) 51578 ); 51579 } 51580 51581 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-canvas/index.js 51582 51583 /** 51584 * WordPress dependencies 51585 */ 51586 51587 51588 51589 /** 51590 * Internal dependencies 51591 */ 51592 51593 51594 51595 51596 51597 51598 51599 function ExperimentalBlockCanvas({ 51600 shouldIframe = true, 51601 height = '300px', 51602 children = (0,external_React_.createElement)(BlockList, null), 51603 styles, 51604 contentRef: contentRefProp, 51605 iframeProps 51606 }) { 51607 const resetTypingRef = useMouseMoveTypingReset(); 51608 const clearerRef = useBlockSelectionClearer(); 51609 const localRef = (0,external_wp_element_namespaceObject.useRef)(); 51610 const contentRef = (0,external_wp_compose_namespaceObject.useMergeRefs)([contentRefProp, clearerRef, localRef]); 51611 if (!shouldIframe) { 51612 return (0,external_React_.createElement)(BlockTools, { 51613 __unstableContentRef: localRef, 51614 style: { 51615 height, 51616 display: 'flex' 51617 } 51618 }, (0,external_React_.createElement)(EditorStyles, { 51619 styles: styles, 51620 scope: ".editor-styles-wrapper" 51621 }), (0,external_React_.createElement)(writing_flow, { 51622 ref: contentRef, 51623 className: "editor-styles-wrapper", 51624 tabIndex: -1, 51625 style: { 51626 height: '100%', 51627 width: '100%' 51628 } 51629 }, children)); 51630 } 51631 return (0,external_React_.createElement)(BlockTools, { 51632 __unstableContentRef: localRef, 51633 style: { 51634 height, 51635 display: 'flex' 51636 } 51637 }, (0,external_React_.createElement)(iframe, { 51638 ...iframeProps, 51639 ref: resetTypingRef, 51640 contentRef: contentRef, 51641 style: { 51642 ...iframeProps?.style 51643 }, 51644 name: "editor-canvas" 51645 }, (0,external_React_.createElement)(EditorStyles, { 51646 styles: styles 51647 }), children)); 51648 } 51649 51650 /** 51651 * BlockCanvas component is a component used to display the canvas of the block editor. 51652 * What we call the canvas is an iframe containing the block list that you can manipulate. 51653 * The component is also responsible of wiring up all the necessary hooks to enable 51654 * the keyboard navigation across blocks in the editor and inject content styles into the iframe. 51655 * 51656 * @example 51657 * 51658 * ```jsx 51659 * function MyBlockEditor() { 51660 * const [ blocks, updateBlocks ] = useState([]); 51661 * return ( 51662 * <BlockEditorProvider 51663 * value={ blocks } 51664 * onInput={ updateBlocks } 51665 * onChange={ persistBlocks } 51666 * > 51667 * <BlockCanvas height="400px" /> 51668 * </BlockEditorProvider> 51669 * ); 51670 * } 51671 * ``` 51672 * 51673 * @param {Object} props Component props. 51674 * @param {string} props.height Canvas height, defaults to 300px. 51675 * @param {Array} props.styles Content styles to inject into the iframe. 51676 * @param {Element} props.children Content of the canvas, defaults to the BlockList component. 51677 * @return {Element} Block Breadcrumb. 51678 */ 51679 function BlockCanvas({ 51680 children, 51681 height, 51682 styles 51683 }) { 51684 return (0,external_React_.createElement)(ExperimentalBlockCanvas, { 51685 height: height, 51686 styles: styles 51687 }, children); 51688 } 51689 /* harmony default export */ const block_canvas = (BlockCanvas); 51690 51691 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/color-style-selector/index.js 51692 51693 /** 51694 * WordPress dependencies 51695 */ 51696 51697 51698 51699 51700 const ColorSelectorSVGIcon = () => (0,external_React_.createElement)(external_wp_components_namespaceObject.SVG, { 51701 xmlns: "http://www.w3.org/2000/svg", 51702 viewBox: "0 0 20 20" 51703 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Path, { 51704 d: "M7.434 5l3.18 9.16H8.538l-.692-2.184H4.628l-.705 2.184H2L5.18 5h2.254zm-1.13 1.904h-.115l-1.148 3.593H7.44L6.304 6.904zM14.348 7.006c1.853 0 2.9.876 2.9 2.374v4.78h-1.79v-.914h-.114c-.362.64-1.123 1.022-2.031 1.022-1.346 0-2.292-.826-2.292-2.108 0-1.27.972-2.006 2.71-2.107l1.696-.102V9.38c0-.584-.42-.914-1.18-.914-.667 0-1.112.228-1.264.647h-1.701c.12-1.295 1.307-2.107 3.066-2.107zm1.079 4.1l-1.416.09c-.793.056-1.18.342-1.18.844 0 .52.45.837 1.091.837.857 0 1.505-.545 1.505-1.256v-.515z" 51705 })); 51706 51707 /** 51708 * Color Selector Icon component. 51709 * 51710 * @param {Object} props Component properties. 51711 * @param {Object} props.style Style object. 51712 * @param {string} props.className Class name for component. 51713 * 51714 * @return {*} React Icon component. 51715 */ 51716 const ColorSelectorIcon = ({ 51717 style, 51718 className 51719 }) => { 51720 return (0,external_React_.createElement)("div", { 51721 className: "block-library-colors-selector__icon-container" 51722 }, (0,external_React_.createElement)("div", { 51723 className: `$className} block-library-colors-selector__state-selection`, 51724 style: style 51725 }, (0,external_React_.createElement)(ColorSelectorSVGIcon, null))); 51726 }; 51727 51728 /** 51729 * Renders the Colors Selector Toolbar with the icon button. 51730 * 51731 * @param {Object} props Component properties. 51732 * @param {Object} props.TextColor Text color component that wraps icon. 51733 * @param {Object} props.BackgroundColor Background color component that wraps icon. 51734 * 51735 * @return {*} React toggle button component. 51736 */ 51737 const renderToggleComponent = ({ 51738 TextColor, 51739 BackgroundColor 51740 }) => ({ 51741 onToggle, 51742 isOpen 51743 }) => { 51744 const openOnArrowDown = event => { 51745 if (!isOpen && event.keyCode === external_wp_keycodes_namespaceObject.DOWN) { 51746 event.preventDefault(); 51747 onToggle(); 51748 } 51749 }; 51750 return (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarGroup, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarButton, { 51751 className: "components-toolbar__control block-library-colors-selector__toggle", 51752 label: (0,external_wp_i18n_namespaceObject.__)('Open Colors Selector'), 51753 onClick: onToggle, 51754 onKeyDown: openOnArrowDown, 51755 icon: (0,external_React_.createElement)(BackgroundColor, null, (0,external_React_.createElement)(TextColor, null, (0,external_React_.createElement)(ColorSelectorIcon, null))) 51756 })); 51757 }; 51758 const BlockColorsStyleSelector = ({ 51759 children, 51760 ...other 51761 }) => { 51762 external_wp_deprecated_default()(`wp.blockEditor.BlockColorsStyleSelector`, { 51763 alternative: 'block supports API', 51764 since: '6.1', 51765 version: '6.3' 51766 }); 51767 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Dropdown, { 51768 popoverProps: { 51769 placement: 'bottom-start' 51770 }, 51771 className: "block-library-colors-selector", 51772 contentClassName: "block-library-colors-selector__popover", 51773 renderToggle: renderToggleComponent(other), 51774 renderContent: () => children 51775 }); 51776 }; 51777 /* harmony default export */ const color_style_selector = (BlockColorsStyleSelector); 51778 51779 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/list-view.js 51780 51781 /** 51782 * WordPress dependencies 51783 */ 51784 51785 const listView = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 51786 viewBox: "0 0 24 24", 51787 xmlns: "http://www.w3.org/2000/svg" 51788 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 51789 d: "M3 6h11v1.5H3V6Zm3.5 5.5h11V13h-11v-1.5ZM21 17H10v1.5h11V17Z" 51790 })); 51791 /* harmony default export */ const list_view = (listView); 51792 51793 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/list-view/context.js 51794 /** 51795 * WordPress dependencies 51796 */ 51797 51798 const ListViewContext = (0,external_wp_element_namespaceObject.createContext)({}); 51799 const useListViewContext = () => (0,external_wp_element_namespaceObject.useContext)(ListViewContext); 51800 51801 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/list-view/aria-referenced-text.js 51802 51803 /** 51804 * WordPress dependencies 51805 */ 51806 51807 51808 /** 51809 * A component specifically designed to be used as an element referenced 51810 * by ARIA attributes such as `aria-labelledby` or `aria-describedby`. 51811 * 51812 * @param {Object} props Props. 51813 * @param {import('react').ReactNode} props.children 51814 */ 51815 function AriaReferencedText({ 51816 children, 51817 ...props 51818 }) { 51819 const ref = (0,external_wp_element_namespaceObject.useRef)(); 51820 (0,external_wp_element_namespaceObject.useEffect)(() => { 51821 if (ref.current) { 51822 // This seems like a no-op, but it fixes a bug in Firefox where 51823 // it fails to recompute the text when only the text node changes. 51824 // @see https://github.com/WordPress/gutenberg/pull/51035 51825 ref.current.textContent = ref.current.textContent; 51826 } 51827 }, [children]); 51828 return (0,external_React_.createElement)("div", { 51829 hidden: true, 51830 ...props, 51831 ref: ref 51832 }, children); 51833 } 51834 51835 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/list-view/appender.js 51836 51837 /** 51838 * WordPress dependencies 51839 */ 51840 51841 51842 51843 51844 51845 51846 /** 51847 * Internal dependencies 51848 */ 51849 51850 51851 51852 51853 51854 const Appender = (0,external_wp_element_namespaceObject.forwardRef)(({ 51855 nestingLevel, 51856 blockCount, 51857 clientId, 51858 ...props 51859 }, ref) => { 51860 const { 51861 insertedBlock, 51862 setInsertedBlock 51863 } = useListViewContext(); 51864 const instanceId = (0,external_wp_compose_namespaceObject.useInstanceId)(Appender); 51865 const hideInserter = (0,external_wp_data_namespaceObject.useSelect)(select => { 51866 const { 51867 getTemplateLock, 51868 __unstableGetEditorMode 51869 } = select(store); 51870 return !!getTemplateLock(clientId) || __unstableGetEditorMode() === 'zoom-out'; 51871 }, [clientId]); 51872 const blockTitle = useBlockDisplayTitle({ 51873 clientId, 51874 context: 'list-view' 51875 }); 51876 const insertedBlockTitle = useBlockDisplayTitle({ 51877 clientId: insertedBlock?.clientId, 51878 context: 'list-view' 51879 }); 51880 (0,external_wp_element_namespaceObject.useEffect)(() => { 51881 if (!insertedBlockTitle?.length) { 51882 return; 51883 } 51884 (0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.sprintf)( 51885 // translators: %s: name of block being inserted (i.e. Paragraph, Image, Group etc) 51886 (0,external_wp_i18n_namespaceObject.__)('%s block inserted'), insertedBlockTitle), 'assertive'); 51887 }, [insertedBlockTitle]); 51888 if (hideInserter) { 51889 return null; 51890 } 51891 const descriptionId = `list-view-appender__$instanceId}`; 51892 const description = (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: 1: The name of the block. 2: The numerical position of the block. 3: The level of nesting for the block. */ 51893 (0,external_wp_i18n_namespaceObject.__)('Append to %1$s block at position %2$d, Level %3$d'), blockTitle, blockCount + 1, nestingLevel); 51894 return (0,external_React_.createElement)("div", { 51895 className: "list-view-appender" 51896 }, (0,external_React_.createElement)(inserter, { 51897 ref: ref, 51898 rootClientId: clientId, 51899 position: "bottom right", 51900 isAppender: true, 51901 selectBlockOnInsert: false, 51902 shouldDirectInsert: false, 51903 __experimentalIsQuick: true, 51904 ...props, 51905 toggleProps: { 51906 'aria-describedby': descriptionId 51907 }, 51908 onSelectOrClose: maybeInsertedBlock => { 51909 if (maybeInsertedBlock?.clientId) { 51910 setInsertedBlock(maybeInsertedBlock); 51911 } 51912 } 51913 }), (0,external_React_.createElement)(AriaReferencedText, { 51914 id: descriptionId 51915 }, description)); 51916 }); 51917 51918 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/list-view/leaf.js 51919 51920 /** 51921 * External dependencies 51922 */ 51923 51924 51925 51926 /** 51927 * WordPress dependencies 51928 */ 51929 51930 51931 51932 51933 /** 51934 * Internal dependencies 51935 */ 51936 51937 const AnimatedTreeGridRow = dist_esm_it(external_wp_components_namespaceObject.__experimentalTreeGridRow); 51938 const ListViewLeaf = (0,external_wp_element_namespaceObject.forwardRef)(({ 51939 isDragged, 51940 isSelected, 51941 position, 51942 level, 51943 rowCount, 51944 children, 51945 className, 51946 path, 51947 ...props 51948 }, ref) => { 51949 const animationRef = use_moving_animation({ 51950 clientId: props['data-block'], 51951 enableAnimation: true, 51952 triggerAnimationOnChange: path 51953 }); 51954 const mergedRef = (0,external_wp_compose_namespaceObject.useMergeRefs)([ref, animationRef]); 51955 return (0,external_React_.createElement)(AnimatedTreeGridRow, { 51956 ref: mergedRef, 51957 className: classnames_default()('block-editor-list-view-leaf', className), 51958 level: level, 51959 positionInSet: position, 51960 setSize: rowCount, 51961 isExpanded: undefined, 51962 ...props 51963 }, children); 51964 }); 51965 /* harmony default export */ const leaf = (ListViewLeaf); 51966 51967 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/list-view/use-list-view-scroll-into-view.js 51968 /** 51969 * WordPress dependencies 51970 */ 51971 51972 51973 function useListViewScrollIntoView({ 51974 isSelected, 51975 selectedClientIds, 51976 rowItemRef 51977 }) { 51978 const isSingleSelection = selectedClientIds.length === 1; 51979 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 51980 // Skip scrolling into view if this particular block isn't selected, 51981 // or if more than one block is selected overall. This is to avoid 51982 // scrolling the view in a multi selection where the user has intentionally 51983 // selected multiple blocks within the list view, but the initially 51984 // selected block may be out of view. 51985 if (!isSelected || !isSingleSelection || !rowItemRef.current) { 51986 return; 51987 } 51988 const scrollContainer = (0,external_wp_dom_namespaceObject.getScrollContainer)(rowItemRef.current); 51989 const { 51990 ownerDocument 51991 } = rowItemRef.current; 51992 const windowScroll = scrollContainer === ownerDocument.body || scrollContainer === ownerDocument.documentElement; 51993 51994 // If the there is no scroll container, of if the scroll container is the window, 51995 // do not scroll into view, as the block is already in view. 51996 if (windowScroll || !scrollContainer) { 51997 return; 51998 } 51999 const rowRect = rowItemRef.current.getBoundingClientRect(); 52000 const scrollContainerRect = scrollContainer.getBoundingClientRect(); 52001 52002 // If the selected block is not currently visible, scroll to it. 52003 if (rowRect.top < scrollContainerRect.top || rowRect.bottom > scrollContainerRect.bottom) { 52004 rowItemRef.current.scrollIntoView(); 52005 } 52006 }, [isSelected, isSingleSelection, rowItemRef]); 52007 } 52008 52009 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/pin-small.js 52010 52011 /** 52012 * WordPress dependencies 52013 */ 52014 52015 const pinSmall = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 52016 width: "24", 52017 height: "24", 52018 viewBox: "0 0 24 24", 52019 xmlns: "http://www.w3.org/2000/svg" 52020 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 52021 d: "M10.97 10.159a3.382 3.382 0 0 0-2.857.955l1.724 1.723-2.836 2.913L7 17h1.25l2.913-2.837 1.723 1.723a3.38 3.38 0 0 0 .606-.825c.33-.63.446-1.343.35-2.032L17 10.695 13.305 7l-2.334 3.159Z" 52022 })); 52023 /* harmony default export */ const pin_small = (pinSmall); 52024 52025 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/lock-small.js 52026 52027 /** 52028 * WordPress dependencies 52029 */ 52030 52031 const lockSmall = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 52032 viewBox: "0 0 24 24", 52033 xmlns: "http://www.w3.org/2000/svg" 52034 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 52035 fillRule: "evenodd", 52036 clipRule: "evenodd", 52037 d: "M15 11h-.2V9c0-1.5-1.2-2.8-2.8-2.8S9.2 7.5 9.2 9v2H9c-.6 0-1 .4-1 1v4c0 .6.4 1 1 1h6c.6 0 1-.4 1-1v-4c0-.6-.4-1-1-1zm-1.8 0h-2.5V9c0-.7.6-1.2 1.2-1.2s1.2.6 1.2 1.2v2z" 52038 })); 52039 /* harmony default export */ const lock_small = (lockSmall); 52040 52041 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/list-view/expander.js 52042 52043 /** 52044 * WordPress dependencies 52045 */ 52046 52047 52048 function ListViewExpander({ 52049 onClick 52050 }) { 52051 return ( 52052 // Keyboard events are handled by TreeGrid see: components/src/tree-grid/index.js 52053 // 52054 // The expander component is implemented as a pseudo element in the w3 example 52055 // https://www.w3.org/TR/wai-aria-practices/examples/treegrid/treegrid-1.html 52056 // 52057 // We've mimicked this by adding an icon with aria-hidden set to true to hide this from the accessibility tree. 52058 // For the current tree grid implementation, please do not try to make this a button. 52059 // 52060 // eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions 52061 (0,external_React_.createElement)("span", { 52062 className: "block-editor-list-view__expander", 52063 onClick: event => onClick(event, { 52064 forceToggle: true 52065 }), 52066 "aria-hidden": "true", 52067 "data-testid": "list-view-expander" 52068 }, (0,external_React_.createElement)(build_module_icon, { 52069 icon: (0,external_wp_i18n_namespaceObject.isRTL)() ? chevron_left_small : chevron_right_small 52070 })) 52071 ); 52072 } 52073 52074 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/list-view/use-list-view-images.js 52075 /** 52076 * WordPress dependencies 52077 */ 52078 52079 52080 52081 /** 52082 * Internal dependencies 52083 */ 52084 52085 52086 // Maximum number of images to display in a list view row. 52087 const MAX_IMAGES = 3; 52088 function getImage(block) { 52089 if (block.name !== 'core/image') { 52090 return; 52091 } 52092 if (block.attributes?.url) { 52093 return { 52094 url: block.attributes.url, 52095 alt: block.attributes.alt, 52096 clientId: block.clientId 52097 }; 52098 } 52099 } 52100 function getImagesFromGallery(block) { 52101 if (block.name !== 'core/gallery' || !block.innerBlocks) { 52102 return []; 52103 } 52104 const images = []; 52105 for (const innerBlock of block.innerBlocks) { 52106 const img = getImage(innerBlock); 52107 if (img) { 52108 images.push(img); 52109 } 52110 if (images.length >= MAX_IMAGES) { 52111 return images; 52112 } 52113 } 52114 return images; 52115 } 52116 function getImagesFromBlock(block, isExpanded) { 52117 const img = getImage(block); 52118 if (img) { 52119 return [img]; 52120 } 52121 return isExpanded ? [] : getImagesFromGallery(block); 52122 } 52123 52124 /** 52125 * Get a block's preview images for display within a list view row. 52126 * 52127 * TODO: Currently only supports images from the core/image and core/gallery 52128 * blocks. This should be expanded to support other blocks that have images, 52129 * potentially via an API that blocks can opt into / provide their own logic. 52130 * 52131 * @param {Object} props Hook properties. 52132 * @param {string} props.clientId The block's clientId. 52133 * @param {boolean} props.isExpanded Whether or not the block is expanded in the list view. 52134 * @return {Array} Images. 52135 */ 52136 function useListViewImages({ 52137 clientId, 52138 isExpanded 52139 }) { 52140 const { 52141 block 52142 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 52143 const _block = select(store).getBlock(clientId); 52144 return { 52145 block: _block 52146 }; 52147 }, [clientId]); 52148 const images = (0,external_wp_element_namespaceObject.useMemo)(() => { 52149 return getImagesFromBlock(block, isExpanded); 52150 }, [block, isExpanded]); 52151 return images; 52152 } 52153 52154 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/list-view/block-select-button.js 52155 52156 /** 52157 * External dependencies 52158 */ 52159 52160 52161 /** 52162 * WordPress dependencies 52163 */ 52164 52165 52166 52167 52168 52169 52170 52171 52172 52173 52174 /** 52175 * Internal dependencies 52176 */ 52177 52178 52179 52180 52181 52182 52183 52184 52185 52186 function ListViewBlockSelectButton({ 52187 className, 52188 block: { 52189 clientId, 52190 name: blockName 52191 }, 52192 onClick, 52193 onContextMenu, 52194 onMouseDown, 52195 onToggleExpanded, 52196 tabIndex, 52197 onFocus, 52198 onDragStart, 52199 onDragEnd, 52200 draggable, 52201 isExpanded, 52202 ariaLabel, 52203 ariaDescribedBy, 52204 updateFocusAndSelection 52205 }, ref) { 52206 const blockInformation = useBlockDisplayInformation(clientId); 52207 const blockTitle = useBlockDisplayTitle({ 52208 clientId, 52209 context: 'list-view' 52210 }); 52211 const { 52212 isLocked 52213 } = useBlockLock(clientId); 52214 const { 52215 canInsertBlockType, 52216 getSelectedBlockClientIds, 52217 getPreviousBlockClientId, 52218 getBlockRootClientId, 52219 getBlockOrder, 52220 getBlocksByClientId, 52221 getBlockAttributes, 52222 canRemoveBlocks 52223 } = (0,external_wp_data_namespaceObject.useSelect)(store); 52224 const { 52225 duplicateBlocks, 52226 multiSelect, 52227 removeBlocks 52228 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 52229 const isMatch = (0,external_wp_keyboardShortcuts_namespaceObject.__unstableUseShortcutEventMatch)(); 52230 const isSticky = blockInformation?.positionType === 'sticky'; 52231 const images = useListViewImages({ 52232 clientId, 52233 isExpanded 52234 }); 52235 const { 52236 rootClientId 52237 } = useListViewContext(); 52238 const isConnected = getBlockAttributes(clientId)?.metadata?.bindings; 52239 const positionLabel = blockInformation?.positionLabel ? (0,external_wp_i18n_namespaceObject.sprintf)( 52240 // translators: 1: Position of selected block, e.g. "Sticky" or "Fixed". 52241 (0,external_wp_i18n_namespaceObject.__)('Position: %1$s'), blockInformation.positionLabel) : ''; 52242 52243 // The `href` attribute triggers the browser's native HTML drag operations. 52244 // When the link is dragged, the element's outerHTML is set in DataTransfer object as text/html. 52245 // We need to clear any HTML drag data to prevent `pasteHandler` from firing 52246 // inside the `useOnBlockDrop` hook. 52247 const onDragStartHandler = event => { 52248 event.dataTransfer.clearData(); 52249 onDragStart?.(event); 52250 }; 52251 52252 // Determine which blocks to update: 52253 // If the current (focused) block is part of the block selection, use the whole selection. 52254 // If the focused block is not part of the block selection, only update the focused block. 52255 function getBlocksToUpdate() { 52256 const selectedBlockClientIds = getSelectedBlockClientIds(); 52257 const isUpdatingSelectedBlocks = selectedBlockClientIds.includes(clientId); 52258 const firstBlockClientId = isUpdatingSelectedBlocks ? selectedBlockClientIds[0] : clientId; 52259 const firstBlockRootClientId = getBlockRootClientId(firstBlockClientId); 52260 const blocksToUpdate = isUpdatingSelectedBlocks ? selectedBlockClientIds : [clientId]; 52261 return { 52262 blocksToUpdate, 52263 firstBlockClientId, 52264 firstBlockRootClientId, 52265 selectedBlockClientIds 52266 }; 52267 } 52268 52269 /** 52270 * @param {KeyboardEvent} event 52271 */ 52272 async function onKeyDownHandler(event) { 52273 if (event.keyCode === external_wp_keycodes_namespaceObject.ENTER || event.keyCode === external_wp_keycodes_namespaceObject.SPACE) { 52274 onClick(event); 52275 } else if (event.keyCode === external_wp_keycodes_namespaceObject.BACKSPACE || event.keyCode === external_wp_keycodes_namespaceObject.DELETE || isMatch('core/block-editor/remove', event)) { 52276 var _getPreviousBlockClie; 52277 const { 52278 blocksToUpdate: blocksToDelete, 52279 firstBlockClientId, 52280 firstBlockRootClientId, 52281 selectedBlockClientIds 52282 } = getBlocksToUpdate(); 52283 52284 // Don't update the selection if the blocks cannot be deleted. 52285 if (!canRemoveBlocks(blocksToDelete, firstBlockRootClientId)) { 52286 return; 52287 } 52288 let blockToFocus = (_getPreviousBlockClie = getPreviousBlockClientId(firstBlockClientId)) !== null && _getPreviousBlockClie !== void 0 ? _getPreviousBlockClie : 52289 // If the previous block is not found (when the first block is deleted), 52290 // fallback to focus the parent block. 52291 firstBlockRootClientId; 52292 removeBlocks(blocksToDelete, false); 52293 52294 // Update the selection if the original selection has been removed. 52295 const shouldUpdateSelection = selectedBlockClientIds.length > 0 && getSelectedBlockClientIds().length === 0; 52296 52297 // If there's no previous block nor parent block, focus the first block. 52298 if (!blockToFocus) { 52299 blockToFocus = getBlockOrder()[0]; 52300 } 52301 updateFocusAndSelection(blockToFocus, shouldUpdateSelection); 52302 } else if (isMatch('core/block-editor/duplicate', event)) { 52303 if (event.defaultPrevented) { 52304 return; 52305 } 52306 event.preventDefault(); 52307 const { 52308 blocksToUpdate, 52309 firstBlockRootClientId 52310 } = getBlocksToUpdate(); 52311 const canDuplicate = getBlocksByClientId(blocksToUpdate).every(block => { 52312 return !!block && (0,external_wp_blocks_namespaceObject.hasBlockSupport)(block.name, 'multiple', true) && canInsertBlockType(block.name, firstBlockRootClientId); 52313 }); 52314 if (canDuplicate) { 52315 const updatedBlocks = await duplicateBlocks(blocksToUpdate, false); 52316 if (updatedBlocks?.length) { 52317 // If blocks have been duplicated, focus the first duplicated block. 52318 updateFocusAndSelection(updatedBlocks[0], false); 52319 } 52320 } 52321 } else if (isMatch('core/block-editor/select-all', event)) { 52322 if (event.defaultPrevented) { 52323 return; 52324 } 52325 event.preventDefault(); 52326 const { 52327 firstBlockRootClientId, 52328 selectedBlockClientIds 52329 } = getBlocksToUpdate(); 52330 const blockClientIds = getBlockOrder(firstBlockRootClientId); 52331 if (!blockClientIds.length) { 52332 return; 52333 } 52334 52335 // If we have selected all sibling nested blocks, try selecting up a level. 52336 // This is a similar implementation to that used by `useSelectAll`. 52337 // `isShallowEqual` is used for the list view instead of a length check, 52338 // as the array of siblings of the currently focused block may be a different 52339 // set of blocks from the current block selection if the user is focused 52340 // on a different part of the list view from the block selection. 52341 if (external_wp_isShallowEqual_default()(selectedBlockClientIds, blockClientIds)) { 52342 // Only select up a level if the first block is not the root block. 52343 // This ensures that the block selection can't break out of the root block 52344 // used by the list view, if the list view is only showing a partial hierarchy. 52345 if (firstBlockRootClientId && firstBlockRootClientId !== rootClientId) { 52346 updateFocusAndSelection(firstBlockRootClientId, true); 52347 return; 52348 } 52349 } 52350 52351 // Select all while passing `null` to skip focusing to the editor canvas, 52352 // and retain focus within the list view. 52353 multiSelect(blockClientIds[0], blockClientIds[blockClientIds.length - 1], null); 52354 } 52355 } 52356 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 52357 className: classnames_default()('block-editor-list-view-block-select-button', className), 52358 onClick: onClick, 52359 onContextMenu: onContextMenu, 52360 onKeyDown: onKeyDownHandler, 52361 onMouseDown: onMouseDown, 52362 ref: ref, 52363 tabIndex: tabIndex, 52364 onFocus: onFocus, 52365 onDragStart: onDragStartHandler, 52366 onDragEnd: onDragEnd, 52367 draggable: draggable, 52368 href: `#block-$clientId}`, 52369 "aria-label": ariaLabel, 52370 "aria-describedby": ariaDescribedBy, 52371 "aria-expanded": isExpanded 52372 }, (0,external_React_.createElement)(ListViewExpander, { 52373 onClick: onToggleExpanded 52374 }), (0,external_React_.createElement)(block_icon, { 52375 icon: blockInformation?.icon, 52376 showColors: true, 52377 context: "list-view" 52378 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, { 52379 alignment: "center", 52380 className: "block-editor-list-view-block-select-button__label-wrapper", 52381 justify: "flex-start", 52382 spacing: 1 52383 }, (0,external_React_.createElement)("span", { 52384 className: "block-editor-list-view-block-select-button__title" 52385 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalTruncate, { 52386 ellipsizeMode: "auto" 52387 }, blockTitle)), blockInformation?.anchor && (0,external_React_.createElement)("span", { 52388 className: "block-editor-list-view-block-select-button__anchor-wrapper" 52389 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalTruncate, { 52390 className: "block-editor-list-view-block-select-button__anchor", 52391 ellipsizeMode: "auto" 52392 }, blockInformation.anchor)), isConnected && canBindBlock(blockName) && (0,external_React_.createElement)("span", { 52393 className: "block-editor-list-view-block-select-button__bindings" 52394 }, (0,external_React_.createElement)(build_module_icon, { 52395 icon: library_connection 52396 })), positionLabel && isSticky && (0,external_React_.createElement)(external_wp_components_namespaceObject.Tooltip, { 52397 text: positionLabel 52398 }, (0,external_React_.createElement)(build_module_icon, { 52399 icon: pin_small 52400 })), images.length ? (0,external_React_.createElement)("span", { 52401 className: "block-editor-list-view-block-select-button__images", 52402 "aria-hidden": true 52403 }, images.map((image, index) => (0,external_React_.createElement)("span", { 52404 className: "block-editor-list-view-block-select-button__image", 52405 key: image.clientId, 52406 style: { 52407 backgroundImage: `url($image.url})`, 52408 zIndex: images.length - index // Ensure the first image is on top, and subsequent images are behind. 52409 } 52410 }))) : null, isLocked && (0,external_React_.createElement)("span", { 52411 className: "block-editor-list-view-block-select-button__lock" 52412 }, (0,external_React_.createElement)(build_module_icon, { 52413 icon: lock_small 52414 }))))); 52415 } 52416 /* harmony default export */ const block_select_button = ((0,external_wp_element_namespaceObject.forwardRef)(ListViewBlockSelectButton)); 52417 52418 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/list-view/block-contents.js 52419 52420 /** 52421 * External dependencies 52422 */ 52423 52424 52425 /** 52426 * WordPress dependencies 52427 */ 52428 52429 52430 52431 /** 52432 * Internal dependencies 52433 */ 52434 52435 52436 52437 52438 const ListViewBlockContents = (0,external_wp_element_namespaceObject.forwardRef)(({ 52439 onClick, 52440 onToggleExpanded, 52441 block, 52442 isSelected, 52443 position, 52444 siblingBlockCount, 52445 level, 52446 isExpanded, 52447 selectedClientIds, 52448 ...props 52449 }, ref) => { 52450 const { 52451 clientId 52452 } = block; 52453 const { 52454 blockMovingClientId, 52455 selectedBlockInBlockEditor 52456 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 52457 const { 52458 hasBlockMovingClientId, 52459 getSelectedBlockClientId 52460 } = select(store); 52461 return { 52462 blockMovingClientId: hasBlockMovingClientId(), 52463 selectedBlockInBlockEditor: getSelectedBlockClientId() 52464 }; 52465 }, []); 52466 const { 52467 AdditionalBlockContent, 52468 insertedBlock, 52469 setInsertedBlock 52470 } = useListViewContext(); 52471 const isBlockMoveTarget = blockMovingClientId && selectedBlockInBlockEditor === clientId; 52472 const className = classnames_default()('block-editor-list-view-block-contents', { 52473 'is-dropping-before': isBlockMoveTarget 52474 }); 52475 52476 // Only include all selected blocks if the currently clicked on block 52477 // is one of the selected blocks. This ensures that if a user attempts 52478 // to drag a block that isn't part of the selection, they're still able 52479 // to drag it and rearrange its position. 52480 const draggableClientIds = selectedClientIds.includes(clientId) ? selectedClientIds : [clientId]; 52481 return (0,external_React_.createElement)(external_React_.Fragment, null, AdditionalBlockContent && (0,external_React_.createElement)(AdditionalBlockContent, { 52482 block: block, 52483 insertedBlock: insertedBlock, 52484 setInsertedBlock: setInsertedBlock 52485 }), (0,external_React_.createElement)(block_draggable, { 52486 appendToOwnerDocument: true, 52487 clientIds: draggableClientIds, 52488 cloneClassname: 'block-editor-list-view-draggable-chip' 52489 }, ({ 52490 draggable, 52491 onDragStart, 52492 onDragEnd 52493 }) => (0,external_React_.createElement)(block_select_button, { 52494 ref: ref, 52495 className: className, 52496 block: block, 52497 onClick: onClick, 52498 onToggleExpanded: onToggleExpanded, 52499 isSelected: isSelected, 52500 position: position, 52501 siblingBlockCount: siblingBlockCount, 52502 level: level, 52503 draggable: draggable, 52504 onDragStart: onDragStart, 52505 onDragEnd: onDragEnd, 52506 isExpanded: isExpanded, 52507 ...props 52508 }))); 52509 }); 52510 /* harmony default export */ const block_contents = (ListViewBlockContents); 52511 52512 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/list-view/utils.js 52513 /** 52514 * WordPress dependencies 52515 */ 52516 52517 52518 const getBlockPositionDescription = (position, siblingCount, level) => (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: 1: The numerical position of the block. 2: The total number of blocks. 3. The level of nesting for the block. */ 52519 (0,external_wp_i18n_namespaceObject.__)('Block %1$d of %2$d, Level %3$d'), position, siblingCount, level); 52520 52521 /** 52522 * Returns true if the client ID occurs within the block selection or multi-selection, 52523 * or false otherwise. 52524 * 52525 * @param {string} clientId Block client ID. 52526 * @param {string|string[]} selectedBlockClientIds Selected block client ID, or an array of multi-selected blocks client IDs. 52527 * 52528 * @return {boolean} Whether the block is in multi-selection set. 52529 */ 52530 const isClientIdSelected = (clientId, selectedBlockClientIds) => Array.isArray(selectedBlockClientIds) && selectedBlockClientIds.length ? selectedBlockClientIds.indexOf(clientId) !== -1 : selectedBlockClientIds === clientId; 52531 52532 /** 52533 * From a start and end clientId of potentially different nesting levels, 52534 * return the nearest-depth ids that have a common level of depth in the 52535 * nesting hierarchy. For multiple block selection, this ensure that the 52536 * selection is always at the same nesting level, and not split across 52537 * separate levels. 52538 * 52539 * @param {string} startId The first id of a selection. 52540 * @param {string} endId The end id of a selection, usually one that has been clicked on. 52541 * @param {string[]} startParents An array of ancestor ids for the start id, in descending order. 52542 * @param {string[]} endParents An array of ancestor ids for the end id, in descending order. 52543 * @return {Object} An object containing the start and end ids. 52544 */ 52545 function getCommonDepthClientIds(startId, endId, startParents, endParents) { 52546 const startPath = [...startParents, startId]; 52547 const endPath = [...endParents, endId]; 52548 const depth = Math.min(startPath.length, endPath.length) - 1; 52549 const start = startPath[depth]; 52550 const end = endPath[depth]; 52551 return { 52552 start, 52553 end 52554 }; 52555 } 52556 52557 /** 52558 * Shift focus to the list view item associated with a particular clientId. 52559 * 52560 * @typedef {import('@wordpress/element').RefObject} RefObject 52561 * 52562 * @param {string} focusClientId The client ID of the block to focus. 52563 * @param {?HTMLElement} treeGridElement The container element to search within. 52564 */ 52565 function focusListItem(focusClientId, treeGridElement) { 52566 const getFocusElement = () => { 52567 const row = treeGridElement?.querySelector(`[role=row][data-block="$focusClientId}"]`); 52568 if (!row) return null; 52569 // Focus the first focusable in the row, which is the ListViewBlockSelectButton. 52570 return external_wp_dom_namespaceObject.focus.focusable.find(row)[0]; 52571 }; 52572 let focusElement = getFocusElement(); 52573 if (focusElement) { 52574 focusElement.focus(); 52575 } else { 52576 // The element hasn't been painted yet. Defer focusing on the next frame. 52577 // This could happen when all blocks have been deleted and the default block 52578 // hasn't been added to the editor yet. 52579 window.requestAnimationFrame(() => { 52580 focusElement = getFocusElement(); 52581 52582 // Ignore if the element still doesn't exist. 52583 if (focusElement) { 52584 focusElement.focus(); 52585 } 52586 }); 52587 } 52588 } 52589 52590 /** 52591 * Get values for the block that flag whether the block should be displaced up or down, 52592 * whether the block is being nested, and whether the block appears after the dragged 52593 * blocks. These values are used to determine the class names to apply to the block. 52594 * The list view rows are displaced visually via CSS rules. Displacement rules: 52595 * - `normal`: no displacement — used to apply a translateY of `0` so that the block 52596 * appears in its original position, and moves to that position smoothly when dragging 52597 * outside of the list view area. 52598 * - `up`: the block should be displaced up, creating room beneath the block for the drop indicator. 52599 * - `down`: the block should be displaced down, creating room above the block for the drop indicator. 52600 * 52601 * @param {Object} props 52602 * @param {Object} props.blockIndexes The indexes of all the blocks in the list view, keyed by clientId. 52603 * @param {number|null|undefined} props.blockDropTargetIndex The index of the block that the user is dropping to. 52604 * @param {?string} props.blockDropPosition The position relative to the block that the user is dropping to. 52605 * @param {string} props.clientId The client id for the current block. 52606 * @param {?number} props.firstDraggedBlockIndex The index of the first dragged block. 52607 * @param {?boolean} props.isDragged Whether the current block is being dragged. Dragged blocks skip displacement. 52608 * @return {Object} An object containing the `displacement`, `isAfterDraggedBlocks` and `isNesting` values. 52609 */ 52610 function getDragDisplacementValues({ 52611 blockIndexes, 52612 blockDropTargetIndex, 52613 blockDropPosition, 52614 clientId, 52615 firstDraggedBlockIndex, 52616 isDragged 52617 }) { 52618 let displacement; 52619 let isNesting; 52620 let isAfterDraggedBlocks; 52621 if (!isDragged) { 52622 isNesting = false; 52623 const thisBlockIndex = blockIndexes[clientId]; 52624 isAfterDraggedBlocks = thisBlockIndex > firstDraggedBlockIndex; 52625 52626 // Determine where to displace the position of the current block, relative 52627 // to the blocks being dragged (in their original position) and the drop target 52628 // (the position where a user is currently dragging the blocks to). 52629 if (blockDropTargetIndex !== undefined && blockDropTargetIndex !== null && firstDraggedBlockIndex !== undefined) { 52630 // If the block is being dragged and there is a valid drop target, 52631 // determine if the block being rendered should be displaced up or down. 52632 52633 if (thisBlockIndex !== undefined) { 52634 if (thisBlockIndex >= firstDraggedBlockIndex && thisBlockIndex < blockDropTargetIndex) { 52635 // If the current block appears after the set of dragged blocks 52636 // (in their original position), but is before the drop target, 52637 // then the current block should be displaced up. 52638 displacement = 'up'; 52639 } else if (thisBlockIndex < firstDraggedBlockIndex && thisBlockIndex >= blockDropTargetIndex) { 52640 // If the current block appears before the set of dragged blocks 52641 // (in their original position), but is after the drop target, 52642 // then the current block should be displaced down. 52643 displacement = 'down'; 52644 } else { 52645 displacement = 'normal'; 52646 } 52647 isNesting = typeof blockDropTargetIndex === 'number' && blockDropTargetIndex - 1 === thisBlockIndex && blockDropPosition === 'inside'; 52648 } 52649 } else if (blockDropTargetIndex === null && firstDraggedBlockIndex !== undefined) { 52650 // A `null` value for `blockDropTargetIndex` indicates that the 52651 // drop target is outside of the valid areas within the list view. 52652 // In this case, the drag is still active, but as there is no 52653 // valid drop target, we should remove the gap indicating where 52654 // the block would be inserted. 52655 if (thisBlockIndex !== undefined && thisBlockIndex >= firstDraggedBlockIndex) { 52656 displacement = 'up'; 52657 } else { 52658 displacement = 'normal'; 52659 } 52660 } else if (blockDropTargetIndex !== undefined && blockDropTargetIndex !== null && firstDraggedBlockIndex === undefined) { 52661 // If the blockdrop target is defined, but there are no dragged blocks, 52662 // then the block should be displaced relative to the drop target. 52663 if (thisBlockIndex !== undefined) { 52664 if (thisBlockIndex < blockDropTargetIndex) { 52665 displacement = 'normal'; 52666 } else { 52667 displacement = 'down'; 52668 } 52669 } 52670 } else if (blockDropTargetIndex === null) { 52671 displacement = 'normal'; 52672 } 52673 } 52674 return { 52675 displacement, 52676 isNesting, 52677 isAfterDraggedBlocks 52678 }; 52679 } 52680 52681 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/list-view/block.js 52682 52683 /** 52684 * External dependencies 52685 */ 52686 52687 52688 /** 52689 * WordPress dependencies 52690 */ 52691 52692 52693 52694 52695 52696 52697 52698 52699 52700 /** 52701 * Internal dependencies 52702 */ 52703 52704 52705 52706 52707 52708 52709 52710 52711 52712 52713 function ListViewBlock({ 52714 block: { 52715 clientId 52716 }, 52717 displacement, 52718 isAfterDraggedBlocks, 52719 isDragged, 52720 isNesting, 52721 isSelected, 52722 isBranchSelected, 52723 selectBlock, 52724 position, 52725 level, 52726 rowCount, 52727 siblingBlockCount, 52728 showBlockMovers, 52729 path, 52730 isExpanded, 52731 selectedClientIds, 52732 isSyncedBranch 52733 }) { 52734 const cellRef = (0,external_wp_element_namespaceObject.useRef)(null); 52735 const rowRef = (0,external_wp_element_namespaceObject.useRef)(null); 52736 const settingsRef = (0,external_wp_element_namespaceObject.useRef)(null); 52737 const [isHovered, setIsHovered] = (0,external_wp_element_namespaceObject.useState)(false); 52738 const [settingsAnchorRect, setSettingsAnchorRect] = (0,external_wp_element_namespaceObject.useState)(); 52739 const { 52740 isLocked, 52741 canEdit, 52742 canMove 52743 } = useBlockLock(clientId); 52744 const isFirstSelectedBlock = isSelected && selectedClientIds[0] === clientId; 52745 const isLastSelectedBlock = isSelected && selectedClientIds[selectedClientIds.length - 1] === clientId; 52746 const { 52747 toggleBlockHighlight 52748 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 52749 const blockInformation = useBlockDisplayInformation(clientId); 52750 const blockTitle = blockInformation?.name || blockInformation?.title || (0,external_wp_i18n_namespaceObject.__)('Untitled'); 52751 const { 52752 block, 52753 blockName, 52754 blockEditingMode 52755 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 52756 const { 52757 getBlock, 52758 getBlockName, 52759 getBlockEditingMode 52760 } = select(store); 52761 return { 52762 block: getBlock(clientId), 52763 blockName: getBlockName(clientId), 52764 blockEditingMode: getBlockEditingMode(clientId) 52765 }; 52766 }, [clientId]); 52767 const allowRightClickOverrides = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getSettings().allowRightClickOverrides, []); 52768 const showBlockActions = 52769 // When a block hides its toolbar it also hides the block settings menu, 52770 // since that menu is part of the toolbar in the editor canvas. 52771 // List View respects this by also hiding the block settings menu. 52772 (0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockName, '__experimentalToolbar', true) && 52773 // Don't show the settings menu if block is disabled or content only. 52774 blockEditingMode === 'default'; 52775 const instanceId = (0,external_wp_compose_namespaceObject.useInstanceId)(ListViewBlock); 52776 const descriptionId = `list-view-block-select-button__$instanceId}`; 52777 const { 52778 expand, 52779 collapse, 52780 BlockSettingsMenu, 52781 listViewInstanceId, 52782 expandedState, 52783 setInsertedBlock, 52784 treeGridElementRef 52785 } = useListViewContext(); 52786 52787 // If multiple blocks are selected, deselect all blocks when the user 52788 // presses the escape key. 52789 const onKeyDown = event => { 52790 if (event.keyCode === external_wp_keycodes_namespaceObject.ESCAPE && !event.defaultPrevented && selectedClientIds.length > 0) { 52791 event.stopPropagation(); 52792 event.preventDefault(); 52793 selectBlock(event, undefined); 52794 } 52795 }; 52796 const onMouseEnter = (0,external_wp_element_namespaceObject.useCallback)(() => { 52797 setIsHovered(true); 52798 toggleBlockHighlight(clientId, true); 52799 }, [clientId, setIsHovered, toggleBlockHighlight]); 52800 const onMouseLeave = (0,external_wp_element_namespaceObject.useCallback)(() => { 52801 setIsHovered(false); 52802 toggleBlockHighlight(clientId, false); 52803 }, [clientId, setIsHovered, toggleBlockHighlight]); 52804 const selectEditorBlock = (0,external_wp_element_namespaceObject.useCallback)(event => { 52805 selectBlock(event, clientId); 52806 event.preventDefault(); 52807 }, [clientId, selectBlock]); 52808 const updateFocusAndSelection = (0,external_wp_element_namespaceObject.useCallback)((focusClientId, shouldSelectBlock) => { 52809 if (shouldSelectBlock) { 52810 selectBlock(undefined, focusClientId, null, null); 52811 } 52812 focusListItem(focusClientId, treeGridElementRef?.current); 52813 }, [selectBlock, treeGridElementRef]); 52814 const toggleExpanded = (0,external_wp_element_namespaceObject.useCallback)(event => { 52815 // Prevent shift+click from opening link in a new window when toggling. 52816 event.preventDefault(); 52817 event.stopPropagation(); 52818 if (isExpanded === true) { 52819 collapse(clientId); 52820 } else if (isExpanded === false) { 52821 expand(clientId); 52822 } 52823 }, [clientId, expand, collapse, isExpanded]); 52824 52825 // Allow right-clicking an item in the List View to open up the block settings dropdown. 52826 const onContextMenu = (0,external_wp_element_namespaceObject.useCallback)(event => { 52827 if (showBlockActions && allowRightClickOverrides) { 52828 settingsRef.current?.click(); 52829 // Ensure the position of the settings dropdown is at the cursor. 52830 setSettingsAnchorRect(new window.DOMRect(event.clientX, event.clientY, 0, 0)); 52831 event.preventDefault(); 52832 } 52833 }, [allowRightClickOverrides, settingsRef, showBlockActions]); 52834 const onMouseDown = (0,external_wp_element_namespaceObject.useCallback)(event => { 52835 // Prevent right-click from focusing the block, 52836 // because focus will be handled when opening the block settings dropdown. 52837 if (allowRightClickOverrides && event.button === 2) { 52838 event.preventDefault(); 52839 } 52840 }, [allowRightClickOverrides]); 52841 const settingsPopoverAnchor = (0,external_wp_element_namespaceObject.useMemo)(() => { 52842 const { 52843 ownerDocument 52844 } = rowRef?.current || {}; 52845 52846 // If no custom position is set, the settings dropdown will be anchored to the 52847 // DropdownMenu toggle button. 52848 if (!settingsAnchorRect || !ownerDocument) { 52849 return undefined; 52850 } 52851 52852 // Position the settings dropdown at the cursor when right-clicking a block. 52853 return { 52854 ownerDocument, 52855 getBoundingClientRect() { 52856 return settingsAnchorRect; 52857 } 52858 }; 52859 }, [settingsAnchorRect]); 52860 const clearSettingsAnchorRect = (0,external_wp_element_namespaceObject.useCallback)(() => { 52861 // Clear the custom position for the settings dropdown so that it is restored back 52862 // to being anchored to the DropdownMenu toggle button. 52863 setSettingsAnchorRect(undefined); 52864 }, [setSettingsAnchorRect]); 52865 52866 // Pass in a ref to the row, so that it can be scrolled 52867 // into view when selected. For long lists, the placeholder for the 52868 // selected block is also observed, within ListViewLeafPlaceholder. 52869 useListViewScrollIntoView({ 52870 isSelected, 52871 rowItemRef: rowRef, 52872 selectedClientIds 52873 }); 52874 52875 // When switching between rendering modes (such as template preview and content only), 52876 // it is possible for a block to temporarily be unavailable. In this case, we should not 52877 // render the leaf, to avoid errors further down the tree. 52878 if (!block) { 52879 return null; 52880 } 52881 const blockPositionDescription = getBlockPositionDescription(position, siblingBlockCount, level); 52882 const blockAriaLabel = isLocked ? (0,external_wp_i18n_namespaceObject.sprintf)( 52883 // translators: %s: The title of the block. This string indicates a link to select the locked block. 52884 (0,external_wp_i18n_namespaceObject.__)('%s (locked)'), blockTitle) : blockTitle; 52885 const settingsAriaLabel = (0,external_wp_i18n_namespaceObject.sprintf)( 52886 // translators: %s: The title of the block. 52887 (0,external_wp_i18n_namespaceObject.__)('Options for %s'), blockTitle); 52888 const hasSiblings = siblingBlockCount > 0; 52889 const hasRenderedMovers = showBlockMovers && hasSiblings; 52890 const moverCellClassName = classnames_default()('block-editor-list-view-block__mover-cell', { 52891 'is-visible': isHovered || isSelected 52892 }); 52893 const listViewBlockSettingsClassName = classnames_default()('block-editor-list-view-block__menu-cell', { 52894 'is-visible': isHovered || isFirstSelectedBlock 52895 }); 52896 let colSpan; 52897 if (hasRenderedMovers) { 52898 colSpan = 2; 52899 } else if (!showBlockActions) { 52900 colSpan = 3; 52901 } 52902 const classes = classnames_default()({ 52903 'is-selected': isSelected, 52904 'is-first-selected': isFirstSelectedBlock, 52905 'is-last-selected': isLastSelectedBlock, 52906 'is-branch-selected': isBranchSelected, 52907 'is-synced-branch': isSyncedBranch, 52908 'is-dragging': isDragged, 52909 'has-single-cell': !showBlockActions, 52910 'is-synced': blockInformation?.isSynced, 52911 'is-draggable': canMove, 52912 'is-displacement-normal': displacement === 'normal', 52913 'is-displacement-up': displacement === 'up', 52914 'is-displacement-down': displacement === 'down', 52915 'is-after-dragged-blocks': isAfterDraggedBlocks, 52916 'is-nesting': isNesting 52917 }); 52918 52919 // Only include all selected blocks if the currently clicked on block 52920 // is one of the selected blocks. This ensures that if a user attempts 52921 // to alter a block that isn't part of the selection, they're still able 52922 // to do so. 52923 const dropdownClientIds = selectedClientIds.includes(clientId) ? selectedClientIds : [clientId]; 52924 52925 // Detect if there is a block in the canvas currently being edited and multi-selection is not happening. 52926 const currentlyEditingBlockInCanvas = isSelected && selectedClientIds.length === 1; 52927 return (0,external_React_.createElement)(leaf, { 52928 className: classes, 52929 isDragged: isDragged, 52930 onKeyDown: onKeyDown, 52931 onMouseEnter: onMouseEnter, 52932 onMouseLeave: onMouseLeave, 52933 onFocus: onMouseEnter, 52934 onBlur: onMouseLeave, 52935 level: level, 52936 position: position, 52937 rowCount: rowCount, 52938 path: path, 52939 id: `list-view-$listViewInstanceId}-block-$clientId}`, 52940 "data-block": clientId, 52941 "data-expanded": canEdit ? isExpanded : undefined, 52942 ref: rowRef 52943 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalTreeGridCell, { 52944 className: "block-editor-list-view-block__contents-cell", 52945 colSpan: colSpan, 52946 ref: cellRef, 52947 "aria-selected": !!isSelected 52948 }, ({ 52949 ref, 52950 tabIndex, 52951 onFocus 52952 }) => (0,external_React_.createElement)("div", { 52953 className: "block-editor-list-view-block__contents-container" 52954 }, (0,external_React_.createElement)(block_contents, { 52955 block: block, 52956 onClick: selectEditorBlock, 52957 onContextMenu: onContextMenu, 52958 onMouseDown: onMouseDown, 52959 onToggleExpanded: toggleExpanded, 52960 isSelected: isSelected, 52961 position: position, 52962 siblingBlockCount: siblingBlockCount, 52963 level: level, 52964 ref: ref, 52965 tabIndex: currentlyEditingBlockInCanvas ? 0 : tabIndex, 52966 onFocus: onFocus, 52967 isExpanded: canEdit ? isExpanded : undefined, 52968 selectedClientIds: selectedClientIds, 52969 ariaLabel: blockAriaLabel, 52970 ariaDescribedBy: descriptionId, 52971 updateFocusAndSelection: updateFocusAndSelection 52972 }), (0,external_React_.createElement)(AriaReferencedText, { 52973 id: descriptionId 52974 }, blockPositionDescription))), hasRenderedMovers && (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalTreeGridCell, { 52975 className: moverCellClassName, 52976 withoutGridItem: true 52977 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalTreeGridItem, null, ({ 52978 ref, 52979 tabIndex, 52980 onFocus 52981 }) => (0,external_React_.createElement)(BlockMoverUpButton, { 52982 orientation: "vertical", 52983 clientIds: [clientId], 52984 ref: ref, 52985 tabIndex: tabIndex, 52986 onFocus: onFocus 52987 })), (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalTreeGridItem, null, ({ 52988 ref, 52989 tabIndex, 52990 onFocus 52991 }) => (0,external_React_.createElement)(BlockMoverDownButton, { 52992 orientation: "vertical", 52993 clientIds: [clientId], 52994 ref: ref, 52995 tabIndex: tabIndex, 52996 onFocus: onFocus 52997 })))), showBlockActions && BlockSettingsMenu && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalTreeGridCell, { 52998 className: listViewBlockSettingsClassName, 52999 "aria-selected": !!isSelected, 53000 ref: settingsRef 53001 }, ({ 53002 ref, 53003 tabIndex, 53004 onFocus 53005 }) => (0,external_React_.createElement)(BlockSettingsMenu, { 53006 clientIds: dropdownClientIds, 53007 block: block, 53008 icon: more_vertical, 53009 label: settingsAriaLabel, 53010 popoverProps: { 53011 anchor: settingsPopoverAnchor // Used to position the settings at the cursor on right-click. 53012 }, 53013 toggleProps: { 53014 ref, 53015 className: 'block-editor-list-view-block__menu', 53016 tabIndex, 53017 onClick: clearSettingsAnchorRect, 53018 onFocus 53019 }, 53020 disableOpenOnArrowDown: true, 53021 expand: expand, 53022 expandedState: expandedState, 53023 setInsertedBlock: setInsertedBlock, 53024 __experimentalSelectBlock: updateFocusAndSelection 53025 }))); 53026 } 53027 /* harmony default export */ const list_view_block = ((0,external_wp_element_namespaceObject.memo)(ListViewBlock)); 53028 53029 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/list-view/branch.js 53030 53031 /** 53032 * WordPress dependencies 53033 */ 53034 53035 53036 53037 53038 /** 53039 * Internal dependencies 53040 */ 53041 53042 53043 53044 53045 53046 53047 53048 /** 53049 * Given a block, returns the total number of blocks in that subtree. This is used to help determine 53050 * the list position of a block. 53051 * 53052 * When a block is collapsed, we do not count their children as part of that total. In the current drag 53053 * implementation dragged blocks and their children are not counted. 53054 * 53055 * @param {Object} block block tree 53056 * @param {Object} expandedState state that notes which branches are collapsed 53057 * @param {Array} draggedClientIds a list of dragged client ids 53058 * @param {boolean} isExpandedByDefault flag to determine the default fallback expanded state. 53059 * @return {number} block count 53060 */ 53061 function countBlocks(block, expandedState, draggedClientIds, isExpandedByDefault) { 53062 var _expandedState$block$; 53063 const isDragged = draggedClientIds?.includes(block.clientId); 53064 if (isDragged) { 53065 return 0; 53066 } 53067 const isExpanded = (_expandedState$block$ = expandedState[block.clientId]) !== null && _expandedState$block$ !== void 0 ? _expandedState$block$ : isExpandedByDefault; 53068 if (isExpanded) { 53069 return 1 + block.innerBlocks.reduce(countReducer(expandedState, draggedClientIds, isExpandedByDefault), 0); 53070 } 53071 return 1; 53072 } 53073 const countReducer = (expandedState, draggedClientIds, isExpandedByDefault) => (count, block) => { 53074 var _expandedState$block$2; 53075 const isDragged = draggedClientIds?.includes(block.clientId); 53076 if (isDragged) { 53077 return count; 53078 } 53079 const isExpanded = (_expandedState$block$2 = expandedState[block.clientId]) !== null && _expandedState$block$2 !== void 0 ? _expandedState$block$2 : isExpandedByDefault; 53080 if (isExpanded && block.innerBlocks.length > 0) { 53081 return count + countBlocks(block, expandedState, draggedClientIds, isExpandedByDefault); 53082 } 53083 return count + 1; 53084 }; 53085 const branch_noop = () => {}; 53086 function ListViewBranch(props) { 53087 const { 53088 blocks, 53089 selectBlock = branch_noop, 53090 showBlockMovers, 53091 selectedClientIds, 53092 level = 1, 53093 path = '', 53094 isBranchSelected = false, 53095 listPosition = 0, 53096 fixedListWindow, 53097 isExpanded, 53098 parentId, 53099 shouldShowInnerBlocks = true, 53100 isSyncedBranch = false, 53101 showAppender: showAppenderProp = true 53102 } = props; 53103 const parentBlockInformation = useBlockDisplayInformation(parentId); 53104 const syncedBranch = isSyncedBranch || !!parentBlockInformation?.isSynced; 53105 const canParentExpand = (0,external_wp_data_namespaceObject.useSelect)(select => { 53106 if (!parentId) { 53107 return true; 53108 } 53109 return select(store).canEditBlock(parentId); 53110 }, [parentId]); 53111 const { 53112 blockDropPosition, 53113 blockDropTargetIndex, 53114 firstDraggedBlockIndex, 53115 blockIndexes, 53116 expandedState, 53117 draggedClientIds 53118 } = useListViewContext(); 53119 if (!canParentExpand) { 53120 return null; 53121 } 53122 53123 // Only show the appender at the first level. 53124 const showAppender = showAppenderProp && level === 1; 53125 const filteredBlocks = blocks.filter(Boolean); 53126 const blockCount = filteredBlocks.length; 53127 // The appender means an extra row in List View, so add 1 to the row count. 53128 const rowCount = showAppender ? blockCount + 1 : blockCount; 53129 let nextPosition = listPosition; 53130 return (0,external_React_.createElement)(external_React_.Fragment, null, filteredBlocks.map((block, index) => { 53131 var _expandedState$client; 53132 const { 53133 clientId, 53134 innerBlocks 53135 } = block; 53136 if (index > 0) { 53137 nextPosition += countBlocks(filteredBlocks[index - 1], expandedState, draggedClientIds, isExpanded); 53138 } 53139 const isDragged = !!draggedClientIds?.includes(clientId); 53140 53141 // Determine the displacement of the block while dragging. This 53142 // works out whether the current block should be displaced up or 53143 // down, relative to the dragged blocks and the drop target. 53144 const { 53145 displacement, 53146 isAfterDraggedBlocks, 53147 isNesting 53148 } = getDragDisplacementValues({ 53149 blockIndexes, 53150 blockDropTargetIndex, 53151 blockDropPosition, 53152 clientId, 53153 firstDraggedBlockIndex, 53154 isDragged 53155 }); 53156 const { 53157 itemInView 53158 } = fixedListWindow; 53159 const blockInView = itemInView(nextPosition); 53160 const position = index + 1; 53161 const updatedPath = path.length > 0 ? `$path}_$position}` : `$position}`; 53162 const hasNestedBlocks = !!innerBlocks?.length; 53163 const shouldExpand = hasNestedBlocks && shouldShowInnerBlocks ? (_expandedState$client = expandedState[clientId]) !== null && _expandedState$client !== void 0 ? _expandedState$client : isExpanded : undefined; 53164 53165 // Make updates to the selected or dragged blocks synchronous, 53166 // but asynchronous for any other block. 53167 const isSelected = isClientIdSelected(clientId, selectedClientIds); 53168 const isSelectedBranch = isBranchSelected || isSelected && hasNestedBlocks; 53169 53170 // To avoid performance issues, we only render blocks that are in view, 53171 // or blocks that are selected or dragged. If a block is selected, 53172 // it is only counted if it is the first of the block selection. 53173 // This prevents the entire tree from being rendered when a branch is 53174 // selected, or a user selects all blocks, while still enabling scroll 53175 // into view behavior when selecting a block or opening the list view. 53176 const showBlock = isDragged || blockInView || isSelected && clientId === selectedClientIds[0]; 53177 return (0,external_React_.createElement)(external_wp_data_namespaceObject.AsyncModeProvider, { 53178 key: clientId, 53179 value: !isSelected 53180 }, showBlock && (0,external_React_.createElement)(list_view_block, { 53181 block: block, 53182 selectBlock: selectBlock, 53183 isSelected: isSelected, 53184 isBranchSelected: isSelectedBranch, 53185 isDragged: isDragged, 53186 level: level, 53187 position: position, 53188 rowCount: rowCount, 53189 siblingBlockCount: blockCount, 53190 showBlockMovers: showBlockMovers, 53191 path: updatedPath, 53192 isExpanded: isDragged ? false : shouldExpand, 53193 listPosition: nextPosition, 53194 selectedClientIds: selectedClientIds, 53195 isSyncedBranch: syncedBranch, 53196 displacement: displacement, 53197 isAfterDraggedBlocks: isAfterDraggedBlocks, 53198 isNesting: isNesting 53199 }), !showBlock && (0,external_React_.createElement)("tr", null, (0,external_React_.createElement)("td", { 53200 className: "block-editor-list-view-placeholder" 53201 })), hasNestedBlocks && shouldExpand && !isDragged && (0,external_React_.createElement)(ListViewBranch, { 53202 parentId: clientId, 53203 blocks: innerBlocks, 53204 selectBlock: selectBlock, 53205 showBlockMovers: showBlockMovers, 53206 level: level + 1, 53207 path: updatedPath, 53208 listPosition: nextPosition + 1, 53209 fixedListWindow: fixedListWindow, 53210 isBranchSelected: isSelectedBranch, 53211 selectedClientIds: selectedClientIds, 53212 isExpanded: isExpanded, 53213 isSyncedBranch: syncedBranch 53214 })); 53215 }), showAppender && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalTreeGridRow, { 53216 level: level, 53217 setSize: rowCount, 53218 positionInSet: rowCount, 53219 isExpanded: true 53220 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalTreeGridCell, null, treeGridCellProps => (0,external_React_.createElement)(Appender, { 53221 clientId: parentId, 53222 nestingLevel: level, 53223 blockCount: blockCount, 53224 ...treeGridCellProps 53225 })))); 53226 } 53227 /* harmony default export */ const branch = ((0,external_wp_element_namespaceObject.memo)(ListViewBranch)); 53228 53229 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/list-view/drop-indicator.js 53230 53231 /** 53232 * External dependencies 53233 */ 53234 53235 53236 /** 53237 * WordPress dependencies 53238 */ 53239 53240 53241 53242 53243 53244 /** 53245 * Internal dependencies 53246 */ 53247 53248 53249 53250 53251 function ListViewDropIndicatorPreview({ 53252 draggedBlockClientId, 53253 listViewRef, 53254 blockDropTarget 53255 }) { 53256 const blockInformation = useBlockDisplayInformation(draggedBlockClientId); 53257 const blockTitle = useBlockDisplayTitle({ 53258 clientId: draggedBlockClientId, 53259 context: 'list-view' 53260 }); 53261 const { 53262 rootClientId, 53263 clientId, 53264 dropPosition 53265 } = blockDropTarget || {}; 53266 const [rootBlockElement, blockElement] = (0,external_wp_element_namespaceObject.useMemo)(() => { 53267 if (!listViewRef.current) { 53268 return []; 53269 } 53270 53271 // The rootClientId will be defined whenever dropping into inner 53272 // block lists, but is undefined when dropping at the root level. 53273 const _rootBlockElement = rootClientId ? listViewRef.current.querySelector(`[data-block="$rootClientId}"]`) : undefined; 53274 53275 // The clientId represents the sibling block, the dragged block will 53276 // usually be inserted adjacent to it. It will be undefined when 53277 // dropping a block into an empty block list. 53278 const _blockElement = clientId ? listViewRef.current.querySelector(`[data-block="$clientId}"]`) : undefined; 53279 return [_rootBlockElement, _blockElement]; 53280 }, [listViewRef, rootClientId, clientId]); 53281 53282 // The targetElement is the element that the drop indicator will appear 53283 // before or after. When dropping into an empty block list, blockElement 53284 // is undefined, so the indicator will appear after the rootBlockElement. 53285 const targetElement = blockElement || rootBlockElement; 53286 const rtl = (0,external_wp_i18n_namespaceObject.isRTL)(); 53287 const getDropIndicatorWidth = (0,external_wp_element_namespaceObject.useCallback)((targetElementRect, indent) => { 53288 if (!targetElement) { 53289 return 0; 53290 } 53291 53292 // Default to assuming that the width of the drop indicator 53293 // should be the same as the target element. 53294 let width = targetElement.offsetWidth; 53295 53296 // In deeply nested lists, where a scrollbar is present, 53297 // the width of the drop indicator should be the width of 53298 // the scroll container, minus the distance from the left 53299 // edge of the scroll container to the left edge of the 53300 // target element. 53301 const scrollContainer = (0,external_wp_dom_namespaceObject.getScrollContainer)(targetElement, 'horizontal'); 53302 const ownerDocument = targetElement.ownerDocument; 53303 const windowScroll = scrollContainer === ownerDocument.body || scrollContainer === ownerDocument.documentElement; 53304 if (scrollContainer && !windowScroll) { 53305 const scrollContainerRect = scrollContainer.getBoundingClientRect(); 53306 const distanceBetweenContainerAndTarget = (0,external_wp_i18n_namespaceObject.isRTL)() ? scrollContainerRect.right - targetElementRect.right : targetElementRect.left - scrollContainerRect.left; 53307 const scrollContainerWidth = scrollContainer.clientWidth; 53308 if (scrollContainerWidth < width + distanceBetweenContainerAndTarget) { 53309 width = scrollContainerWidth - distanceBetweenContainerAndTarget; 53310 } 53311 53312 // LTR logic for ensuring the drop indicator does not extend 53313 // beyond the right edge of the scroll container. 53314 if (!rtl && targetElementRect.left + indent < scrollContainerRect.left) { 53315 width -= scrollContainerRect.left - targetElementRect.left; 53316 return width; 53317 } 53318 53319 // RTL logic for ensuring the drop indicator does not extend 53320 // beyond the right edge of the scroll container. 53321 if (rtl && targetElementRect.right - indent > scrollContainerRect.right) { 53322 width -= targetElementRect.right - scrollContainerRect.right; 53323 return width; 53324 } 53325 } 53326 53327 // Subtract the indent from the final width of the indicator. 53328 return width - indent; 53329 }, [rtl, targetElement]); 53330 const style = (0,external_wp_element_namespaceObject.useMemo)(() => { 53331 if (!targetElement) { 53332 return {}; 53333 } 53334 const targetElementRect = targetElement.getBoundingClientRect(); 53335 return { 53336 width: getDropIndicatorWidth(targetElementRect, 0) 53337 }; 53338 }, [getDropIndicatorWidth, targetElement]); 53339 const horizontalScrollOffsetStyle = (0,external_wp_element_namespaceObject.useMemo)(() => { 53340 if (!targetElement) { 53341 return {}; 53342 } 53343 const scrollContainer = (0,external_wp_dom_namespaceObject.getScrollContainer)(targetElement); 53344 const ownerDocument = targetElement.ownerDocument; 53345 const windowScroll = scrollContainer === ownerDocument.body || scrollContainer === ownerDocument.documentElement; 53346 if (scrollContainer && !windowScroll) { 53347 const scrollContainerRect = scrollContainer.getBoundingClientRect(); 53348 const targetElementRect = targetElement.getBoundingClientRect(); 53349 const distanceBetweenContainerAndTarget = rtl ? scrollContainerRect.right - targetElementRect.right : targetElementRect.left - scrollContainerRect.left; 53350 if (!rtl && scrollContainerRect.left > targetElementRect.left) { 53351 return { 53352 transform: `translateX( $distanceBetweenContainerAndTarget}px )` 53353 }; 53354 } 53355 if (rtl && scrollContainerRect.right < targetElementRect.right) { 53356 return { 53357 transform: `translateX( $distanceBetweenContainerAndTarget * -1}px )` 53358 }; 53359 } 53360 } 53361 return {}; 53362 }, [rtl, targetElement]); 53363 const ariaLevel = (0,external_wp_element_namespaceObject.useMemo)(() => { 53364 if (!rootBlockElement) { 53365 return 1; 53366 } 53367 const _ariaLevel = parseInt(rootBlockElement.getAttribute('aria-level'), 10); 53368 return _ariaLevel ? _ariaLevel + 1 : 1; 53369 }, [rootBlockElement]); 53370 const hasAdjacentSelectedBranch = (0,external_wp_element_namespaceObject.useMemo)(() => { 53371 if (!targetElement) { 53372 return false; 53373 } 53374 return targetElement.classList.contains('is-branch-selected'); 53375 }, [targetElement]); 53376 const popoverAnchor = (0,external_wp_element_namespaceObject.useMemo)(() => { 53377 const isValidDropPosition = dropPosition === 'top' || dropPosition === 'bottom' || dropPosition === 'inside'; 53378 if (!targetElement || !isValidDropPosition) { 53379 return undefined; 53380 } 53381 return { 53382 contextElement: targetElement, 53383 getBoundingClientRect() { 53384 const rect = targetElement.getBoundingClientRect(); 53385 // In RTL languages, the drop indicator should be positioned 53386 // to the left of the target element, with the width of the 53387 // indicator determining the indent at the right edge of the 53388 // target element. In LTR languages, the drop indicator should 53389 // end at the right edge of the target element, with the indent 53390 // added to the position of the left edge of the target element. 53391 // let left = rtl ? rect.left : rect.left + indent; 53392 let left = rect.left; 53393 let top = 0; 53394 53395 // In deeply nested lists, where a scrollbar is present, 53396 // the width of the drop indicator should be the width of 53397 // the visible area of the scroll container. Additionally, 53398 // the left edge of the drop indicator line needs to be 53399 // offset by the distance the left edge of the target element 53400 // and the left edge of the scroll container. The ensures 53401 // that the drop indicator position never breaks out of the 53402 // visible area of the scroll container. 53403 const scrollContainer = (0,external_wp_dom_namespaceObject.getScrollContainer)(targetElement, 'horizontal'); 53404 const doc = targetElement.ownerDocument; 53405 const windowScroll = scrollContainer === doc.body || scrollContainer === doc.documentElement; 53406 53407 // If the scroll container is not the window, offset the left position, if need be. 53408 if (scrollContainer && !windowScroll) { 53409 const scrollContainerRect = scrollContainer.getBoundingClientRect(); 53410 53411 // In RTL languages, a vertical scrollbar is present on the 53412 // left edge of the scroll container. The width of the 53413 // scrollbar needs to be accounted for when positioning the 53414 // drop indicator. 53415 const scrollbarWidth = rtl ? scrollContainer.offsetWidth - scrollContainer.clientWidth : 0; 53416 if (left < scrollContainerRect.left + scrollbarWidth) { 53417 left = scrollContainerRect.left + scrollbarWidth; 53418 } 53419 } 53420 if (dropPosition === 'top') { 53421 top = rect.top - rect.height * 2; 53422 } else { 53423 // `dropPosition` is either `bottom` or `inside` 53424 top = rect.top; 53425 } 53426 const width = getDropIndicatorWidth(rect, 0); 53427 const height = rect.height; 53428 return new window.DOMRect(left, top, width, height); 53429 } 53430 }; 53431 }, [targetElement, dropPosition, getDropIndicatorWidth, rtl]); 53432 if (!targetElement) { 53433 return null; 53434 } 53435 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Popover, { 53436 animate: false, 53437 anchor: popoverAnchor, 53438 focusOnMount: false, 53439 className: "block-editor-list-view-drop-indicator--preview", 53440 variant: "unstyled", 53441 flip: false, 53442 resize: true 53443 }, (0,external_React_.createElement)("div", { 53444 style: style, 53445 className: classnames_default()('block-editor-list-view-drop-indicator__line', { 53446 'block-editor-list-view-drop-indicator__line--darker': hasAdjacentSelectedBranch 53447 }) 53448 }, (0,external_React_.createElement)("div", { 53449 className: "block-editor-list-view-leaf", 53450 "aria-level": ariaLevel 53451 }, (0,external_React_.createElement)("div", { 53452 className: classnames_default()('block-editor-list-view-block-select-button', 'block-editor-list-view-block-contents'), 53453 style: horizontalScrollOffsetStyle 53454 }, (0,external_React_.createElement)(ListViewExpander, { 53455 onClick: () => {} 53456 }), (0,external_React_.createElement)(block_icon, { 53457 icon: blockInformation?.icon, 53458 showColors: true, 53459 context: "list-view" 53460 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, { 53461 alignment: "center", 53462 className: "block-editor-list-view-block-select-button__label-wrapper", 53463 justify: "flex-start", 53464 spacing: 1 53465 }, (0,external_React_.createElement)("span", { 53466 className: "block-editor-list-view-block-select-button__title" 53467 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalTruncate, { 53468 ellipsizeMode: "auto" 53469 }, blockTitle)))), (0,external_React_.createElement)("div", { 53470 className: "block-editor-list-view-block__menu-cell" 53471 })))); 53472 } 53473 53474 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/list-view/use-block-selection.js 53475 /** 53476 * WordPress dependencies 53477 */ 53478 53479 53480 53481 53482 53483 53484 53485 /** 53486 * Internal dependencies 53487 */ 53488 53489 53490 function useBlockSelection() { 53491 const { 53492 clearSelectedBlock, 53493 multiSelect, 53494 selectBlock 53495 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 53496 const { 53497 getBlockName, 53498 getBlockParents, 53499 getBlockSelectionStart, 53500 getSelectedBlockClientIds, 53501 hasMultiSelection, 53502 hasSelectedBlock 53503 } = (0,external_wp_data_namespaceObject.useSelect)(store); 53504 const { 53505 getBlockType 53506 } = (0,external_wp_data_namespaceObject.useSelect)(external_wp_blocks_namespaceObject.store); 53507 const updateBlockSelection = (0,external_wp_element_namespaceObject.useCallback)(async (event, clientId, destinationClientId, focusPosition) => { 53508 if (!event?.shiftKey && event?.keyCode !== external_wp_keycodes_namespaceObject.ESCAPE) { 53509 selectBlock(clientId, focusPosition); 53510 return; 53511 } 53512 53513 // To handle multiple block selection via the `SHIFT` key, prevent 53514 // the browser default behavior of opening the link in a new window. 53515 event.preventDefault(); 53516 const isOnlyDeselection = event.type === 'keydown' && event.keyCode === external_wp_keycodes_namespaceObject.ESCAPE; 53517 const isKeyPress = event.type === 'keydown' && (event.keyCode === external_wp_keycodes_namespaceObject.UP || event.keyCode === external_wp_keycodes_namespaceObject.DOWN || event.keyCode === external_wp_keycodes_namespaceObject.HOME || event.keyCode === external_wp_keycodes_namespaceObject.END); 53518 53519 // Handle clicking on a block when no blocks are selected, and return early. 53520 if (!isKeyPress && !hasSelectedBlock() && !hasMultiSelection()) { 53521 selectBlock(clientId, null); 53522 return; 53523 } 53524 const selectedBlocks = getSelectedBlockClientIds(); 53525 const clientIdWithParents = [...getBlockParents(clientId), clientId]; 53526 if (isOnlyDeselection || isKeyPress && !selectedBlocks.some(blockId => clientIdWithParents.includes(blockId))) { 53527 // Ensure that shift-selecting blocks via the keyboard only 53528 // expands the current selection if focusing over already 53529 // selected blocks. Otherwise, clear the selection so that 53530 // a user can create a new selection entirely by keyboard. 53531 await clearSelectedBlock(); 53532 } 53533 53534 // Update selection, if not only clearing the selection. 53535 if (!isOnlyDeselection) { 53536 let startTarget = getBlockSelectionStart(); 53537 let endTarget = clientId; 53538 53539 // Handle keyboard behavior for selecting multiple blocks. 53540 if (isKeyPress) { 53541 if (!hasSelectedBlock() && !hasMultiSelection()) { 53542 // Set the starting point of the selection to the currently 53543 // focused block, if there are no blocks currently selected. 53544 // This ensures that as the selection is expanded or contracted, 53545 // the starting point of the selection is anchored to that block. 53546 startTarget = clientId; 53547 } 53548 if (destinationClientId) { 53549 // If the user presses UP or DOWN, we want to ensure that the block they're 53550 // moving to is the target for selection, and not the currently focused one. 53551 endTarget = destinationClientId; 53552 } 53553 } 53554 const startParents = getBlockParents(startTarget); 53555 const endParents = getBlockParents(endTarget); 53556 const { 53557 start, 53558 end 53559 } = getCommonDepthClientIds(startTarget, endTarget, startParents, endParents); 53560 await multiSelect(start, end, null); 53561 } 53562 53563 // Announce deselected block, or number of deselected blocks if 53564 // the total number of blocks deselected is greater than one. 53565 const updatedSelectedBlocks = getSelectedBlockClientIds(); 53566 53567 // If the selection is greater than 1 and the Home or End keys 53568 // were used to generate the selection, then skip announcing the 53569 // deselected blocks. 53570 if ((event.keyCode === external_wp_keycodes_namespaceObject.HOME || event.keyCode === external_wp_keycodes_namespaceObject.END) && updatedSelectedBlocks.length > 1) { 53571 return; 53572 } 53573 const selectionDiff = selectedBlocks.filter(blockId => !updatedSelectedBlocks.includes(blockId)); 53574 let label; 53575 if (selectionDiff.length === 1) { 53576 const title = getBlockType(getBlockName(selectionDiff[0]))?.title; 53577 if (title) { 53578 label = (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: block name */ 53579 (0,external_wp_i18n_namespaceObject.__)('%s deselected.'), title); 53580 } 53581 } else if (selectionDiff.length > 1) { 53582 label = (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: number of deselected blocks */ 53583 (0,external_wp_i18n_namespaceObject.__)('%s blocks deselected.'), selectionDiff.length); 53584 } 53585 if (label) { 53586 (0,external_wp_a11y_namespaceObject.speak)(label, 'assertive'); 53587 } 53588 }, [clearSelectedBlock, getBlockName, getBlockType, getBlockParents, getBlockSelectionStart, getSelectedBlockClientIds, hasMultiSelection, hasSelectedBlock, multiSelect, selectBlock]); 53589 return { 53590 updateBlockSelection 53591 }; 53592 } 53593 53594 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/list-view/use-list-view-block-indexes.js 53595 /** 53596 * WordPress dependencies 53597 */ 53598 53599 function useListViewBlockIndexes(blocks) { 53600 const blockIndexes = (0,external_wp_element_namespaceObject.useMemo)(() => { 53601 const indexes = {}; 53602 let currentGlobalIndex = 0; 53603 const traverseBlocks = blockList => { 53604 blockList.forEach(block => { 53605 indexes[block.clientId] = currentGlobalIndex; 53606 currentGlobalIndex++; 53607 if (block.innerBlocks.length > 0) { 53608 traverseBlocks(block.innerBlocks); 53609 } 53610 }); 53611 }; 53612 traverseBlocks(blocks); 53613 return indexes; 53614 }, [blocks]); 53615 return blockIndexes; 53616 } 53617 53618 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/list-view/use-list-view-client-ids.js 53619 /** 53620 * WordPress dependencies 53621 */ 53622 53623 53624 53625 /** 53626 * Internal dependencies 53627 */ 53628 53629 53630 function useListViewClientIds({ 53631 blocks, 53632 rootClientId 53633 }) { 53634 return (0,external_wp_data_namespaceObject.useSelect)(select => { 53635 const { 53636 getDraggedBlockClientIds, 53637 getSelectedBlockClientIds, 53638 getEnabledClientIdsTree 53639 } = unlock(select(store)); 53640 return { 53641 selectedClientIds: getSelectedBlockClientIds(), 53642 draggedClientIds: getDraggedBlockClientIds(), 53643 clientIdsTree: blocks !== null && blocks !== void 0 ? blocks : getEnabledClientIdsTree(rootClientId) 53644 }; 53645 }, [blocks, rootClientId]); 53646 } 53647 53648 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/list-view/use-list-view-drop-zone.js 53649 /** 53650 * WordPress dependencies 53651 */ 53652 53653 53654 53655 53656 53657 /** 53658 * Internal dependencies 53659 */ 53660 53661 53662 53663 53664 /** @typedef {import('../../utils/math').WPPoint} WPPoint */ 53665 53666 /** 53667 * The type of a drag event. 53668 * 53669 * @typedef {'default'|'file'|'html'} WPDragEventType 53670 */ 53671 53672 /** 53673 * An object representing data for blocks in the DOM used by drag and drop. 53674 * 53675 * @typedef {Object} WPListViewDropZoneBlock 53676 * @property {string} clientId The client id for the block. 53677 * @property {string} rootClientId The root client id for the block. 53678 * @property {number} blockIndex The block's index. 53679 * @property {Element} element The DOM element representing the block. 53680 * @property {number} innerBlockCount The number of inner blocks the block has. 53681 * @property {boolean} isDraggedBlock Whether the block is currently being dragged. 53682 * @property {boolean} isExpanded Whether the block is expanded in the UI. 53683 * @property {boolean} canInsertDraggedBlocksAsSibling Whether the dragged block can be a sibling of this block. 53684 * @property {boolean} canInsertDraggedBlocksAsChild Whether the dragged block can be a child of this block. 53685 */ 53686 53687 /** 53688 * An array representing data for blocks in the DOM used by drag and drop. 53689 * 53690 * @typedef {WPListViewDropZoneBlock[]} WPListViewDropZoneBlocks 53691 */ 53692 53693 /** 53694 * An object containing details of a drop target. 53695 * 53696 * @typedef {Object} WPListViewDropZoneTarget 53697 * @property {string} blockIndex The insertion index. 53698 * @property {string} rootClientId The root client id for the block. 53699 * @property {string|undefined} clientId The client id for the block. 53700 * @property {'top'|'bottom'|'inside'} dropPosition The position relative to the block that the user is dropping to. 53701 * 'inside' refers to nesting as an inner block. 53702 */ 53703 53704 // When the indentation level, the corresponding left margin in `style.scss` 53705 // must be updated as well to ensure the drop zone is aligned with the indentation. 53706 const NESTING_LEVEL_INDENTATION = 28; 53707 53708 /** 53709 * Determines whether the user is positioning the dragged block to be 53710 * moved up to a parent level. 53711 * 53712 * Determined based on nesting level indentation of the current block. 53713 * 53714 * @param {WPPoint} point The point representing the cursor position when dragging. 53715 * @param {DOMRect} rect The rectangle. 53716 * @param {number} nestingLevel The nesting level of the block. 53717 * @param {boolean} rtl Whether the editor is in RTL mode. 53718 * @return {boolean} Whether the gesture is an upward gesture. 53719 */ 53720 function isUpGesture(point, rect, nestingLevel = 1, rtl = false) { 53721 // If the block is nested, and the user is dragging to the bottom 53722 // left of the block (or bottom right in RTL languages), then it is an upward gesture. 53723 const blockIndentPosition = rtl ? rect.right - nestingLevel * NESTING_LEVEL_INDENTATION : rect.left + nestingLevel * NESTING_LEVEL_INDENTATION; 53724 return rtl ? point.x > blockIndentPosition : point.x < blockIndentPosition; 53725 } 53726 53727 /** 53728 * Returns how many nesting levels up the user is attempting to drag to. 53729 * 53730 * The relative parent level is calculated based on how far 53731 * the cursor is from the provided nesting level (e.g. of a candidate block 53732 * that the user is hovering over). The nesting level is considered "desired" 53733 * because it is not guaranteed that the user will be able to drag to the desired level. 53734 * 53735 * The returned integer can be used to access an ascending array 53736 * of parent blocks, where the first item is the block the user 53737 * is hovering over, and the last item is the root block. 53738 * 53739 * @param {WPPoint} point The point representing the cursor position when dragging. 53740 * @param {DOMRect} rect The rectangle. 53741 * @param {number} nestingLevel The nesting level of the block. 53742 * @param {boolean} rtl Whether the editor is in RTL mode. 53743 * @return {number} The desired relative parent level. 53744 */ 53745 function getDesiredRelativeParentLevel(point, rect, nestingLevel = 1, rtl = false) { 53746 // In RTL languages, the block indent position is from the right edge of the block. 53747 // In LTR languages, the block indent position is from the left edge of the block. 53748 const blockIndentPosition = rtl ? rect.right - nestingLevel * NESTING_LEVEL_INDENTATION : rect.left + nestingLevel * NESTING_LEVEL_INDENTATION; 53749 const distanceBetweenPointAndBlockIndentPosition = rtl ? blockIndentPosition - point.x : point.x - blockIndentPosition; 53750 const desiredParentLevel = Math.round(distanceBetweenPointAndBlockIndentPosition / NESTING_LEVEL_INDENTATION); 53751 return Math.abs(desiredParentLevel); 53752 } 53753 53754 /** 53755 * Returns an array of the parent blocks of the block the user is dropping to. 53756 * 53757 * @param {WPListViewDropZoneBlock} candidateBlockData The block the user is dropping to. 53758 * @param {WPListViewDropZoneBlocks} blocksData Data about the blocks in list view. 53759 * @return {WPListViewDropZoneBlocks} An array of block parents, including the block the user is dropping to. 53760 */ 53761 function getCandidateBlockParents(candidateBlockData, blocksData) { 53762 const candidateBlockParents = []; 53763 let currentBlockData = candidateBlockData; 53764 while (currentBlockData) { 53765 candidateBlockParents.push({ 53766 ...currentBlockData 53767 }); 53768 currentBlockData = blocksData.find(blockData => blockData.clientId === currentBlockData.rootClientId); 53769 } 53770 return candidateBlockParents; 53771 } 53772 53773 /** 53774 * Given a list of blocks data and a block index, return the next non-dragged 53775 * block. This is used to determine the block that the user is dropping to, 53776 * while ignoring the dragged block. 53777 * 53778 * @param {WPListViewDropZoneBlocks} blocksData Data about the blocks in list view. 53779 * @param {number} index The index to begin searching from. 53780 * @return {WPListViewDropZoneBlock | undefined} The next non-dragged block. 53781 */ 53782 function getNextNonDraggedBlock(blocksData, index) { 53783 const nextBlockData = blocksData[index + 1]; 53784 if (nextBlockData && nextBlockData.isDraggedBlock) { 53785 return getNextNonDraggedBlock(blocksData, index + 1); 53786 } 53787 return nextBlockData; 53788 } 53789 53790 /** 53791 * Determines whether the user positioning the dragged block to nest as an 53792 * inner block. 53793 * 53794 * Determined based on nesting level indentation of the current block, plus 53795 * the indentation of the next level of nesting. The vertical position of the 53796 * cursor must also be within the block. 53797 * 53798 * @param {WPPoint} point The point representing the cursor position when dragging. 53799 * @param {DOMRect} rect The rectangle. 53800 * @param {number} nestingLevel The nesting level of the block. 53801 * @param {boolean} rtl Whether the editor is in RTL mode. 53802 */ 53803 function isNestingGesture(point, rect, nestingLevel = 1, rtl = false) { 53804 const blockIndentPosition = rtl ? rect.right - nestingLevel * NESTING_LEVEL_INDENTATION : rect.left + nestingLevel * NESTING_LEVEL_INDENTATION; 53805 const isNestingHorizontalGesture = rtl ? point.x < blockIndentPosition - NESTING_LEVEL_INDENTATION : point.x > blockIndentPosition + NESTING_LEVEL_INDENTATION; 53806 return isNestingHorizontalGesture && point.y < rect.bottom; 53807 } 53808 53809 // Block navigation is always a vertical list, so only allow dropping 53810 // to the above or below a block. 53811 const ALLOWED_DROP_EDGES = ['top', 'bottom']; 53812 53813 /** 53814 * Given blocks data and the cursor position, compute the drop target. 53815 * 53816 * @param {WPListViewDropZoneBlocks} blocksData Data about the blocks in list view. 53817 * @param {WPPoint} position The point representing the cursor position when dragging. 53818 * @param {boolean} rtl Whether the editor is in RTL mode. 53819 * 53820 * @return {WPListViewDropZoneTarget | undefined} An object containing data about the drop target. 53821 */ 53822 function getListViewDropTarget(blocksData, position, rtl = false) { 53823 let candidateEdge; 53824 let candidateBlockData; 53825 let candidateDistance; 53826 let candidateRect; 53827 let candidateBlockIndex; 53828 for (let i = 0; i < blocksData.length; i++) { 53829 const blockData = blocksData[i]; 53830 if (blockData.isDraggedBlock) { 53831 continue; 53832 } 53833 const rect = blockData.element.getBoundingClientRect(); 53834 const [distance, edge] = getDistanceToNearestEdge(position, rect, ALLOWED_DROP_EDGES); 53835 const isCursorWithinBlock = isPointContainedByRect(position, rect); 53836 if (candidateDistance === undefined || distance < candidateDistance || isCursorWithinBlock) { 53837 candidateDistance = distance; 53838 const index = blocksData.indexOf(blockData); 53839 const previousBlockData = blocksData[index - 1]; 53840 53841 // If dragging near the top of a block and the preceding block 53842 // is at the same level, use the preceding block as the candidate 53843 // instead, as later it makes determining a nesting drop easier. 53844 if (edge === 'top' && previousBlockData && previousBlockData.rootClientId === blockData.rootClientId && !previousBlockData.isDraggedBlock) { 53845 candidateBlockData = previousBlockData; 53846 candidateEdge = 'bottom'; 53847 candidateRect = previousBlockData.element.getBoundingClientRect(); 53848 candidateBlockIndex = index - 1; 53849 } else { 53850 candidateBlockData = blockData; 53851 candidateEdge = edge; 53852 candidateRect = rect; 53853 candidateBlockIndex = index; 53854 } 53855 53856 // If the mouse position is within the block, break early 53857 // as the user would intend to drop either before or after 53858 // this block. 53859 // 53860 // This solves an issue where some rows in the list view 53861 // tree overlap slightly due to sub-pixel rendering. 53862 if (isCursorWithinBlock) { 53863 break; 53864 } 53865 } 53866 } 53867 if (!candidateBlockData) { 53868 return; 53869 } 53870 const candidateBlockParents = getCandidateBlockParents(candidateBlockData, blocksData); 53871 const isDraggingBelow = candidateEdge === 'bottom'; 53872 53873 // If the user is dragging towards the bottom of the block check whether 53874 // they might be trying to nest the block as a child. 53875 // If the block already has inner blocks, and is expanded, this should be treated 53876 // as nesting since the next block in the tree will be the first child. 53877 // However, if the block is collapsed, dragging beneath the block should 53878 // still be allowed, as the next visible block in the tree will be a sibling. 53879 if (isDraggingBelow && candidateBlockData.canInsertDraggedBlocksAsChild && (candidateBlockData.innerBlockCount > 0 && candidateBlockData.isExpanded || isNestingGesture(position, candidateRect, candidateBlockParents.length, rtl))) { 53880 // If the block is expanded, insert the block as the first child. 53881 // Otherwise, for collapsed blocks, insert the block as the last child. 53882 const newBlockIndex = candidateBlockData.isExpanded ? 0 : candidateBlockData.innerBlockCount || 0; 53883 return { 53884 rootClientId: candidateBlockData.clientId, 53885 clientId: candidateBlockData.clientId, 53886 blockIndex: newBlockIndex, 53887 dropPosition: 'inside' 53888 }; 53889 } 53890 53891 // If the user is dragging towards the bottom of the block check whether 53892 // they might be trying to move the block to be at a parent level. 53893 if (isDraggingBelow && candidateBlockData.rootClientId && isUpGesture(position, candidateRect, candidateBlockParents.length, rtl)) { 53894 const nextBlock = getNextNonDraggedBlock(blocksData, candidateBlockIndex); 53895 const currentLevel = candidateBlockData.nestingLevel; 53896 const nextLevel = nextBlock ? nextBlock.nestingLevel : 1; 53897 if (currentLevel && nextLevel) { 53898 // Determine the desired relative level of the block to be dropped. 53899 const desiredRelativeLevel = getDesiredRelativeParentLevel(position, candidateRect, candidateBlockParents.length, rtl); 53900 const targetParentIndex = Math.max(Math.min(desiredRelativeLevel, currentLevel - nextLevel), 0); 53901 if (candidateBlockParents[targetParentIndex]) { 53902 // Default to the block index of the candidate block. 53903 let newBlockIndex = candidateBlockData.blockIndex; 53904 53905 // If the next block is at the same level, use that as the default 53906 // block index. This ensures that the block is dropped in the correct 53907 // position when dragging to the bottom of a block. 53908 if (candidateBlockParents[targetParentIndex].nestingLevel === nextBlock?.nestingLevel) { 53909 newBlockIndex = nextBlock?.blockIndex; 53910 } else { 53911 // Otherwise, search from the current block index back 53912 // to find the last block index within the same target parent. 53913 for (let i = candidateBlockIndex; i >= 0; i--) { 53914 const blockData = blocksData[i]; 53915 if (blockData.rootClientId === candidateBlockParents[targetParentIndex].rootClientId) { 53916 newBlockIndex = blockData.blockIndex + 1; 53917 break; 53918 } 53919 } 53920 } 53921 return { 53922 rootClientId: candidateBlockParents[targetParentIndex].rootClientId, 53923 clientId: candidateBlockData.clientId, 53924 blockIndex: newBlockIndex, 53925 dropPosition: candidateEdge 53926 }; 53927 } 53928 } 53929 } 53930 53931 // If dropping as a sibling, but block cannot be inserted in 53932 // this context, return early. 53933 if (!candidateBlockData.canInsertDraggedBlocksAsSibling) { 53934 return; 53935 } 53936 const offset = isDraggingBelow ? 1 : 0; 53937 return { 53938 rootClientId: candidateBlockData.rootClientId, 53939 clientId: candidateBlockData.clientId, 53940 blockIndex: candidateBlockData.blockIndex + offset, 53941 dropPosition: candidateEdge 53942 }; 53943 } 53944 53945 // Throttle options need to be defined outside of the hook to avoid 53946 // re-creating the object on every render. This is due to a limitation 53947 // of the `useThrottle` hook, where the options object is included 53948 // in the dependency array for memoization. 53949 const EXPAND_THROTTLE_OPTIONS = { 53950 leading: false, 53951 // Don't call the function immediately on the first call. 53952 trailing: true // Do call the function on the last call. 53953 }; 53954 53955 /** 53956 * A react hook for implementing a drop zone in list view. 53957 * 53958 * @param {Object} props Named parameters. 53959 * @param {?HTMLElement} [props.dropZoneElement] Optional element to be used as the drop zone. 53960 * @param {Object} [props.expandedState] The expanded state of the blocks in the list view. 53961 * @param {Function} [props.setExpandedState] Function to set the expanded state of a list of block clientIds. 53962 * 53963 * @return {WPListViewDropZoneTarget} The drop target. 53964 */ 53965 function useListViewDropZone({ 53966 dropZoneElement, 53967 expandedState, 53968 setExpandedState 53969 }) { 53970 const { 53971 getBlockRootClientId, 53972 getBlockIndex, 53973 getBlockCount, 53974 getDraggedBlockClientIds, 53975 canInsertBlocks 53976 } = (0,external_wp_data_namespaceObject.useSelect)(store); 53977 const [target, setTarget] = (0,external_wp_element_namespaceObject.useState)(); 53978 const { 53979 rootClientId: targetRootClientId, 53980 blockIndex: targetBlockIndex 53981 } = target || {}; 53982 const onBlockDrop = useOnBlockDrop(targetRootClientId, targetBlockIndex); 53983 const rtl = (0,external_wp_i18n_namespaceObject.isRTL)(); 53984 const previousRootClientId = (0,external_wp_compose_namespaceObject.usePrevious)(targetRootClientId); 53985 const maybeExpandBlock = (0,external_wp_element_namespaceObject.useCallback)((_expandedState, _target) => { 53986 // If the user is attempting to drop a block inside a collapsed block, 53987 // that is, using a nesting gesture flagged by 'inside' dropPosition, 53988 // expand the block within the list view, if it isn't already. 53989 const { 53990 rootClientId 53991 } = _target || {}; 53992 if (!rootClientId) { 53993 return; 53994 } 53995 if (_target?.dropPosition === 'inside' && !_expandedState[rootClientId]) { 53996 setExpandedState({ 53997 type: 'expand', 53998 clientIds: [rootClientId] 53999 }); 54000 } 54001 }, [setExpandedState]); 54002 54003 // Throttle the maybeExpandBlock function to avoid expanding the block 54004 // too quickly when the user is dragging over the block. This is to 54005 // avoid expanding the block when the user is just passing over it. 54006 const throttledMaybeExpandBlock = (0,external_wp_compose_namespaceObject.useThrottle)(maybeExpandBlock, 500, EXPAND_THROTTLE_OPTIONS); 54007 (0,external_wp_element_namespaceObject.useEffect)(() => { 54008 if (target?.dropPosition !== 'inside' || previousRootClientId !== target?.rootClientId) { 54009 throttledMaybeExpandBlock.cancel(); 54010 return; 54011 } 54012 throttledMaybeExpandBlock(expandedState, target); 54013 }, [expandedState, previousRootClientId, target, throttledMaybeExpandBlock]); 54014 const draggedBlockClientIds = getDraggedBlockClientIds(); 54015 const throttled = (0,external_wp_compose_namespaceObject.useThrottle)((0,external_wp_element_namespaceObject.useCallback)((event, currentTarget) => { 54016 const position = { 54017 x: event.clientX, 54018 y: event.clientY 54019 }; 54020 const isBlockDrag = !!draggedBlockClientIds?.length; 54021 const blockElements = Array.from(currentTarget.querySelectorAll('[data-block]')); 54022 const blocksData = blockElements.map(blockElement => { 54023 const clientId = blockElement.dataset.block; 54024 const isExpanded = blockElement.dataset.expanded === 'true'; 54025 const isDraggedBlock = blockElement.classList.contains('is-dragging'); 54026 54027 // Get nesting level from `aria-level` attribute because Firefox does not support `element.ariaLevel`. 54028 const nestingLevel = parseInt(blockElement.getAttribute('aria-level'), 10); 54029 const rootClientId = getBlockRootClientId(clientId); 54030 return { 54031 clientId, 54032 isExpanded, 54033 rootClientId, 54034 blockIndex: getBlockIndex(clientId), 54035 element: blockElement, 54036 nestingLevel: nestingLevel || undefined, 54037 isDraggedBlock: isBlockDrag ? isDraggedBlock : false, 54038 innerBlockCount: getBlockCount(clientId), 54039 canInsertDraggedBlocksAsSibling: isBlockDrag ? canInsertBlocks(draggedBlockClientIds, rootClientId) : true, 54040 canInsertDraggedBlocksAsChild: isBlockDrag ? canInsertBlocks(draggedBlockClientIds, clientId) : true 54041 }; 54042 }); 54043 const newTarget = getListViewDropTarget(blocksData, position, rtl); 54044 if (newTarget) { 54045 setTarget(newTarget); 54046 } 54047 }, [canInsertBlocks, draggedBlockClientIds, getBlockCount, getBlockIndex, getBlockRootClientId, rtl]), 50); 54048 const ref = (0,external_wp_compose_namespaceObject.__experimentalUseDropZone)({ 54049 dropZoneElement, 54050 onDrop(event) { 54051 if (target) { 54052 onBlockDrop(event); 54053 } 54054 }, 54055 onDragLeave() { 54056 throttled.cancel(); 54057 // Use `null` value to indicate that the drop target is not valid, 54058 // but that the drag is still active. This allows for styling rules 54059 // that are active only when a user drags outside of the list view. 54060 setTarget(null); 54061 }, 54062 onDragOver(event) { 54063 // `currentTarget` is only available while the event is being 54064 // handled, so get it now and pass it to the thottled function. 54065 // https://developer.mozilla.org/en-US/docs/Web/API/Event/currentTarget 54066 throttled(event, event.currentTarget); 54067 }, 54068 onDragEnd() { 54069 throttled.cancel(); 54070 // Use `undefined` value to indicate that the drag has concluded. 54071 // This allows styling rules that are active only when a user is 54072 // dragging to be removed. 54073 setTarget(undefined); 54074 } 54075 }); 54076 return { 54077 ref, 54078 target 54079 }; 54080 } 54081 54082 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/list-view/use-list-view-expand-selected-item.js 54083 /** 54084 * WordPress dependencies 54085 */ 54086 54087 54088 54089 /** 54090 * Internal dependencies 54091 */ 54092 54093 function useListViewExpandSelectedItem({ 54094 firstSelectedBlockClientId, 54095 setExpandedState 54096 }) { 54097 const [selectedTreeId, setSelectedTreeId] = (0,external_wp_element_namespaceObject.useState)(null); 54098 const { 54099 selectedBlockParentClientIds 54100 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 54101 const { 54102 getBlockParents 54103 } = select(store); 54104 return { 54105 selectedBlockParentClientIds: getBlockParents(firstSelectedBlockClientId, false) 54106 }; 54107 }, [firstSelectedBlockClientId]); 54108 54109 // Expand tree when a block is selected. 54110 (0,external_wp_element_namespaceObject.useEffect)(() => { 54111 // If the selectedTreeId is the same as the selected block, 54112 // it means that the block was selected using the block list tree. 54113 if (selectedTreeId === firstSelectedBlockClientId) { 54114 return; 54115 } 54116 54117 // If the selected block has parents, get the top-level parent. 54118 if (selectedBlockParentClientIds?.length) { 54119 // If the selected block has parents, 54120 // expand the tree branch. 54121 setExpandedState({ 54122 type: 'expand', 54123 clientIds: selectedBlockParentClientIds 54124 }); 54125 } 54126 }, [firstSelectedBlockClientId, selectedBlockParentClientIds, selectedTreeId, setExpandedState]); 54127 return { 54128 setSelectedTreeId 54129 }; 54130 } 54131 54132 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/list-view/use-clipboard-handler.js 54133 /** 54134 * WordPress dependencies 54135 */ 54136 54137 54138 54139 /** 54140 * Internal dependencies 54141 */ 54142 54143 54144 54145 54146 54147 // This hook borrows from useClipboardHandler in ../writing-flow/use-clipboard-handler.js 54148 // and adds behaviour for the list view, while skipping partial selection. 54149 function use_clipboard_handler_useClipboardHandler({ 54150 selectBlock 54151 }) { 54152 const registry = (0,external_wp_data_namespaceObject.useRegistry)(); 54153 const { 54154 getBlockOrder, 54155 getBlockRootClientId, 54156 getBlocksByClientId, 54157 getPreviousBlockClientId, 54158 getSelectedBlockClientIds, 54159 getSettings, 54160 canInsertBlockType, 54161 canRemoveBlocks 54162 } = (0,external_wp_data_namespaceObject.useSelect)(store); 54163 const { 54164 flashBlock, 54165 removeBlocks, 54166 replaceBlocks, 54167 insertBlocks 54168 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 54169 const notifyCopy = useNotifyCopy(); 54170 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 54171 function updateFocusAndSelection(focusClientId, shouldSelectBlock) { 54172 if (shouldSelectBlock) { 54173 selectBlock(undefined, focusClientId, null, null); 54174 } 54175 focusListItem(focusClientId, node); 54176 } 54177 54178 // Determine which blocks to update: 54179 // If the current (focused) block is part of the block selection, use the whole selection. 54180 // If the focused block is not part of the block selection, only update the focused block. 54181 function getBlocksToUpdate(clientId) { 54182 const selectedBlockClientIds = getSelectedBlockClientIds(); 54183 const isUpdatingSelectedBlocks = selectedBlockClientIds.includes(clientId); 54184 const firstBlockClientId = isUpdatingSelectedBlocks ? selectedBlockClientIds[0] : clientId; 54185 const firstBlockRootClientId = getBlockRootClientId(firstBlockClientId); 54186 const blocksToUpdate = isUpdatingSelectedBlocks ? selectedBlockClientIds : [clientId]; 54187 return { 54188 blocksToUpdate, 54189 firstBlockClientId, 54190 firstBlockRootClientId, 54191 originallySelectedBlockClientIds: selectedBlockClientIds 54192 }; 54193 } 54194 function handler(event) { 54195 if (event.defaultPrevented) { 54196 // This was possibly already handled in rich-text/use-paste-handler.js. 54197 return; 54198 } 54199 54200 // Only handle events that occur within the list view. 54201 if (!node.contains(event.target.ownerDocument.activeElement)) { 54202 return; 54203 } 54204 54205 // Retrieve the block clientId associated with the focused list view row. 54206 // This enables applying copy / cut / paste behavior to the focused block, 54207 // rather than just the blocks that are currently selected. 54208 const listViewRow = event.target.ownerDocument.activeElement?.closest('[role=row]'); 54209 const clientId = listViewRow?.dataset?.block; 54210 if (!clientId) { 54211 return; 54212 } 54213 const { 54214 blocksToUpdate: selectedBlockClientIds, 54215 firstBlockClientId, 54216 firstBlockRootClientId, 54217 originallySelectedBlockClientIds 54218 } = getBlocksToUpdate(clientId); 54219 if (selectedBlockClientIds.length === 0) { 54220 return; 54221 } 54222 event.preventDefault(); 54223 if (event.type === 'copy' || event.type === 'cut') { 54224 if (selectedBlockClientIds.length === 1) { 54225 flashBlock(selectedBlockClientIds[0]); 54226 } 54227 notifyCopy(event.type, selectedBlockClientIds); 54228 const blocks = getBlocksByClientId(selectedBlockClientIds); 54229 setClipboardBlocks(event, blocks, registry); 54230 } 54231 if (event.type === 'cut') { 54232 var _getPreviousBlockClie; 54233 // Don't update the selection if the blocks cannot be deleted. 54234 if (!canRemoveBlocks(selectedBlockClientIds, firstBlockRootClientId)) { 54235 return; 54236 } 54237 let blockToFocus = (_getPreviousBlockClie = getPreviousBlockClientId(firstBlockClientId)) !== null && _getPreviousBlockClie !== void 0 ? _getPreviousBlockClie : 54238 // If the previous block is not found (when the first block is deleted), 54239 // fallback to focus the parent block. 54240 firstBlockRootClientId; 54241 54242 // Remove blocks, but don't update selection, and it will be handled below. 54243 removeBlocks(selectedBlockClientIds, false); 54244 54245 // Update the selection if the original selection has been removed. 54246 const shouldUpdateSelection = originallySelectedBlockClientIds.length > 0 && getSelectedBlockClientIds().length === 0; 54247 54248 // If there's no previous block nor parent block, focus the first block. 54249 if (!blockToFocus) { 54250 blockToFocus = getBlockOrder()[0]; 54251 } 54252 updateFocusAndSelection(blockToFocus, shouldUpdateSelection); 54253 } else if (event.type === 'paste') { 54254 const { 54255 __experimentalCanUserUseUnfilteredHTML: canUserUseUnfilteredHTML 54256 } = getSettings(); 54257 const blocks = getPasteBlocks(event, canUserUseUnfilteredHTML); 54258 if (selectedBlockClientIds.length === 1) { 54259 const [selectedBlockClientId] = selectedBlockClientIds; 54260 54261 // If a single block is focused, and the blocks to be posted can 54262 // be inserted within the block, then append the pasted blocks 54263 // within the focused block. For example, if you have copied a paragraph 54264 // block and paste it within a single Group block, this will append 54265 // the paragraph block within the Group block. 54266 if (blocks.every(block => canInsertBlockType(block.name, selectedBlockClientId))) { 54267 insertBlocks(blocks, undefined, selectedBlockClientId); 54268 updateFocusAndSelection(blocks[0]?.clientId, false); 54269 return; 54270 } 54271 } 54272 replaceBlocks(selectedBlockClientIds, blocks, blocks.length - 1, -1); 54273 updateFocusAndSelection(blocks[0]?.clientId, false); 54274 } 54275 } 54276 node.ownerDocument.addEventListener('copy', handler); 54277 node.ownerDocument.addEventListener('cut', handler); 54278 node.ownerDocument.addEventListener('paste', handler); 54279 return () => { 54280 node.ownerDocument.removeEventListener('copy', handler); 54281 node.ownerDocument.removeEventListener('cut', handler); 54282 node.ownerDocument.removeEventListener('paste', handler); 54283 }; 54284 }, []); 54285 } 54286 54287 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/list-view/index.js 54288 54289 /** 54290 * External dependencies 54291 */ 54292 54293 54294 /** 54295 * WordPress dependencies 54296 */ 54297 54298 54299 54300 54301 54302 54303 54304 /** 54305 * Internal dependencies 54306 */ 54307 54308 54309 54310 54311 54312 54313 54314 54315 54316 54317 54318 54319 const expanded = (state, action) => { 54320 if (Array.isArray(action.clientIds)) { 54321 return { 54322 ...state, 54323 ...action.clientIds.reduce((newState, id) => ({ 54324 ...newState, 54325 [id]: action.type === 'expand' 54326 }), {}) 54327 }; 54328 } 54329 return state; 54330 }; 54331 const BLOCK_LIST_ITEM_HEIGHT = 36; 54332 54333 /** @typedef {import('react').ComponentType} ComponentType */ 54334 /** @typedef {import('react').Ref<HTMLElement>} Ref */ 54335 54336 /** 54337 * Show a hierarchical list of blocks. 54338 * 54339 * @param {Object} props Components props. 54340 * @param {string} props.id An HTML element id for the root element of ListView. 54341 * @param {Array} props.blocks _deprecated_ Custom subset of block client IDs to be used instead of the default hierarchy. 54342 * @param {?HTMLElement} props.dropZoneElement Optional element to be used as the drop zone. 54343 * @param {?boolean} props.showBlockMovers Flag to enable block movers. Defaults to `false`. 54344 * @param {?boolean} props.isExpanded Flag to determine whether nested levels are expanded by default. Defaults to `false`. 54345 * @param {?boolean} props.showAppender Flag to show or hide the block appender. Defaults to `false`. 54346 * @param {?ComponentType} props.blockSettingsMenu Optional more menu substitution. Defaults to the standard `BlockSettingsDropdown` component. 54347 * @param {string} props.rootClientId The client id of the root block from which we determine the blocks to show in the list. 54348 * @param {string} props.description Optional accessible description for the tree grid component. 54349 * @param {?Function} props.onSelect Optional callback to be invoked when a block is selected. Receives the block object that was selected. 54350 * @param {?ComponentType} props.additionalBlockContent Component that renders additional block content UI. 54351 * @param {Ref} ref Forwarded ref 54352 */ 54353 function ListViewComponent({ 54354 id, 54355 blocks, 54356 dropZoneElement, 54357 showBlockMovers = false, 54358 isExpanded = false, 54359 showAppender = false, 54360 blockSettingsMenu: BlockSettingsMenu = BlockSettingsDropdown, 54361 rootClientId, 54362 description, 54363 onSelect, 54364 additionalBlockContent: AdditionalBlockContent 54365 }, ref) { 54366 // This can be removed once we no longer need to support the blocks prop. 54367 if (blocks) { 54368 external_wp_deprecated_default()('`blocks` property in `wp.blockEditor.__experimentalListView`', { 54369 since: '6.3', 54370 alternative: '`rootClientId` property' 54371 }); 54372 } 54373 const instanceId = (0,external_wp_compose_namespaceObject.useInstanceId)(ListViewComponent); 54374 const { 54375 clientIdsTree, 54376 draggedClientIds, 54377 selectedClientIds 54378 } = useListViewClientIds({ 54379 blocks, 54380 rootClientId 54381 }); 54382 const blockIndexes = useListViewBlockIndexes(clientIdsTree); 54383 const { 54384 getBlock 54385 } = (0,external_wp_data_namespaceObject.useSelect)(store); 54386 const { 54387 visibleBlockCount, 54388 shouldShowInnerBlocks 54389 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 54390 const { 54391 getGlobalBlockCount, 54392 getClientIdsOfDescendants, 54393 __unstableGetEditorMode 54394 } = select(store); 54395 const draggedBlockCount = draggedClientIds?.length > 0 ? getClientIdsOfDescendants(draggedClientIds).length + 1 : 0; 54396 return { 54397 visibleBlockCount: getGlobalBlockCount() - draggedBlockCount, 54398 shouldShowInnerBlocks: __unstableGetEditorMode() !== 'zoom-out' 54399 }; 54400 }, [draggedClientIds]); 54401 const { 54402 updateBlockSelection 54403 } = useBlockSelection(); 54404 const [expandedState, setExpandedState] = (0,external_wp_element_namespaceObject.useReducer)(expanded, {}); 54405 const [insertedBlock, setInsertedBlock] = (0,external_wp_element_namespaceObject.useState)(null); 54406 const { 54407 setSelectedTreeId 54408 } = useListViewExpandSelectedItem({ 54409 firstSelectedBlockClientId: selectedClientIds[0], 54410 setExpandedState 54411 }); 54412 const selectEditorBlock = (0,external_wp_element_namespaceObject.useCallback)( 54413 /** 54414 * @param {MouseEvent | KeyboardEvent | undefined} event 54415 * @param {string} blockClientId 54416 * @param {null | undefined | -1 | 1} focusPosition 54417 */ 54418 (event, blockClientId, focusPosition) => { 54419 updateBlockSelection(event, blockClientId, null, focusPosition); 54420 setSelectedTreeId(blockClientId); 54421 if (onSelect) { 54422 onSelect(getBlock(blockClientId)); 54423 } 54424 }, [setSelectedTreeId, updateBlockSelection, onSelect, getBlock]); 54425 const { 54426 ref: dropZoneRef, 54427 target: blockDropTarget 54428 } = useListViewDropZone({ 54429 dropZoneElement, 54430 expandedState, 54431 setExpandedState 54432 }); 54433 const elementRef = (0,external_wp_element_namespaceObject.useRef)(); 54434 54435 // Allow handling of copy, cut, and paste events. 54436 const clipBoardRef = use_clipboard_handler_useClipboardHandler({ 54437 selectBlock: selectEditorBlock 54438 }); 54439 const treeGridRef = (0,external_wp_compose_namespaceObject.useMergeRefs)([clipBoardRef, elementRef, dropZoneRef, ref]); 54440 (0,external_wp_element_namespaceObject.useEffect)(() => { 54441 // If a blocks are already selected when the list view is initially 54442 // mounted, shift focus to the first selected block. 54443 if (selectedClientIds?.length) { 54444 focusListItem(selectedClientIds[0], elementRef?.current); 54445 } 54446 // Disable reason: Only focus on the selected item when the list view is mounted. 54447 // eslint-disable-next-line react-hooks/exhaustive-deps 54448 }, []); 54449 const expand = (0,external_wp_element_namespaceObject.useCallback)(clientId => { 54450 if (!clientId) { 54451 return; 54452 } 54453 setExpandedState({ 54454 type: 'expand', 54455 clientIds: [clientId] 54456 }); 54457 }, [setExpandedState]); 54458 const collapse = (0,external_wp_element_namespaceObject.useCallback)(clientId => { 54459 if (!clientId) { 54460 return; 54461 } 54462 setExpandedState({ 54463 type: 'collapse', 54464 clientIds: [clientId] 54465 }); 54466 }, [setExpandedState]); 54467 const expandRow = (0,external_wp_element_namespaceObject.useCallback)(row => { 54468 expand(row?.dataset?.block); 54469 }, [expand]); 54470 const collapseRow = (0,external_wp_element_namespaceObject.useCallback)(row => { 54471 collapse(row?.dataset?.block); 54472 }, [collapse]); 54473 const focusRow = (0,external_wp_element_namespaceObject.useCallback)((event, startRow, endRow) => { 54474 if (event.shiftKey) { 54475 updateBlockSelection(event, startRow?.dataset?.block, endRow?.dataset?.block); 54476 } 54477 }, [updateBlockSelection]); 54478 const firstDraggedBlockClientId = draggedClientIds?.[0]; 54479 54480 // Convert a blockDropTarget into indexes relative to the blocks in the list view. 54481 // These values are used to determine which blocks should be displaced to make room 54482 // for the drop indicator. See `ListViewBranch` and `getDragDisplacementValues`. 54483 const { 54484 blockDropTargetIndex, 54485 blockDropPosition, 54486 firstDraggedBlockIndex 54487 } = (0,external_wp_element_namespaceObject.useMemo)(() => { 54488 let _blockDropTargetIndex, _firstDraggedBlockIndex; 54489 if (blockDropTarget?.clientId) { 54490 const foundBlockIndex = blockIndexes[blockDropTarget.clientId]; 54491 // If dragging below or inside the block, treat the drop target as the next block. 54492 _blockDropTargetIndex = foundBlockIndex === undefined || blockDropTarget?.dropPosition === 'top' ? foundBlockIndex : foundBlockIndex + 1; 54493 } else if (blockDropTarget === null) { 54494 // A `null` value is used to indicate that the user is dragging outside of the list view. 54495 _blockDropTargetIndex = null; 54496 } 54497 if (firstDraggedBlockClientId) { 54498 const foundBlockIndex = blockIndexes[firstDraggedBlockClientId]; 54499 _firstDraggedBlockIndex = foundBlockIndex === undefined || blockDropTarget?.dropPosition === 'top' ? foundBlockIndex : foundBlockIndex + 1; 54500 } 54501 return { 54502 blockDropTargetIndex: _blockDropTargetIndex, 54503 blockDropPosition: blockDropTarget?.dropPosition, 54504 firstDraggedBlockIndex: _firstDraggedBlockIndex 54505 }; 54506 }, [blockDropTarget, blockIndexes, firstDraggedBlockClientId]); 54507 const contextValue = (0,external_wp_element_namespaceObject.useMemo)(() => ({ 54508 blockDropPosition, 54509 blockDropTargetIndex, 54510 blockIndexes, 54511 draggedClientIds, 54512 expandedState, 54513 expand, 54514 firstDraggedBlockIndex, 54515 collapse, 54516 BlockSettingsMenu, 54517 listViewInstanceId: instanceId, 54518 AdditionalBlockContent, 54519 insertedBlock, 54520 setInsertedBlock, 54521 treeGridElementRef: elementRef, 54522 rootClientId 54523 }), [blockDropPosition, blockDropTargetIndex, blockIndexes, draggedClientIds, expandedState, expand, firstDraggedBlockIndex, collapse, BlockSettingsMenu, instanceId, AdditionalBlockContent, insertedBlock, setInsertedBlock, rootClientId]); 54524 54525 // List View renders a fixed number of items and relies on each having a fixed item height of 36px. 54526 // If this value changes, we should also change the itemHeight value set in useFixedWindowList. 54527 // See: https://github.com/WordPress/gutenberg/pull/35230 for additional context. 54528 const [fixedListWindow] = (0,external_wp_compose_namespaceObject.__experimentalUseFixedWindowList)(elementRef, BLOCK_LIST_ITEM_HEIGHT, visibleBlockCount, { 54529 // Ensure that the windowing logic is recalculated when the expanded state changes. 54530 // This is necessary because expanding a collapsed block in a short list view can 54531 // switch the list view to a tall list view with a scrollbar, and vice versa. 54532 // When this happens, the windowing logic needs to be recalculated to ensure that 54533 // the correct number of blocks are rendered, by rechecking for a scroll container. 54534 expandedState, 54535 useWindowing: true, 54536 windowOverscan: 40 54537 }); 54538 54539 // If there are no blocks to show and we're not showing the appender, do not render the list view. 54540 if (!clientIdsTree.length && !showAppender) { 54541 return null; 54542 } 54543 const describedById = description && `block-editor-list-view-description-$instanceId}`; 54544 return (0,external_React_.createElement)(external_wp_data_namespaceObject.AsyncModeProvider, { 54545 value: true 54546 }, (0,external_React_.createElement)(ListViewDropIndicatorPreview, { 54547 draggedBlockClientId: firstDraggedBlockClientId, 54548 listViewRef: elementRef, 54549 blockDropTarget: blockDropTarget 54550 }), description && (0,external_React_.createElement)(external_wp_components_namespaceObject.VisuallyHidden, { 54551 id: describedById 54552 }, description), (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalTreeGrid, { 54553 id: id, 54554 className: classnames_default()('block-editor-list-view-tree', { 54555 'is-dragging': draggedClientIds?.length > 0 && blockDropTargetIndex !== undefined 54556 }), 54557 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Block navigation structure'), 54558 ref: treeGridRef, 54559 onCollapseRow: collapseRow, 54560 onExpandRow: expandRow, 54561 onFocusRow: focusRow, 54562 applicationAriaLabel: (0,external_wp_i18n_namespaceObject.__)('Block navigation structure'), 54563 "aria-describedby": describedById, 54564 style: { 54565 '--wp-admin--list-view-dragged-items-height': draggedClientIds?.length ? `$BLOCK_LIST_ITEM_HEIGHT * (draggedClientIds.length - 1)}px` : null 54566 } 54567 }, (0,external_React_.createElement)(ListViewContext.Provider, { 54568 value: contextValue 54569 }, (0,external_React_.createElement)(branch, { 54570 blocks: clientIdsTree, 54571 parentId: rootClientId, 54572 selectBlock: selectEditorBlock, 54573 showBlockMovers: showBlockMovers, 54574 fixedListWindow: fixedListWindow, 54575 selectedClientIds: selectedClientIds, 54576 isExpanded: isExpanded, 54577 shouldShowInnerBlocks: shouldShowInnerBlocks, 54578 showAppender: showAppender 54579 })))); 54580 } 54581 54582 // This is the private API for the ListView component. 54583 // It allows access to all props, not just the public ones. 54584 const PrivateListView = (0,external_wp_element_namespaceObject.forwardRef)(ListViewComponent); 54585 54586 // This is the public API for the ListView component. 54587 // We wrap the PrivateListView component to hide some props from the public API. 54588 /* harmony default export */ const components_list_view = ((0,external_wp_element_namespaceObject.forwardRef)((props, ref) => { 54589 return (0,external_React_.createElement)(PrivateListView, { 54590 ref: ref, 54591 ...props, 54592 showAppender: false, 54593 rootClientId: null, 54594 onSelect: null, 54595 additionalBlockContent: null, 54596 blockSettingsMenu: undefined 54597 }); 54598 })); 54599 54600 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-navigation/dropdown.js 54601 54602 /** 54603 * WordPress dependencies 54604 */ 54605 54606 54607 /** 54608 * WordPress dependencies 54609 */ 54610 54611 54612 54613 54614 54615 54616 /** 54617 * Internal dependencies 54618 */ 54619 54620 54621 function BlockNavigationDropdownToggle({ 54622 isEnabled, 54623 onToggle, 54624 isOpen, 54625 innerRef, 54626 ...props 54627 }) { 54628 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 54629 ...props, 54630 ref: innerRef, 54631 icon: list_view, 54632 "aria-expanded": isOpen, 54633 "aria-haspopup": "true", 54634 onClick: isEnabled ? onToggle : undefined 54635 /* translators: button label text should, if possible, be under 16 characters. */, 54636 label: (0,external_wp_i18n_namespaceObject.__)('List view'), 54637 className: "block-editor-block-navigation", 54638 "aria-disabled": !isEnabled 54639 }); 54640 } 54641 function BlockNavigationDropdown({ 54642 isDisabled, 54643 ...props 54644 }, ref) { 54645 external_wp_deprecated_default()('wp.blockEditor.BlockNavigationDropdown', { 54646 since: '6.1', 54647 alternative: 'wp.components.Dropdown and wp.blockEditor.ListView' 54648 }); 54649 const hasBlocks = (0,external_wp_data_namespaceObject.useSelect)(select => !!select(store).getBlockCount(), []); 54650 const isEnabled = hasBlocks && !isDisabled; 54651 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Dropdown, { 54652 contentClassName: "block-editor-block-navigation__popover", 54653 popoverProps: { 54654 placement: 'bottom-start' 54655 }, 54656 renderToggle: ({ 54657 isOpen, 54658 onToggle 54659 }) => (0,external_React_.createElement)(BlockNavigationDropdownToggle, { 54660 ...props, 54661 innerRef: ref, 54662 isOpen: isOpen, 54663 onToggle: onToggle, 54664 isEnabled: isEnabled 54665 }), 54666 renderContent: () => (0,external_React_.createElement)("div", { 54667 className: "block-editor-block-navigation__container" 54668 }, (0,external_React_.createElement)("p", { 54669 className: "block-editor-block-navigation__label" 54670 }, (0,external_wp_i18n_namespaceObject.__)('List view')), (0,external_React_.createElement)(components_list_view, null)) 54671 }); 54672 } 54673 /* harmony default export */ const dropdown = ((0,external_wp_element_namespaceObject.forwardRef)(BlockNavigationDropdown)); 54674 54675 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-styles/preview-panel.js 54676 54677 /** 54678 * WordPress dependencies 54679 */ 54680 54681 54682 54683 /** 54684 * Internal dependencies 54685 */ 54686 54687 54688 function BlockStylesPreviewPanel({ 54689 genericPreviewBlock, 54690 style, 54691 className, 54692 activeStyle 54693 }) { 54694 const example = (0,external_wp_blocks_namespaceObject.getBlockType)(genericPreviewBlock.name)?.example; 54695 const styleClassName = replaceActiveStyle(className, activeStyle, style); 54696 const previewBlocks = (0,external_wp_element_namespaceObject.useMemo)(() => { 54697 return { 54698 ...genericPreviewBlock, 54699 title: style.label || style.name, 54700 description: style.description, 54701 initialAttributes: { 54702 ...genericPreviewBlock.attributes, 54703 className: styleClassName + ' block-editor-block-styles__block-preview-container' 54704 }, 54705 example 54706 }; 54707 }, [genericPreviewBlock, styleClassName]); 54708 return (0,external_React_.createElement)(preview_panel, { 54709 item: previewBlocks 54710 }); 54711 } 54712 54713 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-styles/index.js 54714 54715 /** 54716 * External dependencies 54717 */ 54718 54719 54720 /** 54721 * WordPress dependencies 54722 */ 54723 54724 54725 54726 54727 /** 54728 * Internal dependencies 54729 */ 54730 54731 54732 const block_styles_noop = () => {}; 54733 54734 // Block Styles component for the Settings Sidebar. 54735 function BlockStyles({ 54736 clientId, 54737 onSwitch = block_styles_noop, 54738 onHoverClassName = block_styles_noop 54739 }) { 54740 const { 54741 onSelect, 54742 stylesToRender, 54743 activeStyle, 54744 genericPreviewBlock, 54745 className: previewClassName 54746 } = useStylesForBlocks({ 54747 clientId, 54748 onSwitch 54749 }); 54750 const [hoveredStyle, setHoveredStyle] = (0,external_wp_element_namespaceObject.useState)(null); 54751 const isMobileViewport = (0,external_wp_compose_namespaceObject.useViewportMatch)('medium', '<'); 54752 if (!stylesToRender || stylesToRender.length === 0) { 54753 return null; 54754 } 54755 const debouncedSetHoveredStyle = (0,external_wp_compose_namespaceObject.debounce)(setHoveredStyle, 250); 54756 const onSelectStylePreview = style => { 54757 onSelect(style); 54758 onHoverClassName(null); 54759 setHoveredStyle(null); 54760 debouncedSetHoveredStyle.cancel(); 54761 }; 54762 const styleItemHandler = item => { 54763 var _item$name; 54764 if (hoveredStyle === item) { 54765 debouncedSetHoveredStyle.cancel(); 54766 return; 54767 } 54768 debouncedSetHoveredStyle(item); 54769 onHoverClassName((_item$name = item?.name) !== null && _item$name !== void 0 ? _item$name : null); 54770 }; 54771 return (0,external_React_.createElement)("div", { 54772 className: "block-editor-block-styles" 54773 }, (0,external_React_.createElement)("div", { 54774 className: "block-editor-block-styles__variants" 54775 }, stylesToRender.map(style => { 54776 const buttonText = style.label || style.name; 54777 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 54778 __next40pxDefaultSize: true, 54779 className: classnames_default()('block-editor-block-styles__item', { 54780 'is-active': activeStyle.name === style.name 54781 }), 54782 key: style.name, 54783 variant: "secondary", 54784 label: buttonText, 54785 onMouseEnter: () => styleItemHandler(style), 54786 onFocus: () => styleItemHandler(style), 54787 onMouseLeave: () => styleItemHandler(null), 54788 onBlur: () => styleItemHandler(null), 54789 onClick: () => onSelectStylePreview(style), 54790 "aria-current": activeStyle.name === style.name 54791 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalTruncate, { 54792 numberOfLines: 1, 54793 className: "block-editor-block-styles__item-text" 54794 }, buttonText)); 54795 })), hoveredStyle && !isMobileViewport && (0,external_React_.createElement)(external_wp_components_namespaceObject.Popover, { 54796 placement: "left-start", 54797 offset: 34, 54798 focusOnMount: false 54799 }, (0,external_React_.createElement)("div", { 54800 className: "block-editor-block-styles__preview-panel", 54801 onMouseLeave: () => styleItemHandler(null) 54802 }, (0,external_React_.createElement)(BlockStylesPreviewPanel, { 54803 activeStyle: activeStyle, 54804 className: previewClassName, 54805 genericPreviewBlock: genericPreviewBlock, 54806 style: hoveredStyle 54807 })))); 54808 } 54809 /* harmony default export */ const block_styles = (BlockStyles); 54810 54811 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/paragraph.js 54812 54813 /** 54814 * WordPress dependencies 54815 */ 54816 54817 const paragraph = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 54818 xmlns: "http://www.w3.org/2000/svg", 54819 viewBox: "0 0 24 24" 54820 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 54821 d: "m9.99609 14v-.2251l.00391.0001v6.225h1.5v-14.5h2.5v14.5h1.5v-14.5h3v-1.5h-8.50391c-2.76142 0-5 2.23858-5 5 0 2.7614 2.23858 5 5 5z" 54822 })); 54823 /* harmony default export */ const library_paragraph = (paragraph); 54824 54825 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/heading-level-1.js 54826 54827 /** 54828 * WordPress dependencies 54829 */ 54830 54831 const headingLevel1 = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 54832 xmlns: "http://www.w3.org/2000/svg", 54833 viewBox: "0 0 24 24" 54834 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 54835 d: "M17.6 7c-.6.9-1.5 1.7-2.6 2v1h2v7h2V7h-1.4zM11 11H7V7H5v10h2v-4h4v4h2V7h-2v4z" 54836 })); 54837 /* harmony default export */ const heading_level_1 = (headingLevel1); 54838 54839 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/heading-level-2.js 54840 54841 /** 54842 * WordPress dependencies 54843 */ 54844 54845 const headingLevel2 = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 54846 xmlns: "http://www.w3.org/2000/svg", 54847 viewBox: "0 0 24 24" 54848 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 54849 d: "M9 11.1H5v-4H3v10h2v-4h4v4h2v-10H9v4zm8 4c.5-.4.6-.6 1.1-1.1.4-.4.8-.8 1.2-1.3.3-.4.6-.8.9-1.3.2-.4.3-.8.3-1.3 0-.4-.1-.9-.3-1.3-.2-.4-.4-.7-.8-1-.3-.3-.7-.5-1.2-.6-.5-.2-1-.2-1.5-.2-.4 0-.7 0-1.1.1-.3.1-.7.2-1 .3-.3.1-.6.3-.9.5-.3.2-.6.4-.8.7l1.2 1.2c.3-.3.6-.5 1-.7.4-.2.7-.3 1.2-.3s.9.1 1.3.4c.3.3.5.7.5 1.1 0 .4-.1.8-.4 1.1-.3.5-.6.9-1 1.2-.4.4-1 .9-1.6 1.4-.6.5-1.4 1.1-2.2 1.6v1.5h8v-2H17z" 54850 })); 54851 /* harmony default export */ const heading_level_2 = (headingLevel2); 54852 54853 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/heading-level-3.js 54854 54855 /** 54856 * WordPress dependencies 54857 */ 54858 54859 const headingLevel3 = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 54860 xmlns: "http://www.w3.org/2000/svg", 54861 viewBox: "0 0 24 24" 54862 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 54863 d: "M9 11H5V7H3v10h2v-4h4v4h2V7H9v4zm11.3 1.7c-.4-.4-1-.7-1.6-.8v-.1c.6-.2 1.1-.5 1.5-.9.3-.4.5-.8.5-1.3 0-.4-.1-.8-.3-1.1-.2-.3-.5-.6-.8-.8-.4-.2-.8-.4-1.2-.5-.6-.1-1.1-.2-1.6-.2-.6 0-1.3.1-1.8.3s-1.1.5-1.6.9l1.2 1.4c.4-.2.7-.4 1.1-.6.3-.2.7-.3 1.1-.3.4 0 .8.1 1.1.3.3.2.4.5.4.8 0 .4-.2.7-.6.9-.7.3-1.5.5-2.2.4v1.6c.5 0 1 0 1.5.1.3.1.7.2 1 .3.2.1.4.2.5.4s.1.4.1.6c0 .3-.2.7-.5.8-.4.2-.9.3-1.4.3s-1-.1-1.4-.3c-.4-.2-.8-.4-1.2-.7L13 15.6c.5.4 1 .8 1.6 1 .7.3 1.5.4 2.3.4.6 0 1.1-.1 1.6-.2.4-.1.9-.2 1.3-.5.4-.2.7-.5.9-.9.2-.4.3-.8.3-1.2 0-.6-.3-1.1-.7-1.5z" 54864 })); 54865 /* harmony default export */ const heading_level_3 = (headingLevel3); 54866 54867 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/heading-level-4.js 54868 54869 /** 54870 * WordPress dependencies 54871 */ 54872 54873 const headingLevel4 = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 54874 xmlns: "http://www.w3.org/2000/svg", 54875 viewBox: "0 0 24 24" 54876 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 54877 d: "M20 13V7h-3l-4 6v2h5v2h2v-2h1v-2h-1zm-2 0h-2.8L18 9v4zm-9-2H5V7H3v10h2v-4h4v4h2V7H9v4z" 54878 })); 54879 /* harmony default export */ const heading_level_4 = (headingLevel4); 54880 54881 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/heading-level-5.js 54882 54883 /** 54884 * WordPress dependencies 54885 */ 54886 54887 const headingLevel5 = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 54888 xmlns: "http://www.w3.org/2000/svg", 54889 viewBox: "0 0 24 24" 54890 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 54891 d: "M9 11H5V7H3v10h2v-4h4v4h2V7H9v4zm11.7 1.2c-.2-.3-.5-.7-.8-.9-.3-.3-.7-.5-1.1-.6-.5-.1-.9-.2-1.4-.2-.2 0-.5.1-.7.1-.2.1-.5.1-.7.2l.1-1.9h4.3V7H14l-.3 5 1 .6.5-.2.4-.1c.1-.1.3-.1.4-.1h.5c.5 0 1 .1 1.4.4.4.2.6.7.6 1.1 0 .4-.2.8-.6 1.1-.4.3-.9.4-1.4.4-.4 0-.9-.1-1.3-.3-.4-.2-.7-.4-1.1-.7 0 0-1.1 1.4-1 1.5.5.4 1 .8 1.6 1 .7.3 1.5.4 2.3.4.5 0 1-.1 1.5-.3s.9-.4 1.3-.7c.4-.3.7-.7.9-1.1s.3-.9.3-1.4-.1-1-.3-1.4z" 54892 })); 54893 /* harmony default export */ const heading_level_5 = (headingLevel5); 54894 54895 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/heading-level-6.js 54896 54897 /** 54898 * WordPress dependencies 54899 */ 54900 54901 const headingLevel6 = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 54902 xmlns: "http://www.w3.org/2000/svg", 54903 viewBox: "0 0 24 24" 54904 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 54905 d: "M20.7 12.4c-.2-.3-.4-.6-.7-.9s-.6-.5-1-.6c-.4-.2-.8-.2-1.2-.2-.5 0-.9.1-1.3.3s-.8.5-1.2.8c0-.5 0-.9.2-1.4l.6-.9c.2-.2.5-.4.8-.5.6-.2 1.3-.2 1.9 0 .3.1.6.3.8.5 0 0 1.3-1.3 1.3-1.4-.4-.3-.9-.6-1.4-.8-.6-.2-1.3-.3-2-.3-.6 0-1.1.1-1.7.4-.5.2-1 .5-1.4.9-.4.4-.8 1-1 1.6-.3.7-.4 1.5-.4 2.3s.1 1.5.3 2.1c.2.6.6 1.1 1 1.5.4.4.9.7 1.4.9 1 .3 2 .3 3 0 .4-.1.8-.3 1.2-.6.3-.3.6-.6.8-1 .2-.5.3-.9.3-1.4s-.1-.9-.3-1.3zm-2 2.1c-.1.2-.3.4-.4.5-.1.1-.3.2-.5.2-.2.1-.4.1-.6.1-.2.1-.5 0-.7-.1-.2 0-.3-.2-.5-.3-.1-.2-.3-.4-.4-.6-.2-.3-.3-.7-.3-1 .3-.3.6-.5 1-.7.3-.1.7-.2 1-.2.4 0 .8.1 1.1.3.3.3.4.7.4 1.1 0 .2 0 .5-.1.7zM9 11H5V7H3v10h2v-4h4v4h2V7H9v4z" 54906 })); 54907 /* harmony default export */ const heading_level_6 = (headingLevel6); 54908 54909 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-heading-level-dropdown/heading-level-icon.js 54910 54911 /** 54912 * WordPress dependencies 54913 */ 54914 54915 54916 54917 /** @typedef {import('react').ComponentType} ComponentType */ 54918 54919 /** 54920 * HeadingLevelIcon props. 54921 * 54922 * @typedef WPHeadingLevelIconProps 54923 * 54924 * @property {number} level The heading level to show an icon for. 54925 */ 54926 54927 const LEVEL_TO_PATH = { 54928 0: library_paragraph, 54929 1: heading_level_1, 54930 2: heading_level_2, 54931 3: heading_level_3, 54932 4: heading_level_4, 54933 5: heading_level_5, 54934 6: heading_level_6 54935 }; 54936 54937 /** 54938 * Heading level icon. 54939 * 54940 * @param {WPHeadingLevelIconProps} props Component props. 54941 * 54942 * @return {?ComponentType} The icon. 54943 */ 54944 function HeadingLevelIcon({ 54945 level 54946 }) { 54947 if (LEVEL_TO_PATH[level]) { 54948 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Icon, { 54949 icon: LEVEL_TO_PATH[level] 54950 }); 54951 } 54952 return null; 54953 } 54954 54955 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-heading-level-dropdown/index.js 54956 54957 /** 54958 * WordPress dependencies 54959 */ 54960 54961 54962 54963 /** 54964 * Internal dependencies 54965 */ 54966 54967 const HEADING_LEVELS = [1, 2, 3, 4, 5, 6]; 54968 const block_heading_level_dropdown_POPOVER_PROPS = { 54969 className: 'block-library-heading-level-dropdown' 54970 }; 54971 54972 /** @typedef {import('react').ComponentType} ComponentType */ 54973 54974 /** 54975 * HeadingLevelDropdown props. 54976 * 54977 * @typedef WPHeadingLevelDropdownProps 54978 * 54979 * @property {number} value The chosen heading level. 54980 * @property {number[]} options An array of supported heading levels. 54981 * @property {(newValue:number)=>any} onChange Callback to run when 54982 * toolbar value is changed. 54983 */ 54984 54985 /** 54986 * Dropdown for selecting a heading level (1 through 6) or paragraph (0). 54987 * 54988 * @param {WPHeadingLevelDropdownProps} props Component props. 54989 * 54990 * @return {ComponentType} The toolbar. 54991 */ 54992 function HeadingLevelDropdown({ 54993 options = HEADING_LEVELS, 54994 value, 54995 onChange 54996 }) { 54997 return (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarDropdownMenu, { 54998 popoverProps: block_heading_level_dropdown_POPOVER_PROPS, 54999 icon: (0,external_React_.createElement)(HeadingLevelIcon, { 55000 level: value 55001 }), 55002 label: (0,external_wp_i18n_namespaceObject.__)('Change level'), 55003 controls: options.map(targetLevel => { 55004 { 55005 const isActive = targetLevel === value; 55006 return { 55007 icon: (0,external_React_.createElement)(HeadingLevelIcon, { 55008 level: targetLevel, 55009 isPressed: isActive 55010 }), 55011 title: targetLevel === 0 ? (0,external_wp_i18n_namespaceObject.__)('Paragraph') : (0,external_wp_i18n_namespaceObject.sprintf)( 55012 // translators: %s: heading level e.g: "1", "2", "3" 55013 (0,external_wp_i18n_namespaceObject.__)('Heading %d'), targetLevel), 55014 isActive, 55015 onClick() { 55016 onChange(targetLevel); 55017 }, 55018 role: 'menuitemradio' 55019 }; 55020 } 55021 }) 55022 }); 55023 } 55024 55025 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/layout.js 55026 55027 /** 55028 * WordPress dependencies 55029 */ 55030 55031 const layout_layout = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 55032 xmlns: "http://www.w3.org/2000/svg", 55033 viewBox: "0 0 24 24" 55034 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 55035 d: "M18 5.5H6a.5.5 0 00-.5.5v3h13V6a.5.5 0 00-.5-.5zm.5 5H10v8h8a.5.5 0 00.5-.5v-7.5zm-10 0h-3V18a.5.5 0 00.5.5h2.5v-8zM6 4h12a2 2 0 012 2v12a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z" 55036 })); 55037 /* harmony default export */ const library_layout = (layout_layout); 55038 55039 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-variation-picker/index.js 55040 55041 /** 55042 * External dependencies 55043 */ 55044 55045 55046 /** 55047 * WordPress dependencies 55048 */ 55049 55050 55051 55052 function BlockVariationPicker({ 55053 icon = library_layout, 55054 label = (0,external_wp_i18n_namespaceObject.__)('Choose variation'), 55055 instructions = (0,external_wp_i18n_namespaceObject.__)('Select a variation to start with.'), 55056 variations, 55057 onSelect, 55058 allowSkip 55059 }) { 55060 const classes = classnames_default()('block-editor-block-variation-picker', { 55061 'has-many-variations': variations.length > 4 55062 }); 55063 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Placeholder, { 55064 icon: icon, 55065 label: label, 55066 instructions: instructions, 55067 className: classes 55068 }, (0,external_React_.createElement)("ul", { 55069 className: "block-editor-block-variation-picker__variations", 55070 role: "list", 55071 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Block variations') 55072 }, variations.map(variation => (0,external_React_.createElement)("li", { 55073 key: variation.name 55074 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 55075 variant: "secondary", 55076 icon: variation.icon && variation.icon.src ? variation.icon.src : variation.icon, 55077 iconSize: 48, 55078 onClick: () => onSelect(variation), 55079 className: "block-editor-block-variation-picker__variation", 55080 label: variation.description || variation.title 55081 }), (0,external_React_.createElement)("span", { 55082 className: "block-editor-block-variation-picker__variation-label" 55083 }, variation.title)))), allowSkip && (0,external_React_.createElement)("div", { 55084 className: "block-editor-block-variation-picker__skip" 55085 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 55086 variant: "link", 55087 onClick: () => onSelect() 55088 }, (0,external_wp_i18n_namespaceObject.__)('Skip')))); 55089 } 55090 /* harmony default export */ const block_variation_picker = (BlockVariationPicker); 55091 55092 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/grid.js 55093 55094 /** 55095 * WordPress dependencies 55096 */ 55097 55098 const grid_grid = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 55099 xmlns: "http://www.w3.org/2000/svg", 55100 viewBox: "0 0 24 24" 55101 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 55102 d: "m3 5c0-1.10457.89543-2 2-2h13.5c1.1046 0 2 .89543 2 2v13.5c0 1.1046-.8954 2-2 2h-13.5c-1.10457 0-2-.8954-2-2zm2-.5h6v6.5h-6.5v-6c0-.27614.22386-.5.5-.5zm-.5 8v6c0 .2761.22386.5.5.5h6v-6.5zm8 0v6.5h6c.2761 0 .5-.2239.5-.5v-6zm0-8v6.5h6.5v-6c0-.27614-.2239-.5-.5-.5z", 55103 fillRule: "evenodd", 55104 clipRule: "evenodd" 55105 })); 55106 /* harmony default export */ const library_grid = (grid_grid); 55107 55108 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-pattern-setup/constants.js 55109 const VIEWMODES = { 55110 carousel: 'carousel', 55111 grid: 'grid' 55112 }; 55113 55114 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-pattern-setup/setup-toolbar.js 55115 55116 /** 55117 * WordPress dependencies 55118 */ 55119 55120 55121 55122 55123 /** 55124 * Internal dependencies 55125 */ 55126 55127 const Actions = ({ 55128 onBlockPatternSelect 55129 }) => (0,external_React_.createElement)("div", { 55130 className: "block-editor-block-pattern-setup__actions" 55131 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 55132 variant: "primary", 55133 onClick: onBlockPatternSelect 55134 }, (0,external_wp_i18n_namespaceObject.__)('Choose'))); 55135 const CarouselNavigation = ({ 55136 handlePrevious, 55137 handleNext, 55138 activeSlide, 55139 totalSlides 55140 }) => (0,external_React_.createElement)("div", { 55141 className: "block-editor-block-pattern-setup__navigation" 55142 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 55143 icon: chevron_left, 55144 label: (0,external_wp_i18n_namespaceObject.__)('Previous pattern'), 55145 onClick: handlePrevious, 55146 disabled: activeSlide === 0, 55147 __experimentalIsFocusable: true 55148 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 55149 icon: chevron_right, 55150 label: (0,external_wp_i18n_namespaceObject.__)('Next pattern'), 55151 onClick: handleNext, 55152 disabled: activeSlide === totalSlides - 1, 55153 __experimentalIsFocusable: true 55154 })); 55155 const SetupToolbar = ({ 55156 viewMode, 55157 setViewMode, 55158 handlePrevious, 55159 handleNext, 55160 activeSlide, 55161 totalSlides, 55162 onBlockPatternSelect 55163 }) => { 55164 const isCarouselView = viewMode === VIEWMODES.carousel; 55165 const displayControls = (0,external_React_.createElement)("div", { 55166 className: "block-editor-block-pattern-setup__display-controls" 55167 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 55168 icon: stretch_full_width, 55169 label: (0,external_wp_i18n_namespaceObject.__)('Carousel view'), 55170 onClick: () => setViewMode(VIEWMODES.carousel), 55171 isPressed: isCarouselView 55172 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 55173 icon: library_grid, 55174 label: (0,external_wp_i18n_namespaceObject.__)('Grid view'), 55175 onClick: () => setViewMode(VIEWMODES.grid), 55176 isPressed: viewMode === VIEWMODES.grid 55177 })); 55178 return (0,external_React_.createElement)("div", { 55179 className: "block-editor-block-pattern-setup__toolbar" 55180 }, isCarouselView && (0,external_React_.createElement)(CarouselNavigation, { 55181 handlePrevious: handlePrevious, 55182 handleNext: handleNext, 55183 activeSlide: activeSlide, 55184 totalSlides: totalSlides 55185 }), displayControls, isCarouselView && (0,external_React_.createElement)(Actions, { 55186 onBlockPatternSelect: onBlockPatternSelect 55187 })); 55188 }; 55189 /* harmony default export */ const setup_toolbar = (SetupToolbar); 55190 55191 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-pattern-setup/use-patterns-setup.js 55192 /** 55193 * WordPress dependencies 55194 */ 55195 55196 55197 /** 55198 * Internal dependencies 55199 */ 55200 55201 function usePatternsSetup(clientId, blockName, filterPatternsFn) { 55202 return (0,external_wp_data_namespaceObject.useSelect)(select => { 55203 const { 55204 getBlockRootClientId, 55205 getPatternsByBlockTypes, 55206 __experimentalGetAllowedPatterns 55207 } = select(store); 55208 const rootClientId = getBlockRootClientId(clientId); 55209 if (filterPatternsFn) { 55210 return __experimentalGetAllowedPatterns(rootClientId).filter(filterPatternsFn); 55211 } 55212 return getPatternsByBlockTypes(blockName, rootClientId); 55213 }, [clientId, blockName, filterPatternsFn]); 55214 } 55215 /* harmony default export */ const use_patterns_setup = (usePatternsSetup); 55216 55217 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-pattern-setup/index.js 55218 55219 /** 55220 * WordPress dependencies 55221 */ 55222 55223 55224 55225 55226 55227 55228 55229 /** 55230 * Internal dependencies 55231 */ 55232 55233 55234 55235 55236 55237 55238 const { 55239 CompositeV2: block_pattern_setup_Composite, 55240 CompositeItemV2: block_pattern_setup_CompositeItem, 55241 useCompositeStoreV2: block_pattern_setup_useCompositeStore 55242 } = unlock(external_wp_components_namespaceObject.privateApis); 55243 const SetupContent = ({ 55244 viewMode, 55245 activeSlide, 55246 patterns, 55247 onBlockPatternSelect, 55248 showTitles 55249 }) => { 55250 const compositeStore = block_pattern_setup_useCompositeStore(); 55251 const containerClass = 'block-editor-block-pattern-setup__container'; 55252 if (viewMode === VIEWMODES.carousel) { 55253 const slideClass = new Map([[activeSlide, 'active-slide'], [activeSlide - 1, 'previous-slide'], [activeSlide + 1, 'next-slide']]); 55254 return (0,external_React_.createElement)("div", { 55255 className: "block-editor-block-pattern-setup__carousel" 55256 }, (0,external_React_.createElement)("div", { 55257 className: containerClass 55258 }, (0,external_React_.createElement)("div", { 55259 className: "carousel-container" 55260 }, patterns.map((pattern, index) => (0,external_React_.createElement)(BlockPatternSlide, { 55261 active: index === activeSlide, 55262 className: slideClass.get(index) || '', 55263 key: pattern.name, 55264 pattern: pattern 55265 }))))); 55266 } 55267 return (0,external_React_.createElement)("div", { 55268 className: "block-editor-block-pattern-setup__grid" 55269 }, (0,external_React_.createElement)(block_pattern_setup_Composite, { 55270 store: compositeStore, 55271 role: "listbox", 55272 className: containerClass, 55273 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Patterns list') 55274 }, patterns.map(pattern => (0,external_React_.createElement)(block_pattern_setup_BlockPattern, { 55275 key: pattern.name, 55276 pattern: pattern, 55277 onSelect: onBlockPatternSelect, 55278 showTitles: showTitles 55279 })))); 55280 }; 55281 function block_pattern_setup_BlockPattern({ 55282 pattern, 55283 onSelect, 55284 showTitles 55285 }) { 55286 const baseClassName = 'block-editor-block-pattern-setup-list'; 55287 const { 55288 blocks, 55289 description, 55290 viewportWidth = 700 55291 } = pattern; 55292 const descriptionId = (0,external_wp_compose_namespaceObject.useInstanceId)(block_pattern_setup_BlockPattern, `$baseClassName}__item-description`); 55293 return (0,external_React_.createElement)("div", { 55294 className: `$baseClassName}__list-item` 55295 }, (0,external_React_.createElement)(block_pattern_setup_CompositeItem, { 55296 render: (0,external_React_.createElement)("div", { 55297 "aria-describedby": description ? descriptionId : undefined, 55298 "aria-label": pattern.title, 55299 className: `$baseClassName}__item` 55300 }), 55301 id: `$baseClassName}__pattern__$pattern.name}`, 55302 role: "option", 55303 onClick: () => onSelect(blocks) 55304 }, (0,external_React_.createElement)(block_preview, { 55305 blocks: blocks, 55306 viewportWidth: viewportWidth 55307 }), showTitles && (0,external_React_.createElement)("div", { 55308 className: `$baseClassName}__item-title` 55309 }, pattern.title), !!description && (0,external_React_.createElement)(external_wp_components_namespaceObject.VisuallyHidden, { 55310 id: descriptionId 55311 }, description))); 55312 } 55313 function BlockPatternSlide({ 55314 active, 55315 className, 55316 pattern, 55317 minHeight 55318 }) { 55319 const { 55320 blocks, 55321 title, 55322 description 55323 } = pattern; 55324 const descriptionId = (0,external_wp_compose_namespaceObject.useInstanceId)(BlockPatternSlide, 'block-editor-block-pattern-setup-list__item-description'); 55325 return (0,external_React_.createElement)("div", { 55326 "aria-hidden": !active, 55327 role: "img", 55328 className: `pattern-slide $className}`, 55329 "aria-label": title, 55330 "aria-describedby": description ? descriptionId : undefined 55331 }, (0,external_React_.createElement)(block_preview, { 55332 blocks: blocks, 55333 minHeight: minHeight 55334 }), !!description && (0,external_React_.createElement)(external_wp_components_namespaceObject.VisuallyHidden, { 55335 id: descriptionId 55336 }, description)); 55337 } 55338 const BlockPatternSetup = ({ 55339 clientId, 55340 blockName, 55341 filterPatternsFn, 55342 onBlockPatternSelect, 55343 initialViewMode = VIEWMODES.carousel, 55344 showTitles = false 55345 }) => { 55346 const [viewMode, setViewMode] = (0,external_wp_element_namespaceObject.useState)(initialViewMode); 55347 const [activeSlide, setActiveSlide] = (0,external_wp_element_namespaceObject.useState)(0); 55348 const { 55349 replaceBlock 55350 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 55351 const patterns = use_patterns_setup(clientId, blockName, filterPatternsFn); 55352 if (!patterns?.length) { 55353 return null; 55354 } 55355 const onBlockPatternSelectDefault = blocks => { 55356 const clonedBlocks = blocks.map(block => (0,external_wp_blocks_namespaceObject.cloneBlock)(block)); 55357 replaceBlock(clientId, clonedBlocks); 55358 }; 55359 const onPatternSelectCallback = onBlockPatternSelect || onBlockPatternSelectDefault; 55360 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)("div", { 55361 className: `block-editor-block-pattern-setup view-mode-$viewMode}` 55362 }, (0,external_React_.createElement)(SetupContent, { 55363 viewMode: viewMode, 55364 activeSlide: activeSlide, 55365 patterns: patterns, 55366 onBlockPatternSelect: onPatternSelectCallback, 55367 showTitles: showTitles 55368 }), (0,external_React_.createElement)(setup_toolbar, { 55369 viewMode: viewMode, 55370 setViewMode: setViewMode, 55371 activeSlide: activeSlide, 55372 totalSlides: patterns.length, 55373 handleNext: () => { 55374 setActiveSlide(active => Math.min(active + 1, patterns.length - 1)); 55375 }, 55376 handlePrevious: () => { 55377 setActiveSlide(active => Math.max(active - 1, 0)); 55378 }, 55379 onBlockPatternSelect: () => { 55380 onPatternSelectCallback(patterns[activeSlide].blocks); 55381 } 55382 }))); 55383 }; 55384 /* harmony default export */ const block_pattern_setup = (BlockPatternSetup); 55385 55386 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-variation-transforms/index.js 55387 55388 /** 55389 * WordPress dependencies 55390 */ 55391 55392 55393 55394 55395 55396 55397 55398 /** 55399 * Internal dependencies 55400 */ 55401 55402 55403 function VariationsButtons({ 55404 className, 55405 onSelectVariation, 55406 selectedValue, 55407 variations 55408 }) { 55409 return (0,external_React_.createElement)("fieldset", { 55410 className: className 55411 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.VisuallyHidden, { 55412 as: "legend" 55413 }, (0,external_wp_i18n_namespaceObject.__)('Transform to variation')), variations.map(variation => (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 55414 key: variation.name, 55415 icon: (0,external_React_.createElement)(block_icon, { 55416 icon: variation.icon, 55417 showColors: true 55418 }), 55419 isPressed: selectedValue === variation.name, 55420 label: selectedValue === variation.name ? variation.title : (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: Name of the block variation */ 55421 (0,external_wp_i18n_namespaceObject.__)('Transform to %s'), variation.title), 55422 onClick: () => onSelectVariation(variation.name), 55423 "aria-label": variation.title, 55424 showTooltip: true 55425 }))); 55426 } 55427 function VariationsDropdown({ 55428 className, 55429 onSelectVariation, 55430 selectedValue, 55431 variations 55432 }) { 55433 const selectOptions = variations.map(({ 55434 name, 55435 title, 55436 description 55437 }) => ({ 55438 value: name, 55439 label: title, 55440 info: description 55441 })); 55442 return (0,external_React_.createElement)(external_wp_components_namespaceObject.DropdownMenu, { 55443 className: className, 55444 label: (0,external_wp_i18n_namespaceObject.__)('Transform to variation'), 55445 text: (0,external_wp_i18n_namespaceObject.__)('Transform to variation'), 55446 popoverProps: { 55447 position: 'bottom center', 55448 className: `$className}__popover` 55449 }, 55450 icon: chevron_down, 55451 toggleProps: { 55452 iconPosition: 'right' 55453 } 55454 }, () => (0,external_React_.createElement)("div", { 55455 className: `$className}__container` 55456 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuGroup, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItemsChoice, { 55457 choices: selectOptions, 55458 value: selectedValue, 55459 onSelect: onSelectVariation 55460 })))); 55461 } 55462 function VariationsToggleGroupControl({ 55463 className, 55464 onSelectVariation, 55465 selectedValue, 55466 variations 55467 }) { 55468 return (0,external_React_.createElement)("div", { 55469 className: className 55470 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToggleGroupControl, { 55471 label: (0,external_wp_i18n_namespaceObject.__)('Transform to variation'), 55472 value: selectedValue, 55473 hideLabelFromVision: true, 55474 onChange: onSelectVariation, 55475 __next40pxDefaultSize: true, 55476 __nextHasNoMarginBottom: true 55477 }, variations.map(variation => (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOptionIcon, { 55478 key: variation.name, 55479 icon: variation.icon, 55480 value: variation.name, 55481 label: selectedValue === variation.name ? variation.title : (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: Name of the block variation */ 55482 (0,external_wp_i18n_namespaceObject.__)('Transform to %s'), variation.title) 55483 })))); 55484 } 55485 function __experimentalBlockVariationTransforms({ 55486 blockClientId 55487 }) { 55488 const { 55489 updateBlockAttributes 55490 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 55491 const { 55492 activeBlockVariation, 55493 variations 55494 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 55495 const { 55496 getActiveBlockVariation, 55497 getBlockVariations 55498 } = select(external_wp_blocks_namespaceObject.store); 55499 const { 55500 getBlockName, 55501 getBlockAttributes 55502 } = select(store); 55503 const name = blockClientId && getBlockName(blockClientId); 55504 return { 55505 activeBlockVariation: getActiveBlockVariation(name, getBlockAttributes(blockClientId)), 55506 variations: name && getBlockVariations(name, 'transform') 55507 }; 55508 }, [blockClientId]); 55509 const selectedValue = activeBlockVariation?.name; 55510 55511 // Check if each variation has a unique icon. 55512 const hasUniqueIcons = (0,external_wp_element_namespaceObject.useMemo)(() => { 55513 const variationIcons = new Set(); 55514 if (!variations) { 55515 return false; 55516 } 55517 variations.forEach(variation => { 55518 if (variation.icon) { 55519 variationIcons.add(variation.icon?.src || variation.icon); 55520 } 55521 }); 55522 return variationIcons.size === variations.length; 55523 }, [variations]); 55524 const onSelectVariation = variationName => { 55525 updateBlockAttributes(blockClientId, { 55526 ...variations.find(({ 55527 name 55528 }) => name === variationName).attributes 55529 }); 55530 }; 55531 55532 // Skip rendering if there are no variations 55533 if (!variations?.length) return null; 55534 const baseClass = 'block-editor-block-variation-transforms'; 55535 55536 // Show buttons if there are more than 5 variations because the ToggleGroupControl does not wrap 55537 const showButtons = variations.length > 5; 55538 const ButtonComponent = showButtons ? VariationsButtons : VariationsToggleGroupControl; 55539 const Component = hasUniqueIcons ? ButtonComponent : VariationsDropdown; 55540 return (0,external_React_.createElement)(Component, { 55541 className: baseClass, 55542 onSelectVariation: onSelectVariation, 55543 selectedValue: selectedValue, 55544 variations: variations 55545 }); 55546 } 55547 /* harmony default export */ const block_variation_transforms = (__experimentalBlockVariationTransforms); 55548 55549 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/color-palette/with-color-context.js 55550 55551 /** 55552 * WordPress dependencies 55553 */ 55554 55555 55556 /** 55557 * Internal dependencies 55558 */ 55559 55560 /* harmony default export */ const with_color_context = ((0,external_wp_compose_namespaceObject.createHigherOrderComponent)(WrappedComponent => { 55561 return props => { 55562 const [colorsFeature, enableCustomColors] = use_settings_useSettings('color.palette', 'color.custom'); 55563 const { 55564 colors = colorsFeature, 55565 disableCustomColors = !enableCustomColors 55566 } = props; 55567 const hasColorsToChoose = colors && colors.length > 0 || !disableCustomColors; 55568 return (0,external_React_.createElement)(WrappedComponent, { 55569 ...props, 55570 colors, 55571 disableCustomColors, 55572 hasColorsToChoose 55573 }); 55574 }; 55575 }, 'withColorContext')); 55576 55577 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/color-palette/index.js 55578 /** 55579 * WordPress dependencies 55580 */ 55581 55582 55583 /** 55584 * Internal dependencies 55585 */ 55586 55587 /* harmony default export */ const color_palette = (with_color_context(external_wp_components_namespaceObject.ColorPalette)); 55588 55589 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/color-palette/control.js 55590 55591 /** 55592 * Internal dependencies 55593 */ 55594 55595 function ColorPaletteControl({ 55596 onChange, 55597 value, 55598 ...otherProps 55599 }) { 55600 return (0,external_React_.createElement)(control, { 55601 ...otherProps, 55602 onColorChange: onChange, 55603 colorValue: value, 55604 gradients: [], 55605 disableCustomGradients: true 55606 }); 55607 } 55608 55609 ;// CONCATENATED MODULE: external ["wp","date"] 55610 const external_wp_date_namespaceObject = window["wp"]["date"]; 55611 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/date-format-picker/index.js 55612 55613 /** 55614 * WordPress dependencies 55615 */ 55616 55617 55618 55619 55620 55621 // So that we can illustrate the different formats in the dropdown properly, 55622 // show a date that has a day greater than 12 and a month with more than three 55623 // letters. Here we're using 2022-01-25 which is when WordPress 5.9 was 55624 // released. 55625 const EXAMPLE_DATE = new Date(2022, 0, 25); 55626 55627 /** 55628 * The `DateFormatPicker` component renders controls that let the user choose a 55629 * _date format_. That is, how they want their dates to be formatted. 55630 * 55631 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/date-format-picker/README.md 55632 * 55633 * @param {Object} props 55634 * @param {string|null} props.format The selected date 55635 * format. If 55636 * `null`, 55637 * _Default_ is 55638 * selected. 55639 * @param {string} props.defaultFormat The date format that 55640 * will be used if the 55641 * user selects 55642 * 'Default'. 55643 * @param {( format: string|null ) => void} props.onChange Called when a 55644 * selection is 55645 * made. If `null`, 55646 * _Default_ is 55647 * selected. 55648 */ 55649 function DateFormatPicker({ 55650 format, 55651 defaultFormat, 55652 onChange 55653 }) { 55654 return (0,external_React_.createElement)("fieldset", { 55655 className: "block-editor-date-format-picker" 55656 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.VisuallyHidden, { 55657 as: "legend" 55658 }, (0,external_wp_i18n_namespaceObject.__)('Date format')), (0,external_React_.createElement)(external_wp_components_namespaceObject.ToggleControl, { 55659 __nextHasNoMarginBottom: true, 55660 label: (0,external_wp_i18n_namespaceObject.__)('Default format'), 55661 help: `${(0,external_wp_i18n_namespaceObject.__)('Example:')} ${(0,external_wp_date_namespaceObject.dateI18n)(defaultFormat, EXAMPLE_DATE)}`, 55662 checked: !format, 55663 onChange: checked => onChange(checked ? null : defaultFormat) 55664 }), format && (0,external_React_.createElement)(NonDefaultControls, { 55665 format: format, 55666 onChange: onChange 55667 })); 55668 } 55669 function NonDefaultControls({ 55670 format, 55671 onChange 55672 }) { 55673 var _suggestedOptions$fin; 55674 // Suggest a short format, medium format, long format, and a standardised 55675 // (YYYY-MM-DD) format. The short, medium, and long formats are localised as 55676 // different languages have different ways of writing these. For example, 'F 55677 // j, Y' (April 20, 2022) in American English (en_US) is 'j. F Y' (20. April 55678 // 2022) in German (de). The resultant array is de-duplicated as some 55679 // languages will use the same format string for short, medium, and long 55680 // formats. 55681 const suggestedFormats = [...new Set([/* translators: See https://www.php.net/manual/datetime.format.php */ 55682 'Y-m-d', /* translators: See https://www.php.net/manual/datetime.format.php */ 55683 (0,external_wp_i18n_namespaceObject._x)('n/j/Y', 'short date format'), /* translators: See https://www.php.net/manual/datetime.format.php */ 55684 (0,external_wp_i18n_namespaceObject._x)('n/j/Y g:i A', 'short date format with time'), /* translators: See https://www.php.net/manual/datetime.format.php */ 55685 (0,external_wp_i18n_namespaceObject._x)('M j, Y', 'medium date format'), /* translators: See https://www.php.net/manual/datetime.format.php */ 55686 (0,external_wp_i18n_namespaceObject._x)('M j, Y g:i A', 'medium date format with time'), /* translators: See https://www.php.net/manual/datetime.format.php */ 55687 (0,external_wp_i18n_namespaceObject._x)('F j, Y', 'long date format'), /* translators: See https://www.php.net/manual/datetime.format.php */ 55688 (0,external_wp_i18n_namespaceObject._x)('M j', 'short date format without the year')])]; 55689 const suggestedOptions = suggestedFormats.map((suggestedFormat, index) => ({ 55690 key: `suggested-$index}`, 55691 name: (0,external_wp_date_namespaceObject.dateI18n)(suggestedFormat, EXAMPLE_DATE), 55692 format: suggestedFormat 55693 })); 55694 const customOption = { 55695 key: 'custom', 55696 name: (0,external_wp_i18n_namespaceObject.__)('Custom'), 55697 className: 'block-editor-date-format-picker__custom-format-select-control__custom-option', 55698 __experimentalHint: (0,external_wp_i18n_namespaceObject.__)('Enter your own date format') 55699 }; 55700 const [isCustom, setIsCustom] = (0,external_wp_element_namespaceObject.useState)(() => !!format && !suggestedFormats.includes(format)); 55701 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalVStack, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.CustomSelectControl, { 55702 __nextUnconstrainedWidth: true, 55703 label: (0,external_wp_i18n_namespaceObject.__)('Choose a format'), 55704 options: [...suggestedOptions, customOption], 55705 value: isCustom ? customOption : (_suggestedOptions$fin = suggestedOptions.find(option => option.format === format)) !== null && _suggestedOptions$fin !== void 0 ? _suggestedOptions$fin : customOption, 55706 onChange: ({ 55707 selectedItem 55708 }) => { 55709 if (selectedItem === customOption) { 55710 setIsCustom(true); 55711 } else { 55712 setIsCustom(false); 55713 onChange(selectedItem.format); 55714 } 55715 } 55716 }), isCustom && (0,external_React_.createElement)(external_wp_components_namespaceObject.TextControl, { 55717 __nextHasNoMarginBottom: true, 55718 label: (0,external_wp_i18n_namespaceObject.__)('Custom format'), 55719 hideLabelFromVision: true, 55720 help: (0,external_wp_element_namespaceObject.createInterpolateElement)((0,external_wp_i18n_namespaceObject.__)('Enter a date or time <Link>format string</Link>.'), { 55721 Link: (0,external_React_.createElement)(external_wp_components_namespaceObject.ExternalLink, { 55722 href: (0,external_wp_i18n_namespaceObject.__)('https://wordpress.org/documentation/article/customize-date-and-time-format/') 55723 }) 55724 }), 55725 value: format, 55726 onChange: value => onChange(value) 55727 })); 55728 } 55729 55730 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/colors-gradients/dropdown.js 55731 55732 /** 55733 * External dependencies 55734 */ 55735 55736 55737 /** 55738 * WordPress dependencies 55739 */ 55740 55741 55742 /** 55743 * Internal dependencies 55744 */ 55745 55746 55747 // When the `ColorGradientSettingsDropdown` controls are being rendered to a 55748 // `ToolsPanel` they must be wrapped in a `ToolsPanelItem`. 55749 const WithToolsPanelItem = ({ 55750 setting, 55751 children, 55752 panelId, 55753 ...props 55754 }) => { 55755 const clearValue = () => { 55756 if (setting.colorValue) { 55757 setting.onColorChange(); 55758 } else if (setting.gradientValue) { 55759 setting.onGradientChange(); 55760 } 55761 }; 55762 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 55763 hasValue: () => { 55764 return !!setting.colorValue || !!setting.gradientValue; 55765 }, 55766 label: setting.label, 55767 onDeselect: clearValue, 55768 isShownByDefault: setting.isShownByDefault !== undefined ? setting.isShownByDefault : true, 55769 ...props, 55770 className: "block-editor-tools-panel-color-gradient-settings__item", 55771 panelId: panelId 55772 // Pass resetAllFilter if supplied due to rendering via SlotFill 55773 // into parent ToolsPanel. 55774 , 55775 resetAllFilter: setting.resetAllFilter 55776 }, children); 55777 }; 55778 const dropdown_LabeledColorIndicator = ({ 55779 colorValue, 55780 label 55781 }) => (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, { 55782 justify: "flex-start" 55783 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.ColorIndicator, { 55784 className: "block-editor-panel-color-gradient-settings__color-indicator", 55785 colorValue: colorValue 55786 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexItem, { 55787 className: "block-editor-panel-color-gradient-settings__color-name", 55788 title: label 55789 }, label)); 55790 55791 // Renders a color dropdown's toggle as an `Item` if it is within an `ItemGroup` 55792 // or as a `Button` if it isn't e.g. the controls are being rendered in 55793 // a `ToolsPanel`. 55794 const renderToggle = settings => ({ 55795 onToggle, 55796 isOpen 55797 }) => { 55798 const { 55799 colorValue, 55800 label 55801 } = settings; 55802 const toggleProps = { 55803 onClick: onToggle, 55804 className: classnames_default()('block-editor-panel-color-gradient-settings__dropdown', { 55805 'is-open': isOpen 55806 }), 55807 'aria-expanded': isOpen 55808 }; 55809 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 55810 ...toggleProps 55811 }, (0,external_React_.createElement)(dropdown_LabeledColorIndicator, { 55812 colorValue: colorValue, 55813 label: label 55814 })); 55815 }; 55816 55817 // Renders a collection of color controls as dropdowns. Depending upon the 55818 // context in which these dropdowns are being rendered, they may be wrapped 55819 // in an `ItemGroup` with each dropdown's toggle as an `Item`, or alternatively, 55820 // the may be individually wrapped in a `ToolsPanelItem` with the toggle as 55821 // a regular `Button`. 55822 // 55823 // For more context see: https://github.com/WordPress/gutenberg/pull/40084 55824 function ColorGradientSettingsDropdown({ 55825 colors, 55826 disableCustomColors, 55827 disableCustomGradients, 55828 enableAlpha, 55829 gradients, 55830 settings, 55831 __experimentalIsRenderedInSidebar, 55832 ...props 55833 }) { 55834 let popoverProps; 55835 if (__experimentalIsRenderedInSidebar) { 55836 popoverProps = { 55837 placement: 'left-start', 55838 offset: 36, 55839 shift: true 55840 }; 55841 } 55842 return (0,external_React_.createElement)(external_React_.Fragment, null, settings.map((setting, index) => { 55843 var _setting$gradientValu; 55844 const controlProps = { 55845 clearable: false, 55846 colorValue: setting.colorValue, 55847 colors, 55848 disableCustomColors, 55849 disableCustomGradients, 55850 enableAlpha, 55851 gradientValue: setting.gradientValue, 55852 gradients, 55853 label: setting.label, 55854 onColorChange: setting.onColorChange, 55855 onGradientChange: setting.onGradientChange, 55856 showTitle: false, 55857 __experimentalIsRenderedInSidebar, 55858 ...setting 55859 }; 55860 const toggleSettings = { 55861 colorValue: (_setting$gradientValu = setting.gradientValue) !== null && _setting$gradientValu !== void 0 ? _setting$gradientValu : setting.colorValue, 55862 label: setting.label 55863 }; 55864 return setting && 55865 // If not in an `ItemGroup` wrap the dropdown in a 55866 // `ToolsPanelItem` 55867 (0,external_React_.createElement)(WithToolsPanelItem, { 55868 key: index, 55869 setting: setting, 55870 ...props 55871 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Dropdown, { 55872 popoverProps: popoverProps, 55873 className: "block-editor-tools-panel-color-gradient-settings__dropdown", 55874 renderToggle: renderToggle(toggleSettings), 55875 renderContent: () => (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalDropdownContentWrapper, { 55876 paddingSize: "none" 55877 }, (0,external_React_.createElement)("div", { 55878 className: "block-editor-panel-color-gradient-settings__dropdown-content" 55879 }, (0,external_React_.createElement)(control, { 55880 ...controlProps 55881 }))) 55882 })); 55883 })); 55884 } 55885 55886 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/colors-gradients/panel-color-gradient-settings.js 55887 55888 /** 55889 * External dependencies 55890 */ 55891 55892 55893 /** 55894 * WordPress dependencies 55895 */ 55896 55897 55898 55899 55900 /** 55901 * Internal dependencies 55902 */ 55903 55904 55905 const panel_color_gradient_settings_colorsAndGradientKeys = ['colors', 'disableCustomColors', 'gradients', 'disableCustomGradients']; 55906 const PanelColorGradientSettingsInner = ({ 55907 className, 55908 colors, 55909 gradients, 55910 disableCustomColors, 55911 disableCustomGradients, 55912 children, 55913 settings, 55914 title, 55915 showTitle = true, 55916 __experimentalIsRenderedInSidebar, 55917 enableAlpha 55918 }) => { 55919 const panelId = (0,external_wp_compose_namespaceObject.useInstanceId)(PanelColorGradientSettingsInner); 55920 const { 55921 batch 55922 } = (0,external_wp_data_namespaceObject.useRegistry)(); 55923 if ((!colors || colors.length === 0) && (!gradients || gradients.length === 0) && disableCustomColors && disableCustomGradients && settings?.every(setting => (!setting.colors || setting.colors.length === 0) && (!setting.gradients || setting.gradients.length === 0) && (setting.disableCustomColors === undefined || setting.disableCustomColors) && (setting.disableCustomGradients === undefined || setting.disableCustomGradients))) { 55924 return null; 55925 } 55926 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanel, { 55927 className: classnames_default()('block-editor-panel-color-gradient-settings', className), 55928 label: showTitle ? title : undefined, 55929 resetAll: () => { 55930 batch(() => { 55931 settings.forEach(({ 55932 colorValue, 55933 gradientValue, 55934 onColorChange, 55935 onGradientChange 55936 }) => { 55937 if (colorValue) { 55938 onColorChange(); 55939 } else if (gradientValue) { 55940 onGradientChange(); 55941 } 55942 }); 55943 }); 55944 }, 55945 panelId: panelId, 55946 __experimentalFirstVisibleItemClass: "first", 55947 __experimentalLastVisibleItemClass: "last" 55948 }, (0,external_React_.createElement)(ColorGradientSettingsDropdown, { 55949 settings: settings, 55950 panelId: panelId, 55951 colors, 55952 gradients, 55953 disableCustomColors, 55954 disableCustomGradients, 55955 __experimentalIsRenderedInSidebar, 55956 enableAlpha 55957 }), !!children && (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalSpacer, { 55958 marginY: 4 55959 }), " ", children)); 55960 }; 55961 const PanelColorGradientSettingsSelect = props => { 55962 const colorGradientSettings = useMultipleOriginColorsAndGradients(); 55963 return (0,external_React_.createElement)(PanelColorGradientSettingsInner, { 55964 ...colorGradientSettings, 55965 ...props 55966 }); 55967 }; 55968 const PanelColorGradientSettings = props => { 55969 if (panel_color_gradient_settings_colorsAndGradientKeys.every(key => props.hasOwnProperty(key))) { 55970 return (0,external_React_.createElement)(PanelColorGradientSettingsInner, { 55971 ...props 55972 }); 55973 } 55974 return (0,external_React_.createElement)(PanelColorGradientSettingsSelect, { 55975 ...props 55976 }); 55977 }; 55978 /* harmony default export */ const panel_color_gradient_settings = (PanelColorGradientSettings); 55979 55980 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/image-editor/use-save-image.js 55981 /** 55982 * WordPress dependencies 55983 */ 55984 // Disable Reason: Needs to be refactored. 55985 // eslint-disable-next-line no-restricted-imports 55986 55987 55988 55989 55990 55991 55992 function useSaveImage({ 55993 crop, 55994 rotation, 55995 url, 55996 id, 55997 onSaveImage, 55998 onFinishEditing 55999 }) { 56000 const { 56001 createErrorNotice 56002 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_notices_namespaceObject.store); 56003 const [isInProgress, setIsInProgress] = (0,external_wp_element_namespaceObject.useState)(false); 56004 const cancel = (0,external_wp_element_namespaceObject.useCallback)(() => { 56005 setIsInProgress(false); 56006 onFinishEditing(); 56007 }, [onFinishEditing]); 56008 const apply = (0,external_wp_element_namespaceObject.useCallback)(() => { 56009 setIsInProgress(true); 56010 const modifiers = []; 56011 if (rotation > 0) { 56012 modifiers.push({ 56013 type: 'rotate', 56014 args: { 56015 angle: rotation 56016 } 56017 }); 56018 } 56019 56020 // The crop script may return some very small, sub-pixel values when the image was not cropped. 56021 // Crop only when the new size has changed by more than 0.1%. 56022 if (crop.width < 99.9 || crop.height < 99.9) { 56023 modifiers.push({ 56024 type: 'crop', 56025 args: { 56026 left: crop.x, 56027 top: crop.y, 56028 width: crop.width, 56029 height: crop.height 56030 } 56031 }); 56032 } 56033 external_wp_apiFetch_default()({ 56034 path: `/wp/v2/media/$id}/edit`, 56035 method: 'POST', 56036 data: { 56037 src: url, 56038 modifiers 56039 } 56040 }).then(response => { 56041 onSaveImage({ 56042 id: response.id, 56043 url: response.source_url 56044 }); 56045 }).catch(error => { 56046 createErrorNotice((0,external_wp_i18n_namespaceObject.sprintf)( /* translators: 1. Error message */ 56047 (0,external_wp_i18n_namespaceObject.__)('Could not edit image. %s'), (0,external_wp_dom_namespaceObject.__unstableStripHTML)(error.message)), { 56048 id: 'image-editing-error', 56049 type: 'snackbar' 56050 }); 56051 }).finally(() => { 56052 setIsInProgress(false); 56053 onFinishEditing(); 56054 }); 56055 }, [crop, rotation, id, url, onSaveImage, createErrorNotice, onFinishEditing]); 56056 return (0,external_wp_element_namespaceObject.useMemo)(() => ({ 56057 isInProgress, 56058 apply, 56059 cancel 56060 }), [isInProgress, apply, cancel]); 56061 } 56062 56063 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/image-editor/use-transform-image.js 56064 /** 56065 * WordPress dependencies 56066 */ 56067 56068 56069 function useTransformImage({ 56070 url, 56071 naturalWidth, 56072 naturalHeight 56073 }) { 56074 const [editedUrl, setEditedUrl] = (0,external_wp_element_namespaceObject.useState)(); 56075 const [crop, setCrop] = (0,external_wp_element_namespaceObject.useState)(); 56076 const [position, setPosition] = (0,external_wp_element_namespaceObject.useState)({ 56077 x: 0, 56078 y: 0 56079 }); 56080 const [zoom, setZoom] = (0,external_wp_element_namespaceObject.useState)(100); 56081 const [rotation, setRotation] = (0,external_wp_element_namespaceObject.useState)(0); 56082 const defaultAspect = naturalWidth / naturalHeight; 56083 const [aspect, setAspect] = (0,external_wp_element_namespaceObject.useState)(defaultAspect); 56084 const rotateClockwise = (0,external_wp_element_namespaceObject.useCallback)(() => { 56085 const angle = (rotation + 90) % 360; 56086 let naturalAspectRatio = defaultAspect; 56087 if (rotation % 180 === 90) { 56088 naturalAspectRatio = 1 / defaultAspect; 56089 } 56090 if (angle === 0) { 56091 setEditedUrl(); 56092 setRotation(angle); 56093 setAspect(defaultAspect); 56094 setPosition(prevPosition => ({ 56095 x: -(prevPosition.y * naturalAspectRatio), 56096 y: prevPosition.x * naturalAspectRatio 56097 })); 56098 return; 56099 } 56100 function editImage(event) { 56101 const canvas = document.createElement('canvas'); 56102 let translateX = 0; 56103 let translateY = 0; 56104 if (angle % 180) { 56105 canvas.width = event.target.height; 56106 canvas.height = event.target.width; 56107 } else { 56108 canvas.width = event.target.width; 56109 canvas.height = event.target.height; 56110 } 56111 if (angle === 90 || angle === 180) { 56112 translateX = canvas.width; 56113 } 56114 if (angle === 270 || angle === 180) { 56115 translateY = canvas.height; 56116 } 56117 const context = canvas.getContext('2d'); 56118 context.translate(translateX, translateY); 56119 context.rotate(angle * Math.PI / 180); 56120 context.drawImage(event.target, 0, 0); 56121 canvas.toBlob(blob => { 56122 setEditedUrl(URL.createObjectURL(blob)); 56123 setRotation(angle); 56124 setAspect(canvas.width / canvas.height); 56125 setPosition(prevPosition => ({ 56126 x: -(prevPosition.y * naturalAspectRatio), 56127 y: prevPosition.x * naturalAspectRatio 56128 })); 56129 }); 56130 } 56131 const el = new window.Image(); 56132 el.src = url; 56133 el.onload = editImage; 56134 const imgCrossOrigin = (0,external_wp_hooks_namespaceObject.applyFilters)('media.crossOrigin', undefined, url); 56135 if (typeof imgCrossOrigin === 'string') { 56136 el.crossOrigin = imgCrossOrigin; 56137 } 56138 }, [rotation, defaultAspect, url]); 56139 return (0,external_wp_element_namespaceObject.useMemo)(() => ({ 56140 editedUrl, 56141 setEditedUrl, 56142 crop, 56143 setCrop, 56144 position, 56145 setPosition, 56146 zoom, 56147 setZoom, 56148 rotation, 56149 setRotation, 56150 rotateClockwise, 56151 aspect, 56152 setAspect, 56153 defaultAspect 56154 }), [editedUrl, crop, position, zoom, rotation, rotateClockwise, aspect, defaultAspect]); 56155 } 56156 56157 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/image-editor/context.js 56158 56159 /** 56160 * WordPress dependencies 56161 */ 56162 56163 56164 /** 56165 * Internal dependencies 56166 */ 56167 56168 56169 const ImageEditingContext = (0,external_wp_element_namespaceObject.createContext)({}); 56170 const useImageEditingContext = () => (0,external_wp_element_namespaceObject.useContext)(ImageEditingContext); 56171 function ImageEditingProvider({ 56172 id, 56173 url, 56174 naturalWidth, 56175 naturalHeight, 56176 onFinishEditing, 56177 onSaveImage, 56178 children 56179 }) { 56180 const transformImage = useTransformImage({ 56181 url, 56182 naturalWidth, 56183 naturalHeight 56184 }); 56185 const saveImage = useSaveImage({ 56186 id, 56187 url, 56188 onSaveImage, 56189 onFinishEditing, 56190 ...transformImage 56191 }); 56192 const providerValue = (0,external_wp_element_namespaceObject.useMemo)(() => ({ 56193 ...transformImage, 56194 ...saveImage 56195 }), [transformImage, saveImage]); 56196 return (0,external_React_.createElement)(ImageEditingContext.Provider, { 56197 value: providerValue 56198 }, children); 56199 } 56200 56201 ;// CONCATENATED MODULE: ./node_modules/react-easy-crop/node_modules/tslib/tslib.es6.js 56202 /*! ***************************************************************************** 56203 Copyright (c) Microsoft Corporation. 56204 56205 Permission to use, copy, modify, and/or distribute this software for any 56206 purpose with or without fee is hereby granted. 56207 56208 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 56209 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 56210 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 56211 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 56212 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 56213 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 56214 PERFORMANCE OF THIS SOFTWARE. 56215 ***************************************************************************** */ 56216 /* global Reflect, Promise */ 56217 56218 var extendStatics = function(d, b) { 56219 extendStatics = Object.setPrototypeOf || 56220 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 56221 function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; 56222 return extendStatics(d, b); 56223 }; 56224 56225 function __extends(d, b) { 56226 extendStatics(d, b); 56227 function __() { this.constructor = d; } 56228 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 56229 } 56230 56231 var __assign = function() { 56232 __assign = Object.assign || function __assign(t) { 56233 for (var s, i = 1, n = arguments.length; i < n; i++) { 56234 s = arguments[i]; 56235 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 56236 } 56237 return t; 56238 } 56239 return __assign.apply(this, arguments); 56240 } 56241 56242 function __rest(s, e) { 56243 var t = {}; 56244 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) 56245 t[p] = s[p]; 56246 if (s != null && typeof Object.getOwnPropertySymbols === "function") 56247 for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { 56248 if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) 56249 t[p[i]] = s[p[i]]; 56250 } 56251 return t; 56252 } 56253 56254 function __decorate(decorators, target, key, desc) { 56255 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 56256 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 56257 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 56258 return c > 3 && r && Object.defineProperty(target, key, r), r; 56259 } 56260 56261 function __param(paramIndex, decorator) { 56262 return function (target, key) { decorator(target, key, paramIndex); } 56263 } 56264 56265 function __metadata(metadataKey, metadataValue) { 56266 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); 56267 } 56268 56269 function __awaiter(thisArg, _arguments, P, generator) { 56270 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 56271 return new (P || (P = Promise))(function (resolve, reject) { 56272 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 56273 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 56274 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 56275 step((generator = generator.apply(thisArg, _arguments || [])).next()); 56276 }); 56277 } 56278 56279 function __generator(thisArg, body) { 56280 var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; 56281 return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 56282 function verb(n) { return function (v) { return step([n, v]); }; } 56283 function step(op) { 56284 if (f) throw new TypeError("Generator is already executing."); 56285 while (_) try { 56286 if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; 56287 if (y = 0, t) op = [op[0] & 2, t.value]; 56288 switch (op[0]) { 56289 case 0: case 1: t = op; break; 56290 case 4: _.label++; return { value: op[1], done: false }; 56291 case 5: _.label++; y = op[1]; op = [0]; continue; 56292 case 7: op = _.ops.pop(); _.trys.pop(); continue; 56293 default: 56294 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 56295 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 56296 if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 56297 if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 56298 if (t[2]) _.ops.pop(); 56299 _.trys.pop(); continue; 56300 } 56301 op = body.call(thisArg, _); 56302 } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 56303 if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 56304 } 56305 } 56306 56307 var __createBinding = Object.create ? (function(o, m, k, k2) { 56308 if (k2 === undefined) k2 = k; 56309 Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); 56310 }) : (function(o, m, k, k2) { 56311 if (k2 === undefined) k2 = k; 56312 o[k2] = m[k]; 56313 }); 56314 56315 function __exportStar(m, o) { 56316 for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); 56317 } 56318 56319 function __values(o) { 56320 var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; 56321 if (m) return m.call(o); 56322 if (o && typeof o.length === "number") return { 56323 next: function () { 56324 if (o && i >= o.length) o = void 0; 56325 return { value: o && o[i++], done: !o }; 56326 } 56327 }; 56328 throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); 56329 } 56330 56331 function __read(o, n) { 56332 var m = typeof Symbol === "function" && o[Symbol.iterator]; 56333 if (!m) return o; 56334 var i = m.call(o), r, ar = [], e; 56335 try { 56336 while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); 56337 } 56338 catch (error) { e = { error: error }; } 56339 finally { 56340 try { 56341 if (r && !r.done && (m = i["return"])) m.call(i); 56342 } 56343 finally { if (e) throw e.error; } 56344 } 56345 return ar; 56346 } 56347 56348 function __spread() { 56349 for (var ar = [], i = 0; i < arguments.length; i++) 56350 ar = ar.concat(__read(arguments[i])); 56351 return ar; 56352 } 56353 56354 function __spreadArrays() { 56355 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; 56356 for (var r = Array(s), k = 0, i = 0; i < il; i++) 56357 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) 56358 r[k] = a[j]; 56359 return r; 56360 }; 56361 56362 function __await(v) { 56363 return this instanceof __await ? (this.v = v, this) : new __await(v); 56364 } 56365 56366 function __asyncGenerator(thisArg, _arguments, generator) { 56367 if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); 56368 var g = generator.apply(thisArg, _arguments || []), i, q = []; 56369 return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; 56370 function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } 56371 function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } 56372 function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } 56373 function fulfill(value) { resume("next", value); } 56374 function reject(value) { resume("throw", value); } 56375 function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } 56376 } 56377 56378 function __asyncDelegator(o) { 56379 var i, p; 56380 return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; 56381 function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } 56382 } 56383 56384 function __asyncValues(o) { 56385 if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); 56386 var m = o[Symbol.asyncIterator], i; 56387 return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); 56388 function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } 56389 function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } 56390 } 56391 56392 function __makeTemplateObject(cooked, raw) { 56393 if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } 56394 return cooked; 56395 }; 56396 56397 var __setModuleDefault = Object.create ? (function(o, v) { 56398 Object.defineProperty(o, "default", { enumerable: true, value: v }); 56399 }) : function(o, v) { 56400 o["default"] = v; 56401 }; 56402 56403 function __importStar(mod) { 56404 if (mod && mod.__esModule) return mod; 56405 var result = {}; 56406 if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 56407 __setModuleDefault(result, mod); 56408 return result; 56409 } 56410 56411 function __importDefault(mod) { 56412 return (mod && mod.__esModule) ? mod : { default: mod }; 56413 } 56414 56415 function __classPrivateFieldGet(receiver, privateMap) { 56416 if (!privateMap.has(receiver)) { 56417 throw new TypeError("attempted to get private field on non-instance"); 56418 } 56419 return privateMap.get(receiver); 56420 } 56421 56422 function __classPrivateFieldSet(receiver, privateMap, value) { 56423 if (!privateMap.has(receiver)) { 56424 throw new TypeError("attempted to set private field on non-instance"); 56425 } 56426 privateMap.set(receiver, value); 56427 return value; 56428 } 56429 56430 // EXTERNAL MODULE: ./node_modules/normalize-wheel/index.js 56431 var normalize_wheel = __webpack_require__(7520); 56432 var normalize_wheel_default = /*#__PURE__*/__webpack_require__.n(normalize_wheel); 56433 ;// CONCATENATED MODULE: ./node_modules/react-easy-crop/index.module.js 56434 56435 56436 56437 56438 /** 56439 * Compute the dimension of the crop area based on media size, 56440 * aspect ratio and optionally rotation 56441 */ 56442 function getCropSize(mediaWidth, mediaHeight, containerWidth, containerHeight, aspect, rotation) { 56443 if (rotation === void 0) { 56444 rotation = 0; 56445 } 56446 var _a = rotateSize(mediaWidth, mediaHeight, rotation), 56447 width = _a.width, 56448 height = _a.height; 56449 var fittingWidth = Math.min(width, containerWidth); 56450 var fittingHeight = Math.min(height, containerHeight); 56451 if (fittingWidth > fittingHeight * aspect) { 56452 return { 56453 width: fittingHeight * aspect, 56454 height: fittingHeight 56455 }; 56456 } 56457 return { 56458 width: fittingWidth, 56459 height: fittingWidth / aspect 56460 }; 56461 } 56462 /** 56463 * Compute media zoom. 56464 * We fit the media into the container with "max-width: 100%; max-height: 100%;" 56465 */ 56466 function getMediaZoom(mediaSize) { 56467 // Take the axis with more pixels to improve accuracy 56468 return mediaSize.width > mediaSize.height ? mediaSize.width / mediaSize.naturalWidth : mediaSize.height / mediaSize.naturalHeight; 56469 } 56470 /** 56471 * Ensure a new media position stays in the crop area. 56472 */ 56473 function restrictPosition(position, mediaSize, cropSize, zoom, rotation) { 56474 if (rotation === void 0) { 56475 rotation = 0; 56476 } 56477 var _a = rotateSize(mediaSize.width, mediaSize.height, rotation), 56478 width = _a.width, 56479 height = _a.height; 56480 return { 56481 x: restrictPositionCoord(position.x, width, cropSize.width, zoom), 56482 y: restrictPositionCoord(position.y, height, cropSize.height, zoom) 56483 }; 56484 } 56485 function restrictPositionCoord(position, mediaSize, cropSize, zoom) { 56486 var maxPosition = mediaSize * zoom / 2 - cropSize / 2; 56487 return clamp(position, -maxPosition, maxPosition); 56488 } 56489 function getDistanceBetweenPoints(pointA, pointB) { 56490 return Math.sqrt(Math.pow(pointA.y - pointB.y, 2) + Math.pow(pointA.x - pointB.x, 2)); 56491 } 56492 function getRotationBetweenPoints(pointA, pointB) { 56493 return Math.atan2(pointB.y - pointA.y, pointB.x - pointA.x) * 180 / Math.PI; 56494 } 56495 /** 56496 * Compute the output cropped area of the media in percentages and pixels. 56497 * x/y are the top-left coordinates on the src media 56498 */ 56499 function computeCroppedArea(crop, mediaSize, cropSize, aspect, zoom, rotation, restrictPosition) { 56500 if (rotation === void 0) { 56501 rotation = 0; 56502 } 56503 if (restrictPosition === void 0) { 56504 restrictPosition = true; 56505 } 56506 // if the media is rotated by the user, we cannot limit the position anymore 56507 // as it might need to be negative. 56508 var limitAreaFn = restrictPosition ? limitArea : noOp; 56509 var mediaBBoxSize = rotateSize(mediaSize.width, mediaSize.height, rotation); 56510 var mediaNaturalBBoxSize = rotateSize(mediaSize.naturalWidth, mediaSize.naturalHeight, rotation); 56511 // calculate the crop area in percentages 56512 // in the rotated space 56513 var croppedAreaPercentages = { 56514 x: limitAreaFn(100, ((mediaBBoxSize.width - cropSize.width / zoom) / 2 - crop.x / zoom) / mediaBBoxSize.width * 100), 56515 y: limitAreaFn(100, ((mediaBBoxSize.height - cropSize.height / zoom) / 2 - crop.y / zoom) / mediaBBoxSize.height * 100), 56516 width: limitAreaFn(100, cropSize.width / mediaBBoxSize.width * 100 / zoom), 56517 height: limitAreaFn(100, cropSize.height / mediaBBoxSize.height * 100 / zoom) 56518 }; 56519 // we compute the pixels size naively 56520 var widthInPixels = Math.round(limitAreaFn(mediaNaturalBBoxSize.width, croppedAreaPercentages.width * mediaNaturalBBoxSize.width / 100)); 56521 var heightInPixels = Math.round(limitAreaFn(mediaNaturalBBoxSize.height, croppedAreaPercentages.height * mediaNaturalBBoxSize.height / 100)); 56522 var isImgWiderThanHigh = mediaNaturalBBoxSize.width >= mediaNaturalBBoxSize.height * aspect; 56523 // then we ensure the width and height exactly match the aspect (to avoid rounding approximations) 56524 // if the media is wider than high, when zoom is 0, the crop height will be equals to image height 56525 // thus we want to compute the width from the height and aspect for accuracy. 56526 // Otherwise, we compute the height from width and aspect. 56527 var sizePixels = isImgWiderThanHigh ? { 56528 width: Math.round(heightInPixels * aspect), 56529 height: heightInPixels 56530 } : { 56531 width: widthInPixels, 56532 height: Math.round(widthInPixels / aspect) 56533 }; 56534 var croppedAreaPixels = __assign(__assign({}, sizePixels), { 56535 x: Math.round(limitAreaFn(mediaNaturalBBoxSize.width - sizePixels.width, croppedAreaPercentages.x * mediaNaturalBBoxSize.width / 100)), 56536 y: Math.round(limitAreaFn(mediaNaturalBBoxSize.height - sizePixels.height, croppedAreaPercentages.y * mediaNaturalBBoxSize.height / 100)) 56537 }); 56538 return { 56539 croppedAreaPercentages: croppedAreaPercentages, 56540 croppedAreaPixels: croppedAreaPixels 56541 }; 56542 } 56543 /** 56544 * Ensure the returned value is between 0 and max 56545 */ 56546 function limitArea(max, value) { 56547 return Math.min(max, Math.max(0, value)); 56548 } 56549 function noOp(_max, value) { 56550 return value; 56551 } 56552 /** 56553 * Compute crop and zoom from the croppedAreaPercentages. 56554 */ 56555 function getInitialCropFromCroppedAreaPercentages(croppedAreaPercentages, mediaSize, rotation, cropSize, minZoom, maxZoom) { 56556 var mediaBBoxSize = rotateSize(mediaSize.width, mediaSize.height, rotation); 56557 // This is the inverse process of computeCroppedArea 56558 var zoom = clamp(cropSize.width / mediaBBoxSize.width * (100 / croppedAreaPercentages.width), minZoom, maxZoom); 56559 var crop = { 56560 x: zoom * mediaBBoxSize.width / 2 - cropSize.width / 2 - mediaBBoxSize.width * zoom * (croppedAreaPercentages.x / 100), 56561 y: zoom * mediaBBoxSize.height / 2 - cropSize.height / 2 - mediaBBoxSize.height * zoom * (croppedAreaPercentages.y / 100) 56562 }; 56563 return { 56564 crop: crop, 56565 zoom: zoom 56566 }; 56567 } 56568 /** 56569 * Compute zoom from the croppedAreaPixels 56570 */ 56571 function getZoomFromCroppedAreaPixels(croppedAreaPixels, mediaSize, cropSize) { 56572 var mediaZoom = getMediaZoom(mediaSize); 56573 return cropSize.height > cropSize.width ? cropSize.height / (croppedAreaPixels.height * mediaZoom) : cropSize.width / (croppedAreaPixels.width * mediaZoom); 56574 } 56575 /** 56576 * Compute crop and zoom from the croppedAreaPixels 56577 */ 56578 function getInitialCropFromCroppedAreaPixels(croppedAreaPixels, mediaSize, rotation, cropSize, minZoom, maxZoom) { 56579 if (rotation === void 0) { 56580 rotation = 0; 56581 } 56582 var mediaNaturalBBoxSize = rotateSize(mediaSize.naturalWidth, mediaSize.naturalHeight, rotation); 56583 var zoom = clamp(getZoomFromCroppedAreaPixels(croppedAreaPixels, mediaSize, cropSize), minZoom, maxZoom); 56584 var cropZoom = cropSize.height > cropSize.width ? cropSize.height / croppedAreaPixels.height : cropSize.width / croppedAreaPixels.width; 56585 var crop = { 56586 x: ((mediaNaturalBBoxSize.width - croppedAreaPixels.width) / 2 - croppedAreaPixels.x) * cropZoom, 56587 y: ((mediaNaturalBBoxSize.height - croppedAreaPixels.height) / 2 - croppedAreaPixels.y) * cropZoom 56588 }; 56589 return { 56590 crop: crop, 56591 zoom: zoom 56592 }; 56593 } 56594 /** 56595 * Return the point that is the center of point a and b 56596 */ 56597 function getCenter(a, b) { 56598 return { 56599 x: (b.x + a.x) / 2, 56600 y: (b.y + a.y) / 2 56601 }; 56602 } 56603 function getRadianAngle(degreeValue) { 56604 return degreeValue * Math.PI / 180; 56605 } 56606 /** 56607 * Returns the new bounding area of a rotated rectangle. 56608 */ 56609 function rotateSize(width, height, rotation) { 56610 var rotRad = getRadianAngle(rotation); 56611 return { 56612 width: Math.abs(Math.cos(rotRad) * width) + Math.abs(Math.sin(rotRad) * height), 56613 height: Math.abs(Math.sin(rotRad) * width) + Math.abs(Math.cos(rotRad) * height) 56614 }; 56615 } 56616 /** 56617 * Clamp value between min and max 56618 */ 56619 function clamp(value, min, max) { 56620 return Math.min(Math.max(value, min), max); 56621 } 56622 /** 56623 * Combine multiple class names into a single string. 56624 */ 56625 function classNames() { 56626 var args = []; 56627 for (var _i = 0; _i < arguments.length; _i++) { 56628 args[_i] = arguments[_i]; 56629 } 56630 return args.filter(function (value) { 56631 if (typeof value === 'string' && value.length > 0) { 56632 return true; 56633 } 56634 return false; 56635 }).join(' ').trim(); 56636 } 56637 56638 var css_248z = ".reactEasyCrop_Container {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n overflow: hidden;\n user-select: none;\n touch-action: none;\n cursor: move;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n.reactEasyCrop_Image,\n.reactEasyCrop_Video {\n will-change: transform; /* this improves performances and prevent painting issues on iOS Chrome */\n}\n\n.reactEasyCrop_Contain {\n max-width: 100%;\n max-height: 100%;\n margin: auto;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n right: 0;\n}\n.reactEasyCrop_Cover_Horizontal {\n width: 100%;\n height: auto;\n}\n.reactEasyCrop_Cover_Vertical {\n width: auto;\n height: 100%;\n}\n\n.reactEasyCrop_CropArea {\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n border: 1px solid rgba(255, 255, 255, 0.5);\n box-sizing: border-box;\n box-shadow: 0 0 0 9999em;\n color: rgba(0, 0, 0, 0.5);\n overflow: hidden;\n}\n\n.reactEasyCrop_CropAreaRound {\n border-radius: 50%;\n}\n\n.reactEasyCrop_CropAreaGrid::before {\n content: ' ';\n box-sizing: border-box;\n position: absolute;\n border: 1px solid rgba(255, 255, 255, 0.5);\n top: 0;\n bottom: 0;\n left: 33.33%;\n right: 33.33%;\n border-top: 0;\n border-bottom: 0;\n}\n\n.reactEasyCrop_CropAreaGrid::after {\n content: ' ';\n box-sizing: border-box;\n position: absolute;\n border: 1px solid rgba(255, 255, 255, 0.5);\n top: 33.33%;\n bottom: 33.33%;\n left: 0;\n right: 0;\n border-left: 0;\n border-right: 0;\n}\n"; 56639 56640 var MIN_ZOOM = 1; 56641 var MAX_ZOOM = 3; 56642 var Cropper = /** @class */function (_super) { 56643 __extends(Cropper, _super); 56644 function Cropper() { 56645 var _this = _super !== null && _super.apply(this, arguments) || this; 56646 _this.imageRef = external_React_default().createRef(); 56647 _this.videoRef = external_React_default().createRef(); 56648 _this.containerRef = null; 56649 _this.styleRef = null; 56650 _this.containerRect = null; 56651 _this.mediaSize = { 56652 width: 0, 56653 height: 0, 56654 naturalWidth: 0, 56655 naturalHeight: 0 56656 }; 56657 _this.dragStartPosition = { 56658 x: 0, 56659 y: 0 56660 }; 56661 _this.dragStartCrop = { 56662 x: 0, 56663 y: 0 56664 }; 56665 _this.gestureZoomStart = 0; 56666 _this.gestureRotationStart = 0; 56667 _this.isTouching = false; 56668 _this.lastPinchDistance = 0; 56669 _this.lastPinchRotation = 0; 56670 _this.rafDragTimeout = null; 56671 _this.rafPinchTimeout = null; 56672 _this.wheelTimer = null; 56673 _this.currentDoc = typeof document !== 'undefined' ? document : null; 56674 _this.currentWindow = typeof window !== 'undefined' ? window : null; 56675 _this.resizeObserver = null; 56676 _this.state = { 56677 cropSize: null, 56678 hasWheelJustStarted: false 56679 }; 56680 _this.initResizeObserver = function () { 56681 if (typeof window.ResizeObserver === 'undefined' || !_this.containerRef) { 56682 return; 56683 } 56684 var isFirstResize = true; 56685 _this.resizeObserver = new window.ResizeObserver(function (entries) { 56686 if (isFirstResize) { 56687 isFirstResize = false; // observe() is called on mount, we don't want to trigger a recompute on mount 56688 return; 56689 } 56690 _this.computeSizes(); 56691 }); 56692 _this.resizeObserver.observe(_this.containerRef); 56693 }; 56694 // this is to prevent Safari on iOS >= 10 to zoom the page 56695 _this.preventZoomSafari = function (e) { 56696 return e.preventDefault(); 56697 }; 56698 _this.cleanEvents = function () { 56699 if (!_this.currentDoc) return; 56700 _this.currentDoc.removeEventListener('mousemove', _this.onMouseMove); 56701 _this.currentDoc.removeEventListener('mouseup', _this.onDragStopped); 56702 _this.currentDoc.removeEventListener('touchmove', _this.onTouchMove); 56703 _this.currentDoc.removeEventListener('touchend', _this.onDragStopped); 56704 _this.currentDoc.removeEventListener('gesturemove', _this.onGestureMove); 56705 _this.currentDoc.removeEventListener('gestureend', _this.onGestureEnd); 56706 }; 56707 _this.clearScrollEvent = function () { 56708 if (_this.containerRef) _this.containerRef.removeEventListener('wheel', _this.onWheel); 56709 if (_this.wheelTimer) { 56710 clearTimeout(_this.wheelTimer); 56711 } 56712 }; 56713 _this.onMediaLoad = function () { 56714 var cropSize = _this.computeSizes(); 56715 if (cropSize) { 56716 _this.emitCropData(); 56717 _this.setInitialCrop(cropSize); 56718 } 56719 if (_this.props.onMediaLoaded) { 56720 _this.props.onMediaLoaded(_this.mediaSize); 56721 } 56722 }; 56723 _this.setInitialCrop = function (cropSize) { 56724 if (_this.props.initialCroppedAreaPercentages) { 56725 var _a = getInitialCropFromCroppedAreaPercentages(_this.props.initialCroppedAreaPercentages, _this.mediaSize, _this.props.rotation, cropSize, _this.props.minZoom, _this.props.maxZoom), 56726 crop = _a.crop, 56727 zoom = _a.zoom; 56728 _this.props.onCropChange(crop); 56729 _this.props.onZoomChange && _this.props.onZoomChange(zoom); 56730 } else if (_this.props.initialCroppedAreaPixels) { 56731 var _b = getInitialCropFromCroppedAreaPixels(_this.props.initialCroppedAreaPixels, _this.mediaSize, _this.props.rotation, cropSize, _this.props.minZoom, _this.props.maxZoom), 56732 crop = _b.crop, 56733 zoom = _b.zoom; 56734 _this.props.onCropChange(crop); 56735 _this.props.onZoomChange && _this.props.onZoomChange(zoom); 56736 } 56737 }; 56738 _this.computeSizes = function () { 56739 var _a, _b, _c, _d, _e, _f; 56740 var mediaRef = _this.imageRef.current || _this.videoRef.current; 56741 if (mediaRef && _this.containerRef) { 56742 _this.containerRect = _this.containerRef.getBoundingClientRect(); 56743 var containerAspect = _this.containerRect.width / _this.containerRect.height; 56744 var naturalWidth = ((_a = _this.imageRef.current) === null || _a === void 0 ? void 0 : _a.naturalWidth) || ((_b = _this.videoRef.current) === null || _b === void 0 ? void 0 : _b.videoWidth) || 0; 56745 var naturalHeight = ((_c = _this.imageRef.current) === null || _c === void 0 ? void 0 : _c.naturalHeight) || ((_d = _this.videoRef.current) === null || _d === void 0 ? void 0 : _d.videoHeight) || 0; 56746 var isMediaScaledDown = mediaRef.offsetWidth < naturalWidth || mediaRef.offsetHeight < naturalHeight; 56747 var mediaAspect = naturalWidth / naturalHeight; 56748 // We do not rely on the offsetWidth/offsetHeight if the media is scaled down 56749 // as the values they report are rounded. That will result in precision losses 56750 // when calculating zoom. We use the fact that the media is positionned relative 56751 // to the container. That allows us to use the container's dimensions 56752 // and natural aspect ratio of the media to calculate accurate media size. 56753 // However, for this to work, the container should not be rotated 56754 var renderedMediaSize = void 0; 56755 if (isMediaScaledDown) { 56756 switch (_this.props.objectFit) { 56757 default: 56758 case 'contain': 56759 renderedMediaSize = containerAspect > mediaAspect ? { 56760 width: _this.containerRect.height * mediaAspect, 56761 height: _this.containerRect.height 56762 } : { 56763 width: _this.containerRect.width, 56764 height: _this.containerRect.width / mediaAspect 56765 }; 56766 break; 56767 case 'horizontal-cover': 56768 renderedMediaSize = { 56769 width: _this.containerRect.width, 56770 height: _this.containerRect.width / mediaAspect 56771 }; 56772 break; 56773 case 'vertical-cover': 56774 renderedMediaSize = { 56775 width: _this.containerRect.height * mediaAspect, 56776 height: _this.containerRect.height 56777 }; 56778 break; 56779 case 'auto-cover': 56780 renderedMediaSize = naturalWidth > naturalHeight ? { 56781 width: _this.containerRect.width, 56782 height: _this.containerRect.width / mediaAspect 56783 } : { 56784 width: _this.containerRect.height * mediaAspect, 56785 height: _this.containerRect.height 56786 }; 56787 break; 56788 } 56789 } else { 56790 renderedMediaSize = { 56791 width: mediaRef.offsetWidth, 56792 height: mediaRef.offsetHeight 56793 }; 56794 } 56795 _this.mediaSize = __assign(__assign({}, renderedMediaSize), { 56796 naturalWidth: naturalWidth, 56797 naturalHeight: naturalHeight 56798 }); 56799 // set media size in the parent 56800 if (_this.props.setMediaSize) { 56801 _this.props.setMediaSize(_this.mediaSize); 56802 } 56803 var cropSize = _this.props.cropSize ? _this.props.cropSize : getCropSize(_this.mediaSize.width, _this.mediaSize.height, _this.containerRect.width, _this.containerRect.height, _this.props.aspect, _this.props.rotation); 56804 if (((_e = _this.state.cropSize) === null || _e === void 0 ? void 0 : _e.height) !== cropSize.height || ((_f = _this.state.cropSize) === null || _f === void 0 ? void 0 : _f.width) !== cropSize.width) { 56805 _this.props.onCropSizeChange && _this.props.onCropSizeChange(cropSize); 56806 } 56807 _this.setState({ 56808 cropSize: cropSize 56809 }, _this.recomputeCropPosition); 56810 // pass crop size to parent 56811 if (_this.props.setCropSize) { 56812 _this.props.setCropSize(cropSize); 56813 } 56814 return cropSize; 56815 } 56816 }; 56817 _this.onMouseDown = function (e) { 56818 if (!_this.currentDoc) return; 56819 e.preventDefault(); 56820 _this.currentDoc.addEventListener('mousemove', _this.onMouseMove); 56821 _this.currentDoc.addEventListener('mouseup', _this.onDragStopped); 56822 _this.onDragStart(Cropper.getMousePoint(e)); 56823 }; 56824 _this.onMouseMove = function (e) { 56825 return _this.onDrag(Cropper.getMousePoint(e)); 56826 }; 56827 _this.onTouchStart = function (e) { 56828 if (!_this.currentDoc) return; 56829 _this.isTouching = true; 56830 if (_this.props.onTouchRequest && !_this.props.onTouchRequest(e)) { 56831 return; 56832 } 56833 _this.currentDoc.addEventListener('touchmove', _this.onTouchMove, { 56834 passive: false 56835 }); // iOS 11 now defaults to passive: true 56836 _this.currentDoc.addEventListener('touchend', _this.onDragStopped); 56837 if (e.touches.length === 2) { 56838 _this.onPinchStart(e); 56839 } else if (e.touches.length === 1) { 56840 _this.onDragStart(Cropper.getTouchPoint(e.touches[0])); 56841 } 56842 }; 56843 _this.onTouchMove = function (e) { 56844 // Prevent whole page from scrolling on iOS. 56845 e.preventDefault(); 56846 if (e.touches.length === 2) { 56847 _this.onPinchMove(e); 56848 } else if (e.touches.length === 1) { 56849 _this.onDrag(Cropper.getTouchPoint(e.touches[0])); 56850 } 56851 }; 56852 _this.onGestureStart = function (e) { 56853 if (!_this.currentDoc) return; 56854 e.preventDefault(); 56855 _this.currentDoc.addEventListener('gesturechange', _this.onGestureMove); 56856 _this.currentDoc.addEventListener('gestureend', _this.onGestureEnd); 56857 _this.gestureZoomStart = _this.props.zoom; 56858 _this.gestureRotationStart = _this.props.rotation; 56859 }; 56860 _this.onGestureMove = function (e) { 56861 e.preventDefault(); 56862 if (_this.isTouching) { 56863 // this is to avoid conflict between gesture and touch events 56864 return; 56865 } 56866 var point = Cropper.getMousePoint(e); 56867 var newZoom = _this.gestureZoomStart - 1 + e.scale; 56868 _this.setNewZoom(newZoom, point, { 56869 shouldUpdatePosition: true 56870 }); 56871 if (_this.props.onRotationChange) { 56872 var newRotation = _this.gestureRotationStart + e.rotation; 56873 _this.props.onRotationChange(newRotation); 56874 } 56875 }; 56876 _this.onGestureEnd = function (e) { 56877 _this.cleanEvents(); 56878 }; 56879 _this.onDragStart = function (_a) { 56880 var _b, _c; 56881 var x = _a.x, 56882 y = _a.y; 56883 _this.dragStartPosition = { 56884 x: x, 56885 y: y 56886 }; 56887 _this.dragStartCrop = __assign({}, _this.props.crop); 56888 (_c = (_b = _this.props).onInteractionStart) === null || _c === void 0 ? void 0 : _c.call(_b); 56889 }; 56890 _this.onDrag = function (_a) { 56891 var x = _a.x, 56892 y = _a.y; 56893 if (!_this.currentWindow) return; 56894 if (_this.rafDragTimeout) _this.currentWindow.cancelAnimationFrame(_this.rafDragTimeout); 56895 _this.rafDragTimeout = _this.currentWindow.requestAnimationFrame(function () { 56896 if (!_this.state.cropSize) return; 56897 if (x === undefined || y === undefined) return; 56898 var offsetX = x - _this.dragStartPosition.x; 56899 var offsetY = y - _this.dragStartPosition.y; 56900 var requestedPosition = { 56901 x: _this.dragStartCrop.x + offsetX, 56902 y: _this.dragStartCrop.y + offsetY 56903 }; 56904 var newPosition = _this.props.restrictPosition ? restrictPosition(requestedPosition, _this.mediaSize, _this.state.cropSize, _this.props.zoom, _this.props.rotation) : requestedPosition; 56905 _this.props.onCropChange(newPosition); 56906 }); 56907 }; 56908 _this.onDragStopped = function () { 56909 var _a, _b; 56910 _this.isTouching = false; 56911 _this.cleanEvents(); 56912 _this.emitCropData(); 56913 (_b = (_a = _this.props).onInteractionEnd) === null || _b === void 0 ? void 0 : _b.call(_a); 56914 }; 56915 _this.onWheel = function (e) { 56916 if (!_this.currentWindow) return; 56917 if (_this.props.onWheelRequest && !_this.props.onWheelRequest(e)) { 56918 return; 56919 } 56920 e.preventDefault(); 56921 var point = Cropper.getMousePoint(e); 56922 var pixelY = normalize_wheel_default()(e).pixelY; 56923 var newZoom = _this.props.zoom - pixelY * _this.props.zoomSpeed / 200; 56924 _this.setNewZoom(newZoom, point, { 56925 shouldUpdatePosition: true 56926 }); 56927 if (!_this.state.hasWheelJustStarted) { 56928 _this.setState({ 56929 hasWheelJustStarted: true 56930 }, function () { 56931 var _a, _b; 56932 return (_b = (_a = _this.props).onInteractionStart) === null || _b === void 0 ? void 0 : _b.call(_a); 56933 }); 56934 } 56935 if (_this.wheelTimer) { 56936 clearTimeout(_this.wheelTimer); 56937 } 56938 _this.wheelTimer = _this.currentWindow.setTimeout(function () { 56939 return _this.setState({ 56940 hasWheelJustStarted: false 56941 }, function () { 56942 var _a, _b; 56943 return (_b = (_a = _this.props).onInteractionEnd) === null || _b === void 0 ? void 0 : _b.call(_a); 56944 }); 56945 }, 250); 56946 }; 56947 _this.getPointOnContainer = function (_a) { 56948 var x = _a.x, 56949 y = _a.y; 56950 if (!_this.containerRect) { 56951 throw new Error('The Cropper is not mounted'); 56952 } 56953 return { 56954 x: _this.containerRect.width / 2 - (x - _this.containerRect.left), 56955 y: _this.containerRect.height / 2 - (y - _this.containerRect.top) 56956 }; 56957 }; 56958 _this.getPointOnMedia = function (_a) { 56959 var x = _a.x, 56960 y = _a.y; 56961 var _b = _this.props, 56962 crop = _b.crop, 56963 zoom = _b.zoom; 56964 return { 56965 x: (x + crop.x) / zoom, 56966 y: (y + crop.y) / zoom 56967 }; 56968 }; 56969 _this.setNewZoom = function (zoom, point, _a) { 56970 var _b = _a === void 0 ? {} : _a, 56971 _c = _b.shouldUpdatePosition, 56972 shouldUpdatePosition = _c === void 0 ? true : _c; 56973 if (!_this.state.cropSize || !_this.props.onZoomChange) return; 56974 var newZoom = clamp(zoom, _this.props.minZoom, _this.props.maxZoom); 56975 if (shouldUpdatePosition) { 56976 var zoomPoint = _this.getPointOnContainer(point); 56977 var zoomTarget = _this.getPointOnMedia(zoomPoint); 56978 var requestedPosition = { 56979 x: zoomTarget.x * newZoom - zoomPoint.x, 56980 y: zoomTarget.y * newZoom - zoomPoint.y 56981 }; 56982 var newPosition = _this.props.restrictPosition ? restrictPosition(requestedPosition, _this.mediaSize, _this.state.cropSize, newZoom, _this.props.rotation) : requestedPosition; 56983 _this.props.onCropChange(newPosition); 56984 } 56985 _this.props.onZoomChange(newZoom); 56986 }; 56987 _this.getCropData = function () { 56988 if (!_this.state.cropSize) { 56989 return null; 56990 } 56991 // this is to ensure the crop is correctly restricted after a zoom back (https://github.com/ValentinH/react-easy-crop/issues/6) 56992 var restrictedPosition = _this.props.restrictPosition ? restrictPosition(_this.props.crop, _this.mediaSize, _this.state.cropSize, _this.props.zoom, _this.props.rotation) : _this.props.crop; 56993 return computeCroppedArea(restrictedPosition, _this.mediaSize, _this.state.cropSize, _this.getAspect(), _this.props.zoom, _this.props.rotation, _this.props.restrictPosition); 56994 }; 56995 _this.emitCropData = function () { 56996 var cropData = _this.getCropData(); 56997 if (!cropData) return; 56998 var croppedAreaPercentages = cropData.croppedAreaPercentages, 56999 croppedAreaPixels = cropData.croppedAreaPixels; 57000 if (_this.props.onCropComplete) { 57001 _this.props.onCropComplete(croppedAreaPercentages, croppedAreaPixels); 57002 } 57003 if (_this.props.onCropAreaChange) { 57004 _this.props.onCropAreaChange(croppedAreaPercentages, croppedAreaPixels); 57005 } 57006 }; 57007 _this.emitCropAreaChange = function () { 57008 var cropData = _this.getCropData(); 57009 if (!cropData) return; 57010 var croppedAreaPercentages = cropData.croppedAreaPercentages, 57011 croppedAreaPixels = cropData.croppedAreaPixels; 57012 if (_this.props.onCropAreaChange) { 57013 _this.props.onCropAreaChange(croppedAreaPercentages, croppedAreaPixels); 57014 } 57015 }; 57016 _this.recomputeCropPosition = function () { 57017 if (!_this.state.cropSize) return; 57018 var newPosition = _this.props.restrictPosition ? restrictPosition(_this.props.crop, _this.mediaSize, _this.state.cropSize, _this.props.zoom, _this.props.rotation) : _this.props.crop; 57019 _this.props.onCropChange(newPosition); 57020 _this.emitCropData(); 57021 }; 57022 return _this; 57023 } 57024 Cropper.prototype.componentDidMount = function () { 57025 if (!this.currentDoc || !this.currentWindow) return; 57026 if (this.containerRef) { 57027 if (this.containerRef.ownerDocument) { 57028 this.currentDoc = this.containerRef.ownerDocument; 57029 } 57030 if (this.currentDoc.defaultView) { 57031 this.currentWindow = this.currentDoc.defaultView; 57032 } 57033 this.initResizeObserver(); 57034 // only add window resize listener if ResizeObserver is not supported. Otherwise, it would be redundant 57035 if (typeof window.ResizeObserver === 'undefined') { 57036 this.currentWindow.addEventListener('resize', this.computeSizes); 57037 } 57038 this.props.zoomWithScroll && this.containerRef.addEventListener('wheel', this.onWheel, { 57039 passive: false 57040 }); 57041 this.containerRef.addEventListener('gesturestart', this.onGestureStart); 57042 } 57043 if (!this.props.disableAutomaticStylesInjection) { 57044 this.styleRef = this.currentDoc.createElement('style'); 57045 this.styleRef.setAttribute('type', 'text/css'); 57046 if (this.props.nonce) { 57047 this.styleRef.setAttribute('nonce', this.props.nonce); 57048 } 57049 this.styleRef.innerHTML = css_248z; 57050 this.currentDoc.head.appendChild(this.styleRef); 57051 } 57052 // when rendered via SSR, the image can already be loaded and its onLoad callback will never be called 57053 if (this.imageRef.current && this.imageRef.current.complete) { 57054 this.onMediaLoad(); 57055 } 57056 // set image and video refs in the parent if the callbacks exist 57057 if (this.props.setImageRef) { 57058 this.props.setImageRef(this.imageRef); 57059 } 57060 if (this.props.setVideoRef) { 57061 this.props.setVideoRef(this.videoRef); 57062 } 57063 }; 57064 Cropper.prototype.componentWillUnmount = function () { 57065 var _a, _b; 57066 if (!this.currentDoc || !this.currentWindow) return; 57067 if (typeof window.ResizeObserver === 'undefined') { 57068 this.currentWindow.removeEventListener('resize', this.computeSizes); 57069 } 57070 (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect(); 57071 if (this.containerRef) { 57072 this.containerRef.removeEventListener('gesturestart', this.preventZoomSafari); 57073 } 57074 if (this.styleRef) { 57075 (_b = this.styleRef.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(this.styleRef); 57076 } 57077 this.cleanEvents(); 57078 this.props.zoomWithScroll && this.clearScrollEvent(); 57079 }; 57080 Cropper.prototype.componentDidUpdate = function (prevProps) { 57081 var _a, _b, _c, _d, _e, _f, _g, _h, _j; 57082 if (prevProps.rotation !== this.props.rotation) { 57083 this.computeSizes(); 57084 this.recomputeCropPosition(); 57085 } else if (prevProps.aspect !== this.props.aspect) { 57086 this.computeSizes(); 57087 } else if (prevProps.zoom !== this.props.zoom) { 57088 this.recomputeCropPosition(); 57089 } else if (((_a = prevProps.cropSize) === null || _a === void 0 ? void 0 : _a.height) !== ((_b = this.props.cropSize) === null || _b === void 0 ? void 0 : _b.height) || ((_c = prevProps.cropSize) === null || _c === void 0 ? void 0 : _c.width) !== ((_d = this.props.cropSize) === null || _d === void 0 ? void 0 : _d.width)) { 57090 this.computeSizes(); 57091 } else if (((_e = prevProps.crop) === null || _e === void 0 ? void 0 : _e.x) !== ((_f = this.props.crop) === null || _f === void 0 ? void 0 : _f.x) || ((_g = prevProps.crop) === null || _g === void 0 ? void 0 : _g.y) !== ((_h = this.props.crop) === null || _h === void 0 ? void 0 : _h.y)) { 57092 this.emitCropAreaChange(); 57093 } 57094 if (prevProps.zoomWithScroll !== this.props.zoomWithScroll && this.containerRef) { 57095 this.props.zoomWithScroll ? this.containerRef.addEventListener('wheel', this.onWheel, { 57096 passive: false 57097 }) : this.clearScrollEvent(); 57098 } 57099 if (prevProps.video !== this.props.video) { 57100 (_j = this.videoRef.current) === null || _j === void 0 ? void 0 : _j.load(); 57101 } 57102 }; 57103 Cropper.prototype.getAspect = function () { 57104 var _a = this.props, 57105 cropSize = _a.cropSize, 57106 aspect = _a.aspect; 57107 if (cropSize) { 57108 return cropSize.width / cropSize.height; 57109 } 57110 return aspect; 57111 }; 57112 Cropper.prototype.onPinchStart = function (e) { 57113 var pointA = Cropper.getTouchPoint(e.touches[0]); 57114 var pointB = Cropper.getTouchPoint(e.touches[1]); 57115 this.lastPinchDistance = getDistanceBetweenPoints(pointA, pointB); 57116 this.lastPinchRotation = getRotationBetweenPoints(pointA, pointB); 57117 this.onDragStart(getCenter(pointA, pointB)); 57118 }; 57119 Cropper.prototype.onPinchMove = function (e) { 57120 var _this = this; 57121 if (!this.currentDoc || !this.currentWindow) return; 57122 var pointA = Cropper.getTouchPoint(e.touches[0]); 57123 var pointB = Cropper.getTouchPoint(e.touches[1]); 57124 var center = getCenter(pointA, pointB); 57125 this.onDrag(center); 57126 if (this.rafPinchTimeout) this.currentWindow.cancelAnimationFrame(this.rafPinchTimeout); 57127 this.rafPinchTimeout = this.currentWindow.requestAnimationFrame(function () { 57128 var distance = getDistanceBetweenPoints(pointA, pointB); 57129 var newZoom = _this.props.zoom * (distance / _this.lastPinchDistance); 57130 _this.setNewZoom(newZoom, center, { 57131 shouldUpdatePosition: false 57132 }); 57133 _this.lastPinchDistance = distance; 57134 var rotation = getRotationBetweenPoints(pointA, pointB); 57135 var newRotation = _this.props.rotation + (rotation - _this.lastPinchRotation); 57136 _this.props.onRotationChange && _this.props.onRotationChange(newRotation); 57137 _this.lastPinchRotation = rotation; 57138 }); 57139 }; 57140 Cropper.prototype.render = function () { 57141 var _this = this; 57142 var _a = this.props, 57143 image = _a.image, 57144 video = _a.video, 57145 mediaProps = _a.mediaProps, 57146 transform = _a.transform, 57147 _b = _a.crop, 57148 x = _b.x, 57149 y = _b.y, 57150 rotation = _a.rotation, 57151 zoom = _a.zoom, 57152 cropShape = _a.cropShape, 57153 showGrid = _a.showGrid, 57154 _c = _a.style, 57155 containerStyle = _c.containerStyle, 57156 cropAreaStyle = _c.cropAreaStyle, 57157 mediaStyle = _c.mediaStyle, 57158 _d = _a.classes, 57159 containerClassName = _d.containerClassName, 57160 cropAreaClassName = _d.cropAreaClassName, 57161 mediaClassName = _d.mediaClassName, 57162 objectFit = _a.objectFit; 57163 return external_React_default().createElement("div", { 57164 onMouseDown: this.onMouseDown, 57165 onTouchStart: this.onTouchStart, 57166 ref: function ref(el) { 57167 return _this.containerRef = el; 57168 }, 57169 "data-testid": "container", 57170 style: containerStyle, 57171 className: classNames('reactEasyCrop_Container', containerClassName) 57172 }, image ? external_React_default().createElement("img", __assign({ 57173 alt: "", 57174 className: classNames('reactEasyCrop_Image', objectFit === 'contain' && 'reactEasyCrop_Contain', objectFit === 'horizontal-cover' && 'reactEasyCrop_Cover_Horizontal', objectFit === 'vertical-cover' && 'reactEasyCrop_Cover_Vertical', objectFit === 'auto-cover' && (this.mediaSize.naturalWidth > this.mediaSize.naturalHeight ? 'reactEasyCrop_Cover_Horizontal' : 'reactEasyCrop_Cover_Vertical'), mediaClassName) 57175 }, mediaProps, { 57176 src: image, 57177 ref: this.imageRef, 57178 style: __assign(__assign({}, mediaStyle), { 57179 transform: transform || "translate(".concat(x, "px, ").concat(y, "px) rotate(").concat(rotation, "deg) scale(").concat(zoom, ")") 57180 }), 57181 onLoad: this.onMediaLoad 57182 })) : video && external_React_default().createElement("video", __assign({ 57183 autoPlay: true, 57184 loop: true, 57185 muted: true, 57186 className: classNames('reactEasyCrop_Video', objectFit === 'contain' && 'reactEasyCrop_Contain', objectFit === 'horizontal-cover' && 'reactEasyCrop_Cover_Horizontal', objectFit === 'vertical-cover' && 'reactEasyCrop_Cover_Vertical', objectFit === 'auto-cover' && (this.mediaSize.naturalWidth > this.mediaSize.naturalHeight ? 'reactEasyCrop_Cover_Horizontal' : 'reactEasyCrop_Cover_Vertical'), mediaClassName) 57187 }, mediaProps, { 57188 ref: this.videoRef, 57189 onLoadedMetadata: this.onMediaLoad, 57190 style: __assign(__assign({}, mediaStyle), { 57191 transform: transform || "translate(".concat(x, "px, ").concat(y, "px) rotate(").concat(rotation, "deg) scale(").concat(zoom, ")") 57192 }), 57193 controls: false 57194 }), (Array.isArray(video) ? video : [{ 57195 src: video 57196 }]).map(function (item) { 57197 return external_React_default().createElement("source", __assign({ 57198 key: item.src 57199 }, item)); 57200 })), this.state.cropSize && external_React_default().createElement("div", { 57201 style: __assign(__assign({}, cropAreaStyle), { 57202 width: this.state.cropSize.width, 57203 height: this.state.cropSize.height 57204 }), 57205 "data-testid": "cropper", 57206 className: classNames('reactEasyCrop_CropArea', cropShape === 'round' && 'reactEasyCrop_CropAreaRound', showGrid && 'reactEasyCrop_CropAreaGrid', cropAreaClassName) 57207 })); 57208 }; 57209 Cropper.defaultProps = { 57210 zoom: 1, 57211 rotation: 0, 57212 aspect: 4 / 3, 57213 maxZoom: MAX_ZOOM, 57214 minZoom: MIN_ZOOM, 57215 cropShape: 'rect', 57216 objectFit: 'contain', 57217 showGrid: true, 57218 style: {}, 57219 classes: {}, 57220 mediaProps: {}, 57221 zoomSpeed: 1, 57222 restrictPosition: true, 57223 zoomWithScroll: true 57224 }; 57225 Cropper.getMousePoint = function (e) { 57226 return { 57227 x: Number(e.clientX), 57228 y: Number(e.clientY) 57229 }; 57230 }; 57231 Cropper.getTouchPoint = function (touch) { 57232 return { 57233 x: Number(touch.clientX), 57234 y: Number(touch.clientY) 57235 }; 57236 }; 57237 return Cropper; 57238 }((external_React_default()).Component); 57239 57240 57241 57242 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/image-editor/constants.js 57243 const constants_MIN_ZOOM = 100; 57244 const constants_MAX_ZOOM = 300; 57245 const constants_POPOVER_PROPS = { 57246 placement: 'bottom-start' 57247 }; 57248 57249 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/image-editor/cropper.js 57250 57251 /** 57252 * External dependencies 57253 */ 57254 57255 57256 57257 /** 57258 * WordPress dependencies 57259 */ 57260 57261 57262 /** 57263 * Internal dependencies 57264 */ 57265 57266 57267 function ImageCropper({ 57268 url, 57269 width, 57270 height, 57271 clientWidth, 57272 naturalHeight, 57273 naturalWidth, 57274 borderProps 57275 }) { 57276 const { 57277 isInProgress, 57278 editedUrl, 57279 position, 57280 zoom, 57281 aspect, 57282 setPosition, 57283 setCrop, 57284 setZoom, 57285 rotation 57286 } = useImageEditingContext(); 57287 let editedHeight = height || clientWidth * naturalHeight / naturalWidth; 57288 if (rotation % 180 === 90) { 57289 editedHeight = clientWidth * naturalWidth / naturalHeight; 57290 } 57291 return (0,external_React_.createElement)("div", { 57292 className: classnames_default()('wp-block-image__crop-area', borderProps?.className, { 57293 'is-applying': isInProgress 57294 }), 57295 style: { 57296 ...borderProps?.style, 57297 width: width || clientWidth, 57298 height: editedHeight 57299 } 57300 }, (0,external_React_.createElement)(Cropper, { 57301 image: editedUrl || url, 57302 disabled: isInProgress, 57303 minZoom: constants_MIN_ZOOM / 100, 57304 maxZoom: constants_MAX_ZOOM / 100, 57305 crop: position, 57306 zoom: zoom / 100, 57307 aspect: aspect, 57308 onCropChange: pos => { 57309 setPosition(pos); 57310 }, 57311 onCropComplete: newCropPercent => { 57312 setCrop(newCropPercent); 57313 }, 57314 onZoomChange: newZoom => { 57315 setZoom(newZoom * 100); 57316 } 57317 }), isInProgress && (0,external_React_.createElement)(external_wp_components_namespaceObject.Spinner, null)); 57318 } 57319 57320 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/search.js 57321 57322 /** 57323 * WordPress dependencies 57324 */ 57325 57326 const search = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 57327 xmlns: "http://www.w3.org/2000/svg", 57328 viewBox: "0 0 24 24" 57329 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 57330 d: "M13 5c-3.3 0-6 2.7-6 6 0 1.4.5 2.7 1.3 3.7l-3.8 3.8 1.1 1.1 3.8-3.8c1 .8 2.3 1.3 3.7 1.3 3.3 0 6-2.7 6-6S16.3 5 13 5zm0 10.5c-2.5 0-4.5-2-4.5-4.5s2-4.5 4.5-4.5 4.5 2 4.5 4.5-2 4.5-4.5 4.5z" 57331 })); 57332 /* harmony default export */ const library_search = (search); 57333 57334 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/image-editor/zoom-dropdown.js 57335 57336 /** 57337 * WordPress dependencies 57338 */ 57339 57340 57341 57342 57343 /** 57344 * Internal dependencies 57345 */ 57346 57347 57348 function ZoomDropdown() { 57349 const { 57350 isInProgress, 57351 zoom, 57352 setZoom 57353 } = useImageEditingContext(); 57354 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Dropdown, { 57355 contentClassName: "wp-block-image__zoom", 57356 popoverProps: constants_POPOVER_PROPS, 57357 renderToggle: ({ 57358 isOpen, 57359 onToggle 57360 }) => (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarButton, { 57361 icon: library_search, 57362 label: (0,external_wp_i18n_namespaceObject.__)('Zoom'), 57363 onClick: onToggle, 57364 "aria-expanded": isOpen, 57365 disabled: isInProgress 57366 }), 57367 renderContent: () => (0,external_React_.createElement)(external_wp_components_namespaceObject.RangeControl, { 57368 __nextHasNoMarginBottom: true, 57369 label: (0,external_wp_i18n_namespaceObject.__)('Zoom'), 57370 min: constants_MIN_ZOOM, 57371 max: constants_MAX_ZOOM, 57372 value: Math.round(zoom), 57373 onChange: setZoom 57374 }) 57375 }); 57376 } 57377 57378 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/aspect-ratio.js 57379 57380 /** 57381 * WordPress dependencies 57382 */ 57383 57384 const aspectRatio = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 57385 xmlns: "http://www.w3.org/2000/svg", 57386 viewBox: "0 0 24 24" 57387 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 57388 d: "M18.5 5.5h-13c-1.1 0-2 .9-2 2v9c0 1.1.9 2 2 2h13c1.1 0 2-.9 2-2v-9c0-1.1-.9-2-2-2zm.5 11c0 .3-.2.5-.5.5h-13c-.3 0-.5-.2-.5-.5v-9c0-.3.2-.5.5-.5h13c.3 0 .5.2.5.5v9zM6.5 12H8v-2h2V8.5H6.5V12zm9.5 2h-2v1.5h3.5V12H16v2z" 57389 })); 57390 /* harmony default export */ const aspect_ratio = (aspectRatio); 57391 57392 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/image-editor/aspect-ratio-dropdown.js 57393 57394 /** 57395 * WordPress dependencies 57396 */ 57397 57398 57399 57400 57401 /** 57402 * Internal dependencies 57403 */ 57404 57405 57406 function AspectGroup({ 57407 aspectRatios, 57408 isDisabled, 57409 label, 57410 onClick, 57411 value 57412 }) { 57413 return (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuGroup, { 57414 label: label 57415 }, aspectRatios.map(({ 57416 title, 57417 aspect 57418 }) => (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 57419 key: aspect, 57420 disabled: isDisabled, 57421 onClick: () => { 57422 onClick(aspect); 57423 }, 57424 role: "menuitemradio", 57425 isSelected: aspect === value, 57426 icon: aspect === value ? library_check : undefined 57427 }, title))); 57428 } 57429 function AspectRatioDropdown({ 57430 toggleProps 57431 }) { 57432 const { 57433 isInProgress, 57434 aspect, 57435 setAspect, 57436 defaultAspect 57437 } = useImageEditingContext(); 57438 return (0,external_React_.createElement)(external_wp_components_namespaceObject.DropdownMenu, { 57439 icon: aspect_ratio, 57440 label: (0,external_wp_i18n_namespaceObject.__)('Aspect Ratio'), 57441 popoverProps: constants_POPOVER_PROPS, 57442 toggleProps: toggleProps, 57443 className: "wp-block-image__aspect-ratio" 57444 }, ({ 57445 onClose 57446 }) => (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(AspectGroup, { 57447 isDisabled: isInProgress, 57448 onClick: newAspect => { 57449 setAspect(newAspect); 57450 onClose(); 57451 }, 57452 value: aspect, 57453 aspectRatios: [ 57454 // All ratios should be mirrored in AspectRatioTool in @wordpress/block-editor. 57455 { 57456 title: (0,external_wp_i18n_namespaceObject.__)('Original'), 57457 aspect: defaultAspect 57458 }, { 57459 title: (0,external_wp_i18n_namespaceObject.__)('Square'), 57460 aspect: 1 57461 }] 57462 }), (0,external_React_.createElement)(AspectGroup, { 57463 label: (0,external_wp_i18n_namespaceObject.__)('Landscape'), 57464 isDisabled: isInProgress, 57465 onClick: newAspect => { 57466 setAspect(newAspect); 57467 onClose(); 57468 }, 57469 value: aspect, 57470 aspectRatios: [{ 57471 title: (0,external_wp_i18n_namespaceObject.__)('16:9'), 57472 aspect: 16 / 9 57473 }, { 57474 title: (0,external_wp_i18n_namespaceObject.__)('4:3'), 57475 aspect: 4 / 3 57476 }, { 57477 title: (0,external_wp_i18n_namespaceObject.__)('3:2'), 57478 aspect: 3 / 2 57479 }] 57480 }), (0,external_React_.createElement)(AspectGroup, { 57481 label: (0,external_wp_i18n_namespaceObject.__)('Portrait'), 57482 isDisabled: isInProgress, 57483 onClick: newAspect => { 57484 setAspect(newAspect); 57485 onClose(); 57486 }, 57487 value: aspect, 57488 aspectRatios: [{ 57489 title: (0,external_wp_i18n_namespaceObject.__)('9:16'), 57490 aspect: 9 / 16 57491 }, { 57492 title: (0,external_wp_i18n_namespaceObject.__)('3:4'), 57493 aspect: 3 / 4 57494 }, { 57495 title: (0,external_wp_i18n_namespaceObject.__)('2:3'), 57496 aspect: 2 / 3 57497 }] 57498 }))); 57499 } 57500 57501 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/rotate-right.js 57502 57503 /** 57504 * WordPress dependencies 57505 */ 57506 57507 const rotateRight = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 57508 xmlns: "http://www.w3.org/2000/svg", 57509 viewBox: "0 0 24 24" 57510 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 57511 d: "M15.1 4.8l-3-2.5V4c-4.4 0-8 3.6-8 8 0 3.7 2.5 6.9 6 7.7.3.1.6.1 1 .2l.2-1.5c-.4 0-.7-.1-1.1-.2l-.1.2v-.2c-2.6-.8-4.5-3.3-4.5-6.2 0-3.6 2.9-6.5 6.5-6.5v1.8l3-2.5zM20 11c-.2-1.4-.7-2.7-1.6-3.8l-1.2.8c.7.9 1.1 2 1.3 3.1L20 11zm-1.5 1.8c-.1.5-.2 1.1-.4 1.6s-.5 1-.8 1.5l1.2.9c.4-.5.8-1.1 1-1.8s.5-1.3.5-2l-1.5-.2zm-5.6 5.6l.2 1.5c1.4-.2 2.7-.7 3.8-1.6l-.9-1.1c-.9.7-2 1.1-3.1 1.2z" 57512 })); 57513 /* harmony default export */ const rotate_right = (rotateRight); 57514 57515 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/image-editor/rotation-button.js 57516 57517 /** 57518 * WordPress dependencies 57519 */ 57520 57521 57522 57523 57524 57525 /** 57526 * Internal dependencies 57527 */ 57528 57529 function RotationButton() { 57530 const { 57531 isInProgress, 57532 rotateClockwise 57533 } = useImageEditingContext(); 57534 return (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarButton, { 57535 icon: rotate_right, 57536 label: (0,external_wp_i18n_namespaceObject.__)('Rotate'), 57537 onClick: rotateClockwise, 57538 disabled: isInProgress 57539 }); 57540 } 57541 57542 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/image-editor/form-controls.js 57543 57544 /** 57545 * WordPress dependencies 57546 */ 57547 57548 57549 57550 /** 57551 * Internal dependencies 57552 */ 57553 57554 function FormControls() { 57555 const { 57556 isInProgress, 57557 apply, 57558 cancel 57559 } = useImageEditingContext(); 57560 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarButton, { 57561 onClick: apply, 57562 disabled: isInProgress 57563 }, (0,external_wp_i18n_namespaceObject.__)('Apply')), (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarButton, { 57564 onClick: cancel 57565 }, (0,external_wp_i18n_namespaceObject.__)('Cancel'))); 57566 } 57567 57568 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/image-editor/index.js 57569 57570 /** 57571 * WordPress dependencies 57572 */ 57573 57574 57575 /** 57576 * Internal dependencies 57577 */ 57578 57579 57580 57581 57582 57583 57584 57585 function ImageEditor({ 57586 id, 57587 url, 57588 width, 57589 height, 57590 clientWidth, 57591 naturalHeight, 57592 naturalWidth, 57593 onSaveImage, 57594 onFinishEditing, 57595 borderProps 57596 }) { 57597 return (0,external_React_.createElement)(ImageEditingProvider, { 57598 id: id, 57599 url: url, 57600 naturalWidth: naturalWidth, 57601 naturalHeight: naturalHeight, 57602 onSaveImage: onSaveImage, 57603 onFinishEditing: onFinishEditing 57604 }, (0,external_React_.createElement)(ImageCropper, { 57605 borderProps: borderProps, 57606 url: url, 57607 width: width, 57608 height: height, 57609 clientWidth: clientWidth, 57610 naturalHeight: naturalHeight, 57611 naturalWidth: naturalWidth 57612 }), (0,external_React_.createElement)(block_controls, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarGroup, null, (0,external_React_.createElement)(ZoomDropdown, null), (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarItem, null, toggleProps => (0,external_React_.createElement)(AspectRatioDropdown, { 57613 toggleProps: toggleProps 57614 })), (0,external_React_.createElement)(RotationButton, null)), (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarGroup, null, (0,external_React_.createElement)(FormControls, null)))); 57615 } 57616 57617 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/image-size-control/use-dimension-handler.js 57618 /** 57619 * WordPress dependencies 57620 */ 57621 57622 function useDimensionHandler(customHeight, customWidth, defaultHeight, defaultWidth, onChange) { 57623 var _ref, _ref2; 57624 const [currentWidth, setCurrentWidth] = (0,external_wp_element_namespaceObject.useState)((_ref = customWidth !== null && customWidth !== void 0 ? customWidth : defaultWidth) !== null && _ref !== void 0 ? _ref : ''); 57625 const [currentHeight, setCurrentHeight] = (0,external_wp_element_namespaceObject.useState)((_ref2 = customHeight !== null && customHeight !== void 0 ? customHeight : defaultHeight) !== null && _ref2 !== void 0 ? _ref2 : ''); 57626 57627 // When an image is first inserted, the default dimensions are initially 57628 // undefined. This effect updates the dimensions when the default values 57629 // come through. 57630 (0,external_wp_element_namespaceObject.useEffect)(() => { 57631 if (customWidth === undefined && defaultWidth !== undefined) { 57632 setCurrentWidth(defaultWidth); 57633 } 57634 if (customHeight === undefined && defaultHeight !== undefined) { 57635 setCurrentHeight(defaultHeight); 57636 } 57637 }, [defaultWidth, defaultHeight]); 57638 57639 // If custom values change, it means an outsider has resized the image using some other method (eg resize box) 57640 // this keeps track of these values too. We need to parse before comparing; custom values can be strings. 57641 (0,external_wp_element_namespaceObject.useEffect)(() => { 57642 if (customWidth !== undefined && Number.parseInt(customWidth) !== Number.parseInt(currentWidth)) { 57643 setCurrentWidth(customWidth); 57644 } 57645 if (customHeight !== undefined && Number.parseInt(customHeight) !== Number.parseInt(currentHeight)) { 57646 setCurrentHeight(customHeight); 57647 } 57648 }, [customWidth, customHeight]); 57649 const updateDimension = (dimension, value) => { 57650 const parsedValue = value === '' ? undefined : parseInt(value, 10); 57651 if (dimension === 'width') { 57652 setCurrentWidth(parsedValue); 57653 } else { 57654 setCurrentHeight(parsedValue); 57655 } 57656 onChange({ 57657 [dimension]: parsedValue 57658 }); 57659 }; 57660 const updateDimensions = (nextHeight, nextWidth) => { 57661 setCurrentHeight(nextHeight !== null && nextHeight !== void 0 ? nextHeight : defaultHeight); 57662 setCurrentWidth(nextWidth !== null && nextWidth !== void 0 ? nextWidth : defaultWidth); 57663 onChange({ 57664 height: nextHeight, 57665 width: nextWidth 57666 }); 57667 }; 57668 return { 57669 currentHeight, 57670 currentWidth, 57671 updateDimension, 57672 updateDimensions 57673 }; 57674 } 57675 57676 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/image-size-control/index.js 57677 57678 /** 57679 * WordPress dependencies 57680 */ 57681 57682 57683 57684 /** 57685 * Internal dependencies 57686 */ 57687 57688 const IMAGE_SIZE_PRESETS = [25, 50, 75, 100]; 57689 const image_size_control_noop = () => {}; 57690 function ImageSizeControl({ 57691 imageSizeHelp, 57692 imageWidth, 57693 imageHeight, 57694 imageSizeOptions = [], 57695 isResizable = true, 57696 slug, 57697 width, 57698 height, 57699 onChange, 57700 onChangeImage = image_size_control_noop 57701 }) { 57702 const { 57703 currentHeight, 57704 currentWidth, 57705 updateDimension, 57706 updateDimensions 57707 } = useDimensionHandler(height, width, imageHeight, imageWidth, onChange); 57708 return (0,external_React_.createElement)(external_React_.Fragment, null, imageSizeOptions && imageSizeOptions.length > 0 && (0,external_React_.createElement)(external_wp_components_namespaceObject.SelectControl, { 57709 __nextHasNoMarginBottom: true, 57710 label: (0,external_wp_i18n_namespaceObject.__)('Resolution'), 57711 value: slug, 57712 options: imageSizeOptions, 57713 onChange: onChangeImage, 57714 help: imageSizeHelp, 57715 size: "__unstable-large" 57716 }), isResizable && (0,external_React_.createElement)("div", { 57717 className: "block-editor-image-size-control" 57718 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, { 57719 align: "baseline", 57720 spacing: "3" 57721 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalNumberControl, { 57722 className: "block-editor-image-size-control__width", 57723 label: (0,external_wp_i18n_namespaceObject.__)('Width'), 57724 value: currentWidth, 57725 min: 1, 57726 onChange: value => updateDimension('width', value), 57727 size: "__unstable-large" 57728 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalNumberControl, { 57729 className: "block-editor-image-size-control__height", 57730 label: (0,external_wp_i18n_namespaceObject.__)('Height'), 57731 value: currentHeight, 57732 min: 1, 57733 onChange: value => updateDimension('height', value), 57734 size: "__unstable-large" 57735 })), (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.ButtonGroup, { 57736 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Image size presets') 57737 }, IMAGE_SIZE_PRESETS.map(scale => { 57738 const scaledWidth = Math.round(imageWidth * (scale / 100)); 57739 const scaledHeight = Math.round(imageHeight * (scale / 100)); 57740 const isCurrent = currentWidth === scaledWidth && currentHeight === scaledHeight; 57741 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 57742 key: scale, 57743 size: "small", 57744 variant: isCurrent ? 'primary' : undefined, 57745 isPressed: isCurrent, 57746 onClick: () => updateDimensions(scaledHeight, scaledWidth) 57747 }, scale, "%"); 57748 })), (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 57749 size: "small", 57750 onClick: () => updateDimensions() 57751 }, (0,external_wp_i18n_namespaceObject.__)('Reset'))))); 57752 } 57753 57754 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/url-popover/link-viewer-url.js 57755 57756 /** 57757 * External dependencies 57758 */ 57759 57760 57761 /** 57762 * WordPress dependencies 57763 */ 57764 57765 57766 function LinkViewerURL({ 57767 url, 57768 urlLabel, 57769 className 57770 }) { 57771 const linkClassName = classnames_default()(className, 'block-editor-url-popover__link-viewer-url'); 57772 if (!url) { 57773 return (0,external_React_.createElement)("span", { 57774 className: linkClassName 57775 }); 57776 } 57777 return (0,external_React_.createElement)(external_wp_components_namespaceObject.ExternalLink, { 57778 className: linkClassName, 57779 href: url 57780 }, urlLabel || (0,external_wp_url_namespaceObject.filterURLForDisplay)((0,external_wp_url_namespaceObject.safeDecodeURI)(url))); 57781 } 57782 57783 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/url-popover/link-viewer.js 57784 57785 /** 57786 * External dependencies 57787 */ 57788 57789 57790 /** 57791 * WordPress dependencies 57792 */ 57793 57794 57795 57796 57797 /** 57798 * Internal dependencies 57799 */ 57800 57801 function LinkViewer({ 57802 className, 57803 linkClassName, 57804 onEditLinkClick, 57805 url, 57806 urlLabel, 57807 ...props 57808 }) { 57809 return (0,external_React_.createElement)("div", { 57810 className: classnames_default()('block-editor-url-popover__link-viewer', className), 57811 ...props 57812 }, (0,external_React_.createElement)(LinkViewerURL, { 57813 url: url, 57814 urlLabel: urlLabel, 57815 className: linkClassName 57816 }), onEditLinkClick && (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 57817 icon: edit, 57818 label: (0,external_wp_i18n_namespaceObject.__)('Edit'), 57819 onClick: onEditLinkClick, 57820 size: "compact" 57821 })); 57822 } 57823 57824 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/url-popover/link-editor.js 57825 57826 /** 57827 * External dependencies 57828 */ 57829 57830 57831 /** 57832 * WordPress dependencies 57833 */ 57834 57835 57836 57837 57838 /** 57839 * Internal dependencies 57840 */ 57841 57842 function LinkEditor({ 57843 autocompleteRef, 57844 className, 57845 onChangeInputValue, 57846 value, 57847 ...props 57848 }) { 57849 return (0,external_React_.createElement)("form", { 57850 className: classnames_default()('block-editor-url-popover__link-editor', className), 57851 ...props 57852 }, (0,external_React_.createElement)(url_input, { 57853 __nextHasNoMarginBottom: true, 57854 value: value, 57855 onChange: onChangeInputValue, 57856 autocompleteRef: autocompleteRef 57857 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 57858 icon: keyboard_return, 57859 label: (0,external_wp_i18n_namespaceObject.__)('Apply'), 57860 type: "submit", 57861 size: "compact" 57862 })); 57863 } 57864 57865 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/url-popover/index.js 57866 57867 /** 57868 * WordPress dependencies 57869 */ 57870 57871 57872 57873 57874 57875 57876 /** 57877 * Internal dependencies 57878 */ 57879 57880 57881 57882 const { 57883 __experimentalPopoverLegacyPositionToPlacement 57884 } = unlock(external_wp_components_namespaceObject.privateApis); 57885 const DEFAULT_PLACEMENT = 'bottom'; 57886 const URLPopover = (0,external_wp_element_namespaceObject.forwardRef)(({ 57887 additionalControls, 57888 children, 57889 renderSettings, 57890 // The DEFAULT_PLACEMENT value is assigned inside the function's body 57891 placement, 57892 focusOnMount = 'firstElement', 57893 // Deprecated 57894 position, 57895 // Rest 57896 ...popoverProps 57897 }, ref) => { 57898 if (position !== undefined) { 57899 external_wp_deprecated_default()('`position` prop in wp.blockEditor.URLPopover', { 57900 since: '6.2', 57901 alternative: '`placement` prop' 57902 }); 57903 } 57904 57905 // Compute popover's placement: 57906 // - give priority to `placement` prop, if defined 57907 // - otherwise, compute it from the legacy `position` prop (if defined) 57908 // - finally, fallback to the DEFAULT_PLACEMENT. 57909 let computedPlacement; 57910 if (placement !== undefined) { 57911 computedPlacement = placement; 57912 } else if (position !== undefined) { 57913 computedPlacement = __experimentalPopoverLegacyPositionToPlacement(position); 57914 } 57915 computedPlacement = computedPlacement || DEFAULT_PLACEMENT; 57916 const [isSettingsExpanded, setIsSettingsExpanded] = (0,external_wp_element_namespaceObject.useState)(false); 57917 const showSettings = !!renderSettings && isSettingsExpanded; 57918 const toggleSettingsVisibility = () => { 57919 setIsSettingsExpanded(!isSettingsExpanded); 57920 }; 57921 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Popover, { 57922 ref: ref, 57923 className: "block-editor-url-popover", 57924 focusOnMount: focusOnMount, 57925 placement: computedPlacement, 57926 shift: true, 57927 variant: "toolbar", 57928 ...popoverProps 57929 }, (0,external_React_.createElement)("div", { 57930 className: "block-editor-url-popover__input-container" 57931 }, (0,external_React_.createElement)("div", { 57932 className: "block-editor-url-popover__row" 57933 }, children, !!renderSettings && (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 57934 className: "block-editor-url-popover__settings-toggle", 57935 icon: chevron_down, 57936 label: (0,external_wp_i18n_namespaceObject.__)('Link settings'), 57937 onClick: toggleSettingsVisibility, 57938 "aria-expanded": isSettingsExpanded, 57939 size: "compact" 57940 }))), showSettings && (0,external_React_.createElement)("div", { 57941 className: "block-editor-url-popover__settings" 57942 }, renderSettings()), additionalControls && !showSettings && (0,external_React_.createElement)("div", { 57943 className: "block-editor-url-popover__additional-controls" 57944 }, additionalControls)); 57945 }); 57946 URLPopover.LinkEditor = LinkEditor; 57947 URLPopover.LinkViewer = LinkViewer; 57948 57949 /** 57950 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/url-popover/README.md 57951 */ 57952 /* harmony default export */ const url_popover = (URLPopover); 57953 57954 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/media-placeholder/index.js 57955 57956 /** 57957 * External dependencies 57958 */ 57959 57960 57961 /** 57962 * WordPress dependencies 57963 */ 57964 57965 57966 57967 57968 57969 57970 57971 57972 /** 57973 * Internal dependencies 57974 */ 57975 57976 57977 57978 57979 const media_placeholder_noop = () => {}; 57980 const InsertFromURLPopover = ({ 57981 src, 57982 onChange, 57983 onSubmit, 57984 onClose, 57985 popoverAnchor 57986 }) => (0,external_React_.createElement)(url_popover, { 57987 anchor: popoverAnchor, 57988 onClose: onClose 57989 }, (0,external_React_.createElement)("form", { 57990 className: "block-editor-media-placeholder__url-input-form", 57991 onSubmit: onSubmit 57992 }, (0,external_React_.createElement)("input", { 57993 className: "block-editor-media-placeholder__url-input-field", 57994 type: "text", 57995 "aria-label": (0,external_wp_i18n_namespaceObject.__)('URL'), 57996 placeholder: (0,external_wp_i18n_namespaceObject.__)('Paste or type URL'), 57997 onChange: onChange, 57998 value: src 57999 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 58000 className: "block-editor-media-placeholder__url-input-submit-button", 58001 icon: keyboard_return, 58002 label: (0,external_wp_i18n_namespaceObject.__)('Apply'), 58003 type: "submit" 58004 }))); 58005 const URLSelectionUI = ({ 58006 isURLInputVisible, 58007 src, 58008 onChangeSrc, 58009 onSubmitSrc, 58010 openURLInput, 58011 closeURLInput 58012 }) => { 58013 // Use internal state instead of a ref to make sure that the component 58014 // re-renders when the popover's anchor updates. 58015 const [popoverAnchor, setPopoverAnchor] = (0,external_wp_element_namespaceObject.useState)(null); 58016 return (0,external_React_.createElement)("div", { 58017 className: "block-editor-media-placeholder__url-input-container", 58018 ref: setPopoverAnchor 58019 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 58020 className: "block-editor-media-placeholder__button", 58021 onClick: openURLInput, 58022 isPressed: isURLInputVisible, 58023 variant: "tertiary" 58024 }, (0,external_wp_i18n_namespaceObject.__)('Insert from URL')), isURLInputVisible && (0,external_React_.createElement)(InsertFromURLPopover, { 58025 src: src, 58026 onChange: onChangeSrc, 58027 onSubmit: onSubmitSrc, 58028 onClose: closeURLInput, 58029 popoverAnchor: popoverAnchor 58030 })); 58031 }; 58032 function MediaPlaceholder({ 58033 value = {}, 58034 allowedTypes, 58035 className, 58036 icon, 58037 labels = {}, 58038 mediaPreview, 58039 notices, 58040 isAppender, 58041 accept, 58042 addToGallery, 58043 multiple = false, 58044 handleUpload = true, 58045 disableDropZone, 58046 disableMediaButtons, 58047 onError, 58048 onSelect, 58049 onCancel, 58050 onSelectURL, 58051 onToggleFeaturedImage, 58052 onDoubleClick, 58053 onFilesPreUpload = media_placeholder_noop, 58054 onHTMLDrop: deprecatedOnHTMLDrop, 58055 children, 58056 mediaLibraryButton, 58057 placeholder, 58058 style 58059 }) { 58060 if (deprecatedOnHTMLDrop) { 58061 external_wp_deprecated_default()('wp.blockEditor.MediaPlaceholder onHTMLDrop prop', { 58062 since: '6.2', 58063 version: '6.4' 58064 }); 58065 } 58066 const mediaUpload = (0,external_wp_data_namespaceObject.useSelect)(select => { 58067 const { 58068 getSettings 58069 } = select(store); 58070 return getSettings().mediaUpload; 58071 }, []); 58072 const [src, setSrc] = (0,external_wp_element_namespaceObject.useState)(''); 58073 const [isURLInputVisible, setIsURLInputVisible] = (0,external_wp_element_namespaceObject.useState)(false); 58074 (0,external_wp_element_namespaceObject.useEffect)(() => { 58075 var _value$src; 58076 setSrc((_value$src = value?.src) !== null && _value$src !== void 0 ? _value$src : ''); 58077 }, [value?.src]); 58078 const onlyAllowsImages = () => { 58079 if (!allowedTypes || allowedTypes.length === 0) { 58080 return false; 58081 } 58082 return allowedTypes.every(allowedType => allowedType === 'image' || allowedType.startsWith('image/')); 58083 }; 58084 const onChangeSrc = event => { 58085 setSrc(event.target.value); 58086 }; 58087 const openURLInput = () => { 58088 setIsURLInputVisible(true); 58089 }; 58090 const closeURLInput = () => { 58091 setIsURLInputVisible(false); 58092 }; 58093 const onSubmitSrc = event => { 58094 event.preventDefault(); 58095 if (src && onSelectURL) { 58096 onSelectURL(src); 58097 closeURLInput(); 58098 } 58099 }; 58100 const onFilesUpload = files => { 58101 if (!handleUpload) { 58102 return onSelect(files); 58103 } 58104 onFilesPreUpload(files); 58105 let setMedia; 58106 if (multiple) { 58107 if (addToGallery) { 58108 // Since the setMedia function runs multiple times per upload group 58109 // and is passed newMedia containing every item in its group each time, we must 58110 // filter out whatever this upload group had previously returned to the 58111 // gallery before adding and returning the image array with replacement newMedia 58112 // values. 58113 58114 // Define an array to store urls from newMedia between subsequent function calls. 58115 let lastMediaPassed = []; 58116 setMedia = newMedia => { 58117 // Remove any images this upload group is responsible for (lastMediaPassed). 58118 // Their replacements are contained in newMedia. 58119 const filteredMedia = (value !== null && value !== void 0 ? value : []).filter(item => { 58120 // If Item has id, only remove it if lastMediaPassed has an item with that id. 58121 if (item.id) { 58122 return !lastMediaPassed.some( 58123 // Be sure to convert to number for comparison. 58124 ({ 58125 id 58126 }) => Number(id) === Number(item.id)); 58127 } 58128 // Compare transient images via .includes since gallery may append extra info onto the url. 58129 return !lastMediaPassed.some(({ 58130 urlSlug 58131 }) => item.url.includes(urlSlug)); 58132 }); 58133 // Return the filtered media array along with newMedia. 58134 onSelect(filteredMedia.concat(newMedia)); 58135 // Reset lastMediaPassed and set it with ids and urls from newMedia. 58136 lastMediaPassed = newMedia.map(media => { 58137 // Add everything up to '.fileType' to compare via .includes. 58138 const cutOffIndex = media.url.lastIndexOf('.'); 58139 const urlSlug = media.url.slice(0, cutOffIndex); 58140 return { 58141 id: media.id, 58142 urlSlug 58143 }; 58144 }); 58145 }; 58146 } else { 58147 setMedia = onSelect; 58148 } 58149 } else { 58150 setMedia = ([media]) => onSelect(media); 58151 } 58152 mediaUpload({ 58153 allowedTypes, 58154 filesList: files, 58155 onFileChange: setMedia, 58156 onError 58157 }); 58158 }; 58159 async function handleBlocksDrop(blocks) { 58160 if (!blocks || !Array.isArray(blocks)) { 58161 return; 58162 } 58163 function recursivelyFindMediaFromBlocks(_blocks) { 58164 return _blocks.flatMap(block => (block.name === 'core/image' || block.name === 'core/audio' || block.name === 'core/video') && block.attributes.url ? [block] : recursivelyFindMediaFromBlocks(block.innerBlocks)); 58165 } 58166 const mediaBlocks = recursivelyFindMediaFromBlocks(blocks); 58167 if (!mediaBlocks.length) { 58168 return; 58169 } 58170 const uploadedMediaList = await Promise.all(mediaBlocks.map(block => block.attributes.id ? block.attributes : new Promise((resolve, reject) => { 58171 window.fetch(block.attributes.url).then(response => response.blob()).then(blob => mediaUpload({ 58172 filesList: [blob], 58173 additionalData: { 58174 title: block.attributes.title, 58175 alt_text: block.attributes.alt, 58176 caption: block.attributes.caption 58177 }, 58178 onFileChange: ([media]) => { 58179 if (media.id) { 58180 resolve(media); 58181 } 58182 }, 58183 allowedTypes, 58184 onError: reject 58185 })).catch(() => resolve(block.attributes.url)); 58186 }))).catch(err => onError(err)); 58187 if (multiple) { 58188 onSelect(uploadedMediaList); 58189 } else { 58190 onSelect(uploadedMediaList[0]); 58191 } 58192 } 58193 async function onHTMLDrop(HTML) { 58194 const blocks = (0,external_wp_blocks_namespaceObject.pasteHandler)({ 58195 HTML 58196 }); 58197 return await handleBlocksDrop(blocks); 58198 } 58199 const onUpload = event => { 58200 onFilesUpload(event.target.files); 58201 }; 58202 const defaultRenderPlaceholder = content => { 58203 let { 58204 instructions, 58205 title 58206 } = labels; 58207 if (!mediaUpload && !onSelectURL) { 58208 instructions = (0,external_wp_i18n_namespaceObject.__)('To edit this block, you need permission to upload media.'); 58209 } 58210 if (instructions === undefined || title === undefined) { 58211 const typesAllowed = allowedTypes !== null && allowedTypes !== void 0 ? allowedTypes : []; 58212 const [firstAllowedType] = typesAllowed; 58213 const isOneType = 1 === typesAllowed.length; 58214 const isAudio = isOneType && 'audio' === firstAllowedType; 58215 const isImage = isOneType && 'image' === firstAllowedType; 58216 const isVideo = isOneType && 'video' === firstAllowedType; 58217 if (instructions === undefined && mediaUpload) { 58218 instructions = (0,external_wp_i18n_namespaceObject.__)('Upload a media file or pick one from your media library.'); 58219 if (isAudio) { 58220 instructions = (0,external_wp_i18n_namespaceObject.__)('Upload an audio file, pick one from your media library, or add one with a URL.'); 58221 } else if (isImage) { 58222 instructions = (0,external_wp_i18n_namespaceObject.__)('Upload an image file, pick one from your media library, or add one with a URL.'); 58223 } else if (isVideo) { 58224 instructions = (0,external_wp_i18n_namespaceObject.__)('Upload a video file, pick one from your media library, or add one with a URL.'); 58225 } 58226 } 58227 if (title === undefined) { 58228 title = (0,external_wp_i18n_namespaceObject.__)('Media'); 58229 if (isAudio) { 58230 title = (0,external_wp_i18n_namespaceObject.__)('Audio'); 58231 } else if (isImage) { 58232 title = (0,external_wp_i18n_namespaceObject.__)('Image'); 58233 } else if (isVideo) { 58234 title = (0,external_wp_i18n_namespaceObject.__)('Video'); 58235 } 58236 } 58237 } 58238 const placeholderClassName = classnames_default()('block-editor-media-placeholder', className, { 58239 'is-appender': isAppender 58240 }); 58241 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Placeholder, { 58242 icon: icon, 58243 label: title, 58244 instructions: instructions, 58245 className: placeholderClassName, 58246 notices: notices, 58247 onDoubleClick: onDoubleClick, 58248 preview: mediaPreview, 58249 style: style 58250 }, content, children); 58251 }; 58252 const renderPlaceholder = placeholder !== null && placeholder !== void 0 ? placeholder : defaultRenderPlaceholder; 58253 const renderDropZone = () => { 58254 if (disableDropZone) { 58255 return null; 58256 } 58257 return (0,external_React_.createElement)(external_wp_components_namespaceObject.DropZone, { 58258 onFilesDrop: onFilesUpload, 58259 onHTMLDrop: onHTMLDrop 58260 }); 58261 }; 58262 const renderCancelLink = () => { 58263 return onCancel && (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 58264 className: "block-editor-media-placeholder__cancel-button", 58265 title: (0,external_wp_i18n_namespaceObject.__)('Cancel'), 58266 variant: "link", 58267 onClick: onCancel 58268 }, (0,external_wp_i18n_namespaceObject.__)('Cancel')); 58269 }; 58270 const renderUrlSelectionUI = () => { 58271 return onSelectURL && (0,external_React_.createElement)(URLSelectionUI, { 58272 isURLInputVisible: isURLInputVisible, 58273 src: src, 58274 onChangeSrc: onChangeSrc, 58275 onSubmitSrc: onSubmitSrc, 58276 openURLInput: openURLInput, 58277 closeURLInput: closeURLInput 58278 }); 58279 }; 58280 const renderFeaturedImageToggle = () => { 58281 return onToggleFeaturedImage && (0,external_React_.createElement)("div", { 58282 className: "block-editor-media-placeholder__url-input-container" 58283 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 58284 className: "block-editor-media-placeholder__button", 58285 onClick: onToggleFeaturedImage, 58286 variant: "tertiary" 58287 }, (0,external_wp_i18n_namespaceObject.__)('Use featured image'))); 58288 }; 58289 const renderMediaUploadChecked = () => { 58290 const defaultButton = ({ 58291 open 58292 }) => { 58293 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 58294 variant: "tertiary", 58295 onClick: () => { 58296 open(); 58297 } 58298 }, (0,external_wp_i18n_namespaceObject.__)('Media Library')); 58299 }; 58300 const libraryButton = mediaLibraryButton !== null && mediaLibraryButton !== void 0 ? mediaLibraryButton : defaultButton; 58301 const uploadMediaLibraryButton = (0,external_React_.createElement)(media_upload, { 58302 addToGallery: addToGallery, 58303 gallery: multiple && onlyAllowsImages(), 58304 multiple: multiple, 58305 onSelect: onSelect, 58306 allowedTypes: allowedTypes, 58307 mode: 'browse', 58308 value: Array.isArray(value) ? value.map(({ 58309 id 58310 }) => id) : value.id, 58311 render: libraryButton 58312 }); 58313 if (mediaUpload && isAppender) { 58314 return (0,external_React_.createElement)(external_React_.Fragment, null, renderDropZone(), (0,external_React_.createElement)(external_wp_components_namespaceObject.FormFileUpload, { 58315 onChange: onUpload, 58316 accept: accept, 58317 multiple: !!multiple, 58318 render: ({ 58319 openFileDialog 58320 }) => { 58321 const content = (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 58322 variant: "primary", 58323 className: classnames_default()('block-editor-media-placeholder__button', 'block-editor-media-placeholder__upload-button'), 58324 onClick: openFileDialog 58325 }, (0,external_wp_i18n_namespaceObject.__)('Upload')), uploadMediaLibraryButton, renderUrlSelectionUI(), renderFeaturedImageToggle(), renderCancelLink()); 58326 return renderPlaceholder(content); 58327 } 58328 })); 58329 } 58330 if (mediaUpload) { 58331 const content = (0,external_React_.createElement)(external_React_.Fragment, null, renderDropZone(), (0,external_React_.createElement)(external_wp_components_namespaceObject.FormFileUpload, { 58332 variant: "primary", 58333 className: classnames_default()('block-editor-media-placeholder__button', 'block-editor-media-placeholder__upload-button'), 58334 onChange: onUpload, 58335 accept: accept, 58336 multiple: !!multiple 58337 }, (0,external_wp_i18n_namespaceObject.__)('Upload')), uploadMediaLibraryButton, renderUrlSelectionUI(), renderFeaturedImageToggle(), renderCancelLink()); 58338 return renderPlaceholder(content); 58339 } 58340 return renderPlaceholder(uploadMediaLibraryButton); 58341 }; 58342 if (disableMediaButtons) { 58343 return (0,external_React_.createElement)(check, null, renderDropZone()); 58344 } 58345 return (0,external_React_.createElement)(check, { 58346 fallback: renderPlaceholder(renderUrlSelectionUI()) 58347 }, renderMediaUploadChecked()); 58348 } 58349 58350 /** 58351 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/media-placeholder/README.md 58352 */ 58353 /* harmony default export */ const media_placeholder = ((0,external_wp_components_namespaceObject.withFilters)('editor.MediaPlaceholder')(MediaPlaceholder)); 58354 58355 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/panel-color-settings/index.js 58356 58357 /** 58358 * Internal dependencies 58359 */ 58360 58361 const PanelColorSettings = ({ 58362 colorSettings, 58363 ...props 58364 }) => { 58365 const settings = colorSettings.map(setting => { 58366 if (!setting) { 58367 return setting; 58368 } 58369 const { 58370 value, 58371 onChange, 58372 ...otherSettings 58373 } = setting; 58374 return { 58375 ...otherSettings, 58376 colorValue: value, 58377 onColorChange: onChange 58378 }; 58379 }); 58380 return (0,external_React_.createElement)(panel_color_gradient_settings, { 58381 settings: settings, 58382 gradients: [], 58383 disableCustomGradients: true, 58384 ...props 58385 }); 58386 }; 58387 /* harmony default export */ const panel_color_settings = (PanelColorSettings); 58388 58389 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/format-toolbar/index.js 58390 58391 /** 58392 * External dependencies 58393 */ 58394 58395 58396 /** 58397 * WordPress dependencies 58398 */ 58399 58400 58401 58402 58403 /** 58404 * Internal dependencies 58405 */ 58406 58407 const format_toolbar_POPOVER_PROPS = { 58408 placement: 'bottom-start' 58409 }; 58410 const FormatToolbar = () => { 58411 return (0,external_React_.createElement)(external_React_.Fragment, null, ['bold', 'italic', 'link', 'unknown'].map(format => (0,external_React_.createElement)(external_wp_components_namespaceObject.Slot, { 58412 name: `RichText.ToolbarControls.$format}`, 58413 key: format 58414 })), (0,external_React_.createElement)(external_wp_components_namespaceObject.Slot, { 58415 name: "RichText.ToolbarControls" 58416 }, fills => { 58417 if (!fills.length) { 58418 return null; 58419 } 58420 const allProps = fills.map(([{ 58421 props 58422 }]) => props); 58423 const hasActive = allProps.some(({ 58424 isActive 58425 }) => isActive); 58426 return (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarItem, null, toggleProps => (0,external_React_.createElement)(external_wp_components_namespaceObject.DropdownMenu, { 58427 icon: chevron_down 58428 /* translators: button label text should, if possible, be under 16 characters. */, 58429 label: (0,external_wp_i18n_namespaceObject.__)('More'), 58430 toggleProps: { 58431 ...toggleProps, 58432 className: classnames_default()(toggleProps.className, { 58433 'is-pressed': hasActive 58434 }), 58435 describedBy: (0,external_wp_i18n_namespaceObject.__)('Displays more block tools') 58436 }, 58437 controls: orderBy(fills.map(([{ 58438 props 58439 }]) => props), 'title'), 58440 popoverProps: format_toolbar_POPOVER_PROPS 58441 })); 58442 })); 58443 }; 58444 /* harmony default export */ const format_toolbar = (FormatToolbar); 58445 58446 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/format-toolbar-container.js 58447 58448 /** 58449 * WordPress dependencies 58450 */ 58451 58452 58453 58454 58455 58456 /** 58457 * Internal dependencies 58458 */ 58459 58460 58461 58462 58463 function InlineSelectionToolbar({ 58464 editableContentElement, 58465 activeFormats 58466 }) { 58467 const lastFormat = activeFormats[activeFormats.length - 1]; 58468 const lastFormatType = lastFormat?.type; 58469 const settings = (0,external_wp_data_namespaceObject.useSelect)(select => select(external_wp_richText_namespaceObject.store).getFormatType(lastFormatType), [lastFormatType]); 58470 const popoverAnchor = (0,external_wp_richText_namespaceObject.useAnchor)({ 58471 editableContentElement, 58472 settings 58473 }); 58474 return (0,external_React_.createElement)(InlineToolbar, { 58475 popoverAnchor: popoverAnchor 58476 }); 58477 } 58478 function InlineToolbar({ 58479 popoverAnchor 58480 }) { 58481 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Popover, { 58482 placement: "top", 58483 focusOnMount: false, 58484 anchor: popoverAnchor, 58485 className: "block-editor-rich-text__inline-format-toolbar", 58486 __unstableSlotName: "block-toolbar" 58487 }, (0,external_React_.createElement)(NavigableToolbar, { 58488 className: "block-editor-rich-text__inline-format-toolbar-group" 58489 /* translators: accessibility text for the inline format toolbar */, 58490 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Format tools') 58491 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarGroup, null, (0,external_React_.createElement)(format_toolbar, null)))); 58492 } 58493 const FormatToolbarContainer = ({ 58494 inline, 58495 editableContentElement, 58496 value 58497 }) => { 58498 const hasInlineToolbar = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getSettings().hasInlineToolbar, []); 58499 if (inline) { 58500 return (0,external_React_.createElement)(InlineToolbar, { 58501 popoverAnchor: editableContentElement 58502 }); 58503 } 58504 if (hasInlineToolbar) { 58505 const activeFormats = (0,external_wp_richText_namespaceObject.getActiveFormats)(value); 58506 if ((0,external_wp_richText_namespaceObject.isCollapsed)(value) && !activeFormats.length) { 58507 return null; 58508 } 58509 return (0,external_React_.createElement)(InlineSelectionToolbar, { 58510 editableContentElement: editableContentElement, 58511 activeFormats: activeFormats 58512 }); 58513 } 58514 58515 // Render regular toolbar. 58516 return (0,external_React_.createElement)(block_controls, { 58517 group: "inline" 58518 }, (0,external_React_.createElement)(format_toolbar, null)); 58519 }; 58520 /* harmony default export */ const format_toolbar_container = (FormatToolbarContainer); 58521 58522 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/use-undo-automatic-change.js 58523 /** 58524 * WordPress dependencies 58525 */ 58526 58527 58528 58529 58530 /** 58531 * Internal dependencies 58532 */ 58533 58534 function useUndoAutomaticChange() { 58535 const { 58536 didAutomaticChange, 58537 getSettings 58538 } = (0,external_wp_data_namespaceObject.useSelect)(store); 58539 return (0,external_wp_compose_namespaceObject.useRefEffect)(element => { 58540 function onKeyDown(event) { 58541 const { 58542 keyCode 58543 } = event; 58544 if (event.defaultPrevented) { 58545 return; 58546 } 58547 if (keyCode !== external_wp_keycodes_namespaceObject.DELETE && keyCode !== external_wp_keycodes_namespaceObject.BACKSPACE && keyCode !== external_wp_keycodes_namespaceObject.ESCAPE) { 58548 return; 58549 } 58550 const { 58551 __experimentalUndo 58552 } = getSettings(); 58553 if (!__experimentalUndo) { 58554 return; 58555 } 58556 if (!didAutomaticChange()) { 58557 return; 58558 } 58559 event.preventDefault(); 58560 __experimentalUndo(); 58561 } 58562 element.addEventListener('keydown', onKeyDown); 58563 return () => { 58564 element.removeEventListener('keydown', onKeyDown); 58565 }; 58566 }, []); 58567 } 58568 58569 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/use-mark-persistent.js 58570 /** 58571 * WordPress dependencies 58572 */ 58573 58574 58575 58576 /** 58577 * Internal dependencies 58578 */ 58579 58580 function useMarkPersistent({ 58581 html, 58582 value 58583 }) { 58584 const previousText = (0,external_wp_element_namespaceObject.useRef)(); 58585 const hasActiveFormats = !!value.activeFormats?.length; 58586 const { 58587 __unstableMarkLastChangeAsPersistent 58588 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 58589 58590 // Must be set synchronously to make sure it applies to the last change. 58591 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 58592 // Ignore mount. 58593 if (!previousText.current) { 58594 previousText.current = value.text; 58595 return; 58596 } 58597 58598 // Text input, so don't create an undo level for every character. 58599 // Create an undo level after 1 second of no input. 58600 if (previousText.current !== value.text) { 58601 const timeout = window.setTimeout(() => { 58602 __unstableMarkLastChangeAsPersistent(); 58603 }, 1000); 58604 previousText.current = value.text; 58605 return () => { 58606 window.clearTimeout(timeout); 58607 }; 58608 } 58609 __unstableMarkLastChangeAsPersistent(); 58610 }, [html, hasActiveFormats]); 58611 } 58612 58613 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/utils.js 58614 58615 /** 58616 * WordPress dependencies 58617 */ 58618 58619 58620 function addActiveFormats(value, activeFormats) { 58621 if (activeFormats?.length) { 58622 let index = value.formats.length; 58623 while (index--) { 58624 value.formats[index] = [...activeFormats, ...(value.formats[index] || [])]; 58625 } 58626 } 58627 } 58628 58629 /** 58630 * Get the multiline tag based on the multiline prop. 58631 * 58632 * @param {?(string|boolean)} multiline The multiline prop. 58633 * 58634 * @return {string | undefined} The multiline tag. 58635 */ 58636 function getMultilineTag(multiline) { 58637 if (multiline !== true && multiline !== 'p' && multiline !== 'li') { 58638 return; 58639 } 58640 return multiline === true ? 'p' : multiline; 58641 } 58642 function getAllowedFormats({ 58643 allowedFormats, 58644 disableFormats 58645 }) { 58646 if (disableFormats) { 58647 return getAllowedFormats.EMPTY_ARRAY; 58648 } 58649 return allowedFormats; 58650 } 58651 getAllowedFormats.EMPTY_ARRAY = []; 58652 58653 /** 58654 * Creates a link from pasted URL. 58655 * Creates a paragraph block containing a link to the URL, and calls `onReplace`. 58656 * 58657 * @param {string} url The URL that could not be embedded. 58658 * @param {Function} onReplace Function to call with the created fallback block. 58659 */ 58660 function createLinkInParagraph(url, onReplace) { 58661 const link = createElement("a", { 58662 href: url 58663 }, url); 58664 onReplace(createBlock('core/paragraph', { 58665 content: renderToString(link) 58666 })); 58667 } 58668 58669 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/split-value.js 58670 /** 58671 * WordPress dependencies 58672 */ 58673 58674 58675 /* 58676 * Signals to the RichText owner that the block can be replaced with two blocks 58677 * as a result of splitting the block by pressing enter, or with blocks as a 58678 * result of splitting the block by pasting block content in the instance. 58679 */ 58680 function splitValue({ 58681 value, 58682 pastedBlocks = [], 58683 onReplace, 58684 onSplit 58685 }) { 58686 if (!onReplace || !onSplit) { 58687 return; 58688 } 58689 58690 // Ensure the value has a selection. This might happen when trying to split 58691 // an empty value before there was a `selectionchange` event. 58692 const { 58693 start = 0, 58694 end = 0 58695 } = value; 58696 const valueWithEnsuredSelection = { 58697 ...value, 58698 start, 58699 end 58700 }; 58701 const blocks = []; 58702 const [before, after] = (0,external_wp_richText_namespaceObject.split)(valueWithEnsuredSelection); 58703 const hasPastedBlocks = pastedBlocks.length > 0; 58704 let lastPastedBlockIndex = -1; 58705 58706 // Consider the after value to be the original it is not empty and the 58707 // before value *is* empty. 58708 const isAfterOriginal = (0,external_wp_richText_namespaceObject.isEmpty)(before) && !(0,external_wp_richText_namespaceObject.isEmpty)(after); 58709 58710 // Create a block with the content before the caret if there's no pasted 58711 // blocks, or if there are pasted blocks and the value is not empty. We do 58712 // not want a leading empty block on paste, but we do if we split with e.g. 58713 // the enter key. 58714 if (!hasPastedBlocks || !(0,external_wp_richText_namespaceObject.isEmpty)(before)) { 58715 blocks.push(onSplit((0,external_wp_richText_namespaceObject.toHTMLString)({ 58716 value: before 58717 }), !isAfterOriginal)); 58718 lastPastedBlockIndex += 1; 58719 } 58720 if (hasPastedBlocks) { 58721 blocks.push(...pastedBlocks); 58722 lastPastedBlockIndex += pastedBlocks.length; 58723 } 58724 58725 // Create a block with the content after the caret if there's no pasted 58726 // blocks, or if there are pasted blocks and the value is not empty. We do 58727 // not want a trailing empty block on paste, but we do if we split with e.g. 58728 // the enter key. 58729 if (!hasPastedBlocks || !(0,external_wp_richText_namespaceObject.isEmpty)(after)) { 58730 blocks.push(onSplit((0,external_wp_richText_namespaceObject.toHTMLString)({ 58731 value: after 58732 }), isAfterOriginal)); 58733 } 58734 58735 // If there are pasted blocks, set the selection to the last one. Otherwise, 58736 // set the selection to the second block. 58737 const indexToSelect = hasPastedBlocks ? lastPastedBlockIndex : 1; 58738 58739 // If there are pasted blocks, move the caret to the end of the selected 58740 // block Otherwise, retain the default value. 58741 const initialPosition = hasPastedBlocks ? -1 : 0; 58742 onReplace(blocks, indexToSelect, initialPosition); 58743 } 58744 58745 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/use-paste-handler.js 58746 /** 58747 * WordPress dependencies 58748 */ 58749 58750 58751 58752 58753 58754 58755 /** 58756 * Internal dependencies 58757 */ 58758 58759 58760 58761 58762 /** @typedef {import('@wordpress/rich-text').RichTextValue} RichTextValue */ 58763 58764 function usePasteHandler(props) { 58765 const propsRef = (0,external_wp_element_namespaceObject.useRef)(props); 58766 propsRef.current = props; 58767 return (0,external_wp_compose_namespaceObject.useRefEffect)(element => { 58768 function _onPaste(event) { 58769 const { 58770 isSelected, 58771 disableFormats, 58772 onChange, 58773 value, 58774 formatTypes, 58775 tagName, 58776 onReplace, 58777 onSplit, 58778 __unstableEmbedURLOnPaste, 58779 pastePlainText 58780 } = propsRef.current; 58781 if (!isSelected) { 58782 return; 58783 } 58784 const { 58785 plainText, 58786 html, 58787 files 58788 } = getPasteEventData(event); 58789 event.preventDefault(); 58790 58791 // Allows us to ask for this information when we get a report. 58792 window.console.log('Received HTML:\n\n', html); 58793 window.console.log('Received plain text:\n\n', plainText); 58794 if (disableFormats) { 58795 onChange((0,external_wp_richText_namespaceObject.insert)(value, plainText)); 58796 return; 58797 } 58798 const isInternal = event.clipboardData.getData('rich-text') === 'true'; 58799 function pasteInline(content) { 58800 const transformed = formatTypes.reduce((accumulator, { 58801 __unstablePasteRule 58802 }) => { 58803 // Only allow one transform. 58804 if (__unstablePasteRule && accumulator === value) { 58805 accumulator = __unstablePasteRule(value, { 58806 html, 58807 plainText 58808 }); 58809 } 58810 return accumulator; 58811 }, value); 58812 if (transformed !== value) { 58813 onChange(transformed); 58814 } else { 58815 const valueToInsert = (0,external_wp_richText_namespaceObject.create)({ 58816 html: content 58817 }); 58818 addActiveFormats(valueToInsert, value.activeFormats); 58819 onChange((0,external_wp_richText_namespaceObject.insert)(value, valueToInsert)); 58820 } 58821 } 58822 58823 // If the data comes from a rich text instance, we can directly use it 58824 // without filtering the data. The filters are only meant for externally 58825 // pasted content and remove inline styles. 58826 if (isInternal) { 58827 pasteInline(html); 58828 return; 58829 } 58830 if (pastePlainText) { 58831 onChange((0,external_wp_richText_namespaceObject.insert)(value, (0,external_wp_richText_namespaceObject.create)({ 58832 text: plainText 58833 }))); 58834 return; 58835 } 58836 if (files?.length) { 58837 // Allows us to ask for this information when we get a report. 58838 // eslint-disable-next-line no-console 58839 window.console.log('Received items:\n\n', files); 58840 const fromTransforms = (0,external_wp_blocks_namespaceObject.getBlockTransforms)('from'); 58841 const blocks = files.reduce((accumulator, file) => { 58842 const transformation = (0,external_wp_blocks_namespaceObject.findTransform)(fromTransforms, transform => transform.type === 'files' && transform.isMatch([file])); 58843 if (transformation) { 58844 accumulator.push(transformation.transform([file])); 58845 } 58846 return accumulator; 58847 }, []).flat(); 58848 if (!blocks.length) { 58849 return; 58850 } 58851 if (onReplace && (0,external_wp_richText_namespaceObject.isEmpty)(value)) { 58852 onReplace(blocks); 58853 } else { 58854 splitValue({ 58855 value, 58856 pastedBlocks: blocks, 58857 onReplace, 58858 onSplit 58859 }); 58860 } 58861 return; 58862 } 58863 let mode = onReplace && onSplit ? 'AUTO' : 'INLINE'; 58864 const trimmedPlainText = plainText.trim(); 58865 if (__unstableEmbedURLOnPaste && (0,external_wp_richText_namespaceObject.isEmpty)(value) && (0,external_wp_url_namespaceObject.isURL)(trimmedPlainText) && 58866 // For the link pasting feature, allow only http(s) protocols. 58867 /^https?:/.test(trimmedPlainText)) { 58868 mode = 'BLOCKS'; 58869 } 58870 const content = (0,external_wp_blocks_namespaceObject.pasteHandler)({ 58871 HTML: html, 58872 plainText, 58873 mode, 58874 tagName 58875 }); 58876 if (typeof content === 'string') { 58877 pasteInline(content); 58878 } else if (content.length > 0) { 58879 if (onReplace && (0,external_wp_richText_namespaceObject.isEmpty)(value)) { 58880 onReplace(content, content.length - 1, -1); 58881 } else { 58882 splitValue({ 58883 value, 58884 pastedBlocks: content, 58885 onReplace, 58886 onSplit 58887 }); 58888 } 58889 } 58890 } 58891 element.addEventListener('paste', _onPaste); 58892 return () => { 58893 element.removeEventListener('paste', _onPaste); 58894 }; 58895 }, []); 58896 } 58897 58898 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/use-before-input-rules.js 58899 /** 58900 * WordPress dependencies 58901 */ 58902 58903 58904 58905 58906 58907 58908 /** 58909 * Internal dependencies 58910 */ 58911 58912 58913 /** 58914 * When typing over a selection, the selection will we wrapped by a matching 58915 * character pair. The second character is optional, it defaults to the first 58916 * character. 58917 * 58918 * @type {string[]} Array of character pairs. 58919 */ 58920 const wrapSelectionSettings = ['`', '"', "'", '“”', '‘’']; 58921 function useBeforeInputRules(props) { 58922 const { 58923 __unstableMarkLastChangeAsPersistent, 58924 __unstableMarkAutomaticChange 58925 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 58926 const propsRef = (0,external_wp_element_namespaceObject.useRef)(props); 58927 propsRef.current = props; 58928 return (0,external_wp_compose_namespaceObject.useRefEffect)(element => { 58929 function onInput(event) { 58930 const { 58931 inputType, 58932 data 58933 } = event; 58934 const { 58935 value, 58936 onChange 58937 } = propsRef.current; 58938 58939 // Only run the rules when inserting text. 58940 if (inputType !== 'insertText') { 58941 return; 58942 } 58943 if ((0,external_wp_richText_namespaceObject.isCollapsed)(value)) { 58944 return; 58945 } 58946 const pair = (0,external_wp_hooks_namespaceObject.applyFilters)('blockEditor.wrapSelectionSettings', wrapSelectionSettings).find(([startChar, endChar]) => startChar === data || endChar === data); 58947 if (!pair) { 58948 return; 58949 } 58950 const [startChar, endChar = startChar] = pair; 58951 const start = value.start; 58952 const end = value.end + startChar.length; 58953 let newValue = (0,external_wp_richText_namespaceObject.insert)(value, startChar, start, start); 58954 newValue = (0,external_wp_richText_namespaceObject.insert)(newValue, endChar, end, end); 58955 __unstableMarkLastChangeAsPersistent(); 58956 onChange(newValue); 58957 __unstableMarkAutomaticChange(); 58958 const init = {}; 58959 for (const key in event) { 58960 init[key] = event[key]; 58961 } 58962 init.data = endChar; 58963 const { 58964 ownerDocument 58965 } = element; 58966 const { 58967 defaultView 58968 } = ownerDocument; 58969 const newEvent = new defaultView.InputEvent('input', init); 58970 58971 // Dispatch an `input` event with the new data. This will trigger the 58972 // input rules. 58973 // Postpone the `input` to the next event loop tick so that the dispatch 58974 // doesn't happen synchronously in the middle of `beforeinput` dispatch. 58975 // This is closer to how native `input` event would be timed, and also 58976 // makes sure that the `input` event is dispatched only after the `onChange` 58977 // call few lines above has fully updated the data store state and rerendered 58978 // all affected components. 58979 window.queueMicrotask(() => { 58980 event.target.dispatchEvent(newEvent); 58981 }); 58982 event.preventDefault(); 58983 } 58984 element.addEventListener('beforeinput', onInput); 58985 return () => { 58986 element.removeEventListener('beforeinput', onInput); 58987 }; 58988 }, []); 58989 } 58990 58991 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/prevent-event-discovery.js 58992 /** 58993 * WordPress dependencies 58994 */ 58995 58996 function preventEventDiscovery(value) { 58997 const searchText = 'tales of gutenberg'; 58998 const addText = ' 🐡🐢🦀🐤🦋🐘🐧🐹🦁🦄🦍🐼🐿🎃🐴🐝🐆🦕🦔🌱🍇π🍌🐉💧🥨🌌🍂🍠🥦🥚🥝🎟🥥🥒🛵🥖🍒🍯🎾🎲🐺🐚🐮⌛️'; 58999 const { 59000 start, 59001 text 59002 } = value; 59003 if (start < searchText.length) { 59004 return value; 59005 } 59006 const charactersBefore = text.slice(start - searchText.length, start); 59007 if (charactersBefore.toLowerCase() !== searchText) { 59008 return value; 59009 } 59010 return (0,external_wp_richText_namespaceObject.insert)(value, addText); 59011 } 59012 59013 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/use-input-rules.js 59014 /** 59015 * WordPress dependencies 59016 */ 59017 59018 59019 59020 59021 59022 59023 /** 59024 * Internal dependencies 59025 */ 59026 59027 59028 59029 function findSelection(blocks) { 59030 let i = blocks.length; 59031 while (i--) { 59032 const attributeKey = retrieveSelectedAttribute(blocks[i].attributes); 59033 if (attributeKey) { 59034 blocks[i].attributes[attributeKey] = blocks[i].attributes[attributeKey] 59035 // To do: refactor this to use rich text's selection instead, so 59036 // we no longer have to use on this hack inserting a special 59037 // character. 59038 .toString().replace(START_OF_SELECTED_AREA, ''); 59039 return [blocks[i].clientId, attributeKey, 0, 0]; 59040 } 59041 const nestedSelection = findSelection(blocks[i].innerBlocks); 59042 if (nestedSelection) { 59043 return nestedSelection; 59044 } 59045 } 59046 return []; 59047 } 59048 function useInputRules(props) { 59049 const { 59050 __unstableMarkLastChangeAsPersistent, 59051 __unstableMarkAutomaticChange 59052 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 59053 const propsRef = (0,external_wp_element_namespaceObject.useRef)(props); 59054 propsRef.current = props; 59055 return (0,external_wp_compose_namespaceObject.useRefEffect)(element => { 59056 function inputRule() { 59057 const { 59058 getValue, 59059 onReplace, 59060 selectionChange 59061 } = propsRef.current; 59062 if (!onReplace) { 59063 return; 59064 } 59065 59066 // We must use getValue() here because value may be update 59067 // asynchronously. 59068 const value = getValue(); 59069 const { 59070 start, 59071 text 59072 } = value; 59073 const characterBefore = text.slice(start - 1, start); 59074 59075 // The character right before the caret must be a plain space. 59076 if (characterBefore !== ' ') { 59077 return; 59078 } 59079 const trimmedTextBefore = text.slice(0, start).trim(); 59080 const prefixTransforms = (0,external_wp_blocks_namespaceObject.getBlockTransforms)('from').filter(({ 59081 type 59082 }) => type === 'prefix'); 59083 const transformation = (0,external_wp_blocks_namespaceObject.findTransform)(prefixTransforms, ({ 59084 prefix 59085 }) => { 59086 return trimmedTextBefore === prefix; 59087 }); 59088 if (!transformation) { 59089 return; 59090 } 59091 const content = (0,external_wp_richText_namespaceObject.toHTMLString)({ 59092 value: (0,external_wp_richText_namespaceObject.insert)(value, START_OF_SELECTED_AREA, 0, start) 59093 }); 59094 const block = transformation.transform(content); 59095 selectionChange(...findSelection([block])); 59096 onReplace([block]); 59097 __unstableMarkAutomaticChange(); 59098 return true; 59099 } 59100 function onInput(event) { 59101 const { 59102 inputType, 59103 type 59104 } = event; 59105 const { 59106 getValue, 59107 onChange, 59108 __unstableAllowPrefixTransformations, 59109 formatTypes 59110 } = propsRef.current; 59111 59112 // Only run input rules when inserting text. 59113 if (inputType !== 'insertText' && type !== 'compositionend') { 59114 return; 59115 } 59116 if (__unstableAllowPrefixTransformations && inputRule()) { 59117 return; 59118 } 59119 const value = getValue(); 59120 const transformed = formatTypes.reduce((accumlator, { 59121 __unstableInputRule 59122 }) => { 59123 if (__unstableInputRule) { 59124 accumlator = __unstableInputRule(accumlator); 59125 } 59126 return accumlator; 59127 }, preventEventDiscovery(value)); 59128 if (transformed !== value) { 59129 __unstableMarkLastChangeAsPersistent(); 59130 onChange({ 59131 ...transformed, 59132 activeFormats: value.activeFormats 59133 }); 59134 __unstableMarkAutomaticChange(); 59135 } 59136 } 59137 element.addEventListener('input', onInput); 59138 element.addEventListener('compositionend', onInput); 59139 return () => { 59140 element.removeEventListener('input', onInput); 59141 element.removeEventListener('compositionend', onInput); 59142 }; 59143 }, []); 59144 } 59145 59146 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/use-delete.js 59147 /** 59148 * WordPress dependencies 59149 */ 59150 59151 59152 59153 59154 function useDelete(props) { 59155 const propsRef = (0,external_wp_element_namespaceObject.useRef)(props); 59156 propsRef.current = props; 59157 return (0,external_wp_compose_namespaceObject.useRefEffect)(element => { 59158 function onKeyDown(event) { 59159 const { 59160 keyCode 59161 } = event; 59162 if (event.defaultPrevented) { 59163 return; 59164 } 59165 const { 59166 value, 59167 onMerge, 59168 onRemove 59169 } = propsRef.current; 59170 if (keyCode === external_wp_keycodes_namespaceObject.DELETE || keyCode === external_wp_keycodes_namespaceObject.BACKSPACE) { 59171 const { 59172 start, 59173 end, 59174 text 59175 } = value; 59176 const isReverse = keyCode === external_wp_keycodes_namespaceObject.BACKSPACE; 59177 const hasActiveFormats = value.activeFormats && !!value.activeFormats.length; 59178 59179 // Only process delete if the key press occurs at an uncollapsed edge. 59180 if (!(0,external_wp_richText_namespaceObject.isCollapsed)(value) || hasActiveFormats || isReverse && start !== 0 || !isReverse && end !== text.length) { 59181 return; 59182 } 59183 if (onMerge) { 59184 onMerge(!isReverse); 59185 } 59186 59187 // Only handle remove on Backspace. This serves dual-purpose of being 59188 // an intentional user interaction distinguishing between Backspace and 59189 // Delete to remove the empty field, but also to avoid merge & remove 59190 // causing destruction of two fields (merge, then removed merged). 59191 else if (onRemove && (0,external_wp_richText_namespaceObject.isEmpty)(value) && isReverse) { 59192 onRemove(!isReverse); 59193 } 59194 event.preventDefault(); 59195 } 59196 } 59197 element.addEventListener('keydown', onKeyDown); 59198 return () => { 59199 element.removeEventListener('keydown', onKeyDown); 59200 }; 59201 }, []); 59202 } 59203 59204 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/use-enter.js 59205 /** 59206 * WordPress dependencies 59207 */ 59208 59209 59210 59211 59212 59213 59214 59215 /** 59216 * Internal dependencies 59217 */ 59218 59219 59220 function useEnter(props) { 59221 const registry = (0,external_wp_data_namespaceObject.useRegistry)(); 59222 const { 59223 __unstableMarkAutomaticChange 59224 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 59225 const propsRef = (0,external_wp_element_namespaceObject.useRef)(props); 59226 propsRef.current = props; 59227 return (0,external_wp_compose_namespaceObject.useRefEffect)(element => { 59228 function onKeyDown(event) { 59229 if (event.target.contentEditable !== 'true') { 59230 return; 59231 } 59232 if (event.defaultPrevented) { 59233 return; 59234 } 59235 if (event.keyCode !== external_wp_keycodes_namespaceObject.ENTER) { 59236 return; 59237 } 59238 const { 59239 removeEditorOnlyFormats, 59240 value, 59241 onReplace, 59242 onSplit, 59243 onChange, 59244 disableLineBreaks, 59245 onSplitAtEnd, 59246 onSplitAtDoubleLineEnd 59247 } = propsRef.current; 59248 event.preventDefault(); 59249 const _value = { 59250 ...value 59251 }; 59252 _value.formats = removeEditorOnlyFormats(value); 59253 const canSplit = onReplace && onSplit; 59254 if (onReplace) { 59255 const transforms = (0,external_wp_blocks_namespaceObject.getBlockTransforms)('from').filter(({ 59256 type 59257 }) => type === 'enter'); 59258 const transformation = (0,external_wp_blocks_namespaceObject.findTransform)(transforms, item => { 59259 return item.regExp.test(_value.text); 59260 }); 59261 if (transformation) { 59262 onReplace([transformation.transform({ 59263 content: _value.text 59264 })]); 59265 __unstableMarkAutomaticChange(); 59266 return; 59267 } 59268 } 59269 const { 59270 text, 59271 start, 59272 end 59273 } = _value; 59274 if (event.shiftKey) { 59275 if (!disableLineBreaks) { 59276 onChange((0,external_wp_richText_namespaceObject.insert)(_value, '\n')); 59277 } 59278 } else if (canSplit) { 59279 splitValue({ 59280 value: _value, 59281 onReplace, 59282 onSplit 59283 }); 59284 } else if (onSplitAtEnd && start === end && end === text.length) { 59285 onSplitAtEnd(); 59286 } else if ( 59287 // For some blocks it's desirable to split at the end of the 59288 // block when there are two line breaks at the end of the 59289 // block, so triple Enter exits the block. 59290 onSplitAtDoubleLineEnd && start === end && end === text.length && text.slice(-2) === '\n\n') { 59291 registry.batch(() => { 59292 _value.start = _value.end - 2; 59293 onChange((0,external_wp_richText_namespaceObject.remove)(_value)); 59294 onSplitAtDoubleLineEnd(); 59295 }); 59296 } else if (!disableLineBreaks) { 59297 onChange((0,external_wp_richText_namespaceObject.insert)(_value, '\n')); 59298 } 59299 } 59300 element.addEventListener('keydown', onKeyDown); 59301 return () => { 59302 element.removeEventListener('keydown', onKeyDown); 59303 }; 59304 }, []); 59305 } 59306 59307 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/use-format-types.js 59308 /** 59309 * WordPress dependencies 59310 */ 59311 59312 59313 59314 function formatTypesSelector(select) { 59315 return select(external_wp_richText_namespaceObject.store).getFormatTypes(); 59316 } 59317 59318 /** 59319 * Set of all interactive content tags. 59320 * 59321 * @see https://html.spec.whatwg.org/multipage/dom.html#interactive-content 59322 */ 59323 const interactiveContentTags = new Set(['a', 'audio', 'button', 'details', 'embed', 'iframe', 'input', 'label', 'select', 'textarea', 'video']); 59324 function prefixSelectKeys(selected, prefix) { 59325 if (typeof selected !== 'object') return { 59326 [prefix]: selected 59327 }; 59328 return Object.fromEntries(Object.entries(selected).map(([key, value]) => [`$prefix}.$key}`, value])); 59329 } 59330 function getPrefixedSelectKeys(selected, prefix) { 59331 if (selected[prefix]) return selected[prefix]; 59332 return Object.keys(selected).filter(key => key.startsWith(prefix + '.')).reduce((accumulator, key) => { 59333 accumulator[key.slice(prefix.length + 1)] = selected[key]; 59334 return accumulator; 59335 }, {}); 59336 } 59337 59338 /** 59339 * This hook provides RichText with the `formatTypes` and its derived props from 59340 * experimental format type settings. 59341 * 59342 * @param {Object} $0 Options 59343 * @param {string} $0.clientId Block client ID. 59344 * @param {string} $0.identifier Block attribute. 59345 * @param {boolean} $0.withoutInteractiveFormatting Whether to clean the interactive formattings or not. 59346 * @param {Array} $0.allowedFormats Allowed formats 59347 */ 59348 function useFormatTypes({ 59349 clientId, 59350 identifier, 59351 withoutInteractiveFormatting, 59352 allowedFormats 59353 }) { 59354 const allFormatTypes = (0,external_wp_data_namespaceObject.useSelect)(formatTypesSelector, []); 59355 const formatTypes = (0,external_wp_element_namespaceObject.useMemo)(() => { 59356 return allFormatTypes.filter(({ 59357 name, 59358 interactive, 59359 tagName 59360 }) => { 59361 if (allowedFormats && !allowedFormats.includes(name)) { 59362 return false; 59363 } 59364 if (withoutInteractiveFormatting && (interactive || interactiveContentTags.has(tagName))) { 59365 return false; 59366 } 59367 return true; 59368 }); 59369 }, [allFormatTypes, allowedFormats, withoutInteractiveFormatting]); 59370 const keyedSelected = (0,external_wp_data_namespaceObject.useSelect)(select => formatTypes.reduce((accumulator, type) => { 59371 if (!type.__experimentalGetPropsForEditableTreePreparation) { 59372 return accumulator; 59373 } 59374 return { 59375 ...accumulator, 59376 ...prefixSelectKeys(type.__experimentalGetPropsForEditableTreePreparation(select, { 59377 richTextIdentifier: identifier, 59378 blockClientId: clientId 59379 }), type.name) 59380 }; 59381 }, {}), [formatTypes, clientId, identifier]); 59382 const dispatch = (0,external_wp_data_namespaceObject.useDispatch)(); 59383 const prepareHandlers = []; 59384 const valueHandlers = []; 59385 const changeHandlers = []; 59386 const dependencies = []; 59387 for (const key in keyedSelected) { 59388 dependencies.push(keyedSelected[key]); 59389 } 59390 formatTypes.forEach(type => { 59391 if (type.__experimentalCreatePrepareEditableTree) { 59392 const handler = type.__experimentalCreatePrepareEditableTree(getPrefixedSelectKeys(keyedSelected, type.name), { 59393 richTextIdentifier: identifier, 59394 blockClientId: clientId 59395 }); 59396 if (type.__experimentalCreateOnChangeEditableValue) { 59397 valueHandlers.push(handler); 59398 } else { 59399 prepareHandlers.push(handler); 59400 } 59401 } 59402 if (type.__experimentalCreateOnChangeEditableValue) { 59403 let dispatchers = {}; 59404 if (type.__experimentalGetPropsForEditableTreeChangeHandler) { 59405 dispatchers = type.__experimentalGetPropsForEditableTreeChangeHandler(dispatch, { 59406 richTextIdentifier: identifier, 59407 blockClientId: clientId 59408 }); 59409 } 59410 const selected = getPrefixedSelectKeys(keyedSelected, type.name); 59411 changeHandlers.push(type.__experimentalCreateOnChangeEditableValue({ 59412 ...(typeof selected === 'object' ? selected : {}), 59413 ...dispatchers 59414 }, { 59415 richTextIdentifier: identifier, 59416 blockClientId: clientId 59417 })); 59418 } 59419 }); 59420 return { 59421 formatTypes, 59422 prepareHandlers, 59423 valueHandlers, 59424 changeHandlers, 59425 dependencies 59426 }; 59427 } 59428 59429 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/use-remove-browser-shortcuts.js 59430 /** 59431 * WordPress dependencies 59432 */ 59433 59434 59435 59436 /** 59437 * Hook to prevent default behaviors for key combinations otherwise handled 59438 * internally by RichText. 59439 * 59440 * @return {import('react').RefObject} The component to be rendered. 59441 */ 59442 function useRemoveBrowserShortcuts() { 59443 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 59444 function onKeydown(event) { 59445 if (external_wp_keycodes_namespaceObject.isKeyboardEvent.primary(event, 'z') || external_wp_keycodes_namespaceObject.isKeyboardEvent.primary(event, 'y') || external_wp_keycodes_namespaceObject.isKeyboardEvent.primaryShift(event, 'z')) { 59446 event.preventDefault(); 59447 } 59448 } 59449 node.addEventListener('keydown', onKeydown); 59450 return () => { 59451 node.removeEventListener('keydown', onKeydown); 59452 }; 59453 }, []); 59454 } 59455 59456 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/use-shortcuts.js 59457 /** 59458 * WordPress dependencies 59459 */ 59460 59461 function useShortcuts(keyboardShortcuts) { 59462 return (0,external_wp_compose_namespaceObject.useRefEffect)(element => { 59463 function onKeyDown(event) { 59464 for (const keyboardShortcut of keyboardShortcuts.current) { 59465 keyboardShortcut(event); 59466 } 59467 } 59468 element.addEventListener('keydown', onKeyDown); 59469 return () => { 59470 element.removeEventListener('keydown', onKeyDown); 59471 }; 59472 }, []); 59473 } 59474 59475 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/use-input-events.js 59476 /** 59477 * WordPress dependencies 59478 */ 59479 59480 function useInputEvents(inputEvents) { 59481 return (0,external_wp_compose_namespaceObject.useRefEffect)(element => { 59482 function onInput(event) { 59483 for (const keyboardShortcut of inputEvents.current) { 59484 keyboardShortcut(event); 59485 } 59486 } 59487 element.addEventListener('input', onInput); 59488 return () => { 59489 element.removeEventListener('input', onInput); 59490 }; 59491 }, []); 59492 } 59493 59494 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/use-insert-replacement-text.js 59495 /** 59496 * WordPress dependencies 59497 */ 59498 59499 59500 59501 /** 59502 * Internal dependencies 59503 */ 59504 59505 59506 /** 59507 * When the browser is about to auto correct, add an undo level so the user can 59508 * revert the change. 59509 */ 59510 function useInsertReplacementText() { 59511 const { 59512 __unstableMarkLastChangeAsPersistent 59513 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 59514 return (0,external_wp_compose_namespaceObject.useRefEffect)(element => { 59515 function onInput(event) { 59516 if (event.inputType === 'insertReplacementText') { 59517 __unstableMarkLastChangeAsPersistent(); 59518 } 59519 } 59520 element.addEventListener('beforeinput', onInput); 59521 return () => { 59522 element.removeEventListener('beforeinput', onInput); 59523 }; 59524 }, []); 59525 } 59526 59527 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/use-firefox-compat.js 59528 /** 59529 * WordPress dependencies 59530 */ 59531 59532 59533 59534 /** 59535 * Internal dependencies 59536 */ 59537 59538 function useFirefoxCompat() { 59539 const { 59540 isMultiSelecting 59541 } = (0,external_wp_data_namespaceObject.useSelect)(store); 59542 return (0,external_wp_compose_namespaceObject.useRefEffect)(element => { 59543 function onFocus() { 59544 if (!isMultiSelecting()) { 59545 return; 59546 } 59547 59548 // This is a little hack to work around focus issues with nested 59549 // editable elements in Firefox. For some reason the editable child 59550 // element sometimes regains focus, while it should not be focusable 59551 // and focus should remain on the editable parent element. 59552 // To do: try to find the cause of the shifting focus. 59553 const parentEditable = element.parentElement.closest('[contenteditable="true"]'); 59554 if (parentEditable) { 59555 parentEditable.focus(); 59556 } 59557 } 59558 element.addEventListener('focus', onFocus); 59559 return () => { 59560 element.removeEventListener('focus', onFocus); 59561 }; 59562 }, []); 59563 } 59564 59565 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/format-edit.js 59566 59567 /** 59568 * WordPress dependencies 59569 */ 59570 59571 59572 59573 /** 59574 * Internal dependencies 59575 */ 59576 59577 const format_edit_DEFAULT_BLOCK_CONTEXT = {}; 59578 const usesContextKey = Symbol('usesContext'); 59579 function format_edit_Edit({ 59580 onChange, 59581 onFocus, 59582 value, 59583 forwardedRef, 59584 settings 59585 }) { 59586 const { 59587 name, 59588 edit: EditFunction, 59589 [usesContextKey]: usesContext 59590 } = settings; 59591 const blockContext = (0,external_wp_element_namespaceObject.useContext)(block_context); 59592 59593 // Assign context values using the block type's declared context needs. 59594 const context = (0,external_wp_element_namespaceObject.useMemo)(() => { 59595 return usesContext ? Object.fromEntries(Object.entries(blockContext).filter(([key]) => usesContext.includes(key))) : format_edit_DEFAULT_BLOCK_CONTEXT; 59596 }, [usesContext, blockContext]); 59597 if (!EditFunction) { 59598 return null; 59599 } 59600 const activeFormat = (0,external_wp_richText_namespaceObject.getActiveFormat)(value, name); 59601 const isActive = activeFormat !== undefined; 59602 const activeObject = (0,external_wp_richText_namespaceObject.getActiveObject)(value); 59603 const isObjectActive = activeObject !== undefined && activeObject.type === name; 59604 return (0,external_React_.createElement)(EditFunction, { 59605 key: name, 59606 isActive: isActive, 59607 activeAttributes: isActive ? activeFormat.attributes || {} : {}, 59608 isObjectActive: isObjectActive, 59609 activeObjectAttributes: isObjectActive ? activeObject.attributes || {} : {}, 59610 value: value, 59611 onChange: onChange, 59612 onFocus: onFocus, 59613 contentRef: forwardedRef, 59614 context: context 59615 }); 59616 } 59617 function FormatEdit({ 59618 formatTypes, 59619 ...props 59620 }) { 59621 return formatTypes.map(settings => (0,external_React_.createElement)(format_edit_Edit, { 59622 settings: settings, 59623 ...props, 59624 key: settings.name 59625 })); 59626 } 59627 59628 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/content.js 59629 59630 /** 59631 * WordPress dependencies 59632 */ 59633 59634 59635 59636 59637 /** 59638 * Internal dependencies 59639 */ 59640 59641 59642 /** 59643 * Internal dependencies 59644 */ 59645 59646 function Content({ 59647 value, 59648 tagName: Tag, 59649 multiline, 59650 format, 59651 ...props 59652 }) { 59653 if (rich_text.isEmpty(value)) { 59654 const MultilineTag = getMultilineTag(multiline); 59655 value = MultilineTag ? (0,external_React_.createElement)(MultilineTag, null) : null; 59656 } else if (Array.isArray(value)) { 59657 external_wp_deprecated_default()('wp.blockEditor.RichText value prop as children type', { 59658 since: '6.1', 59659 version: '6.3', 59660 alternative: 'value prop as string', 59661 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 59662 }); 59663 value = (0,external_React_.createElement)(external_wp_element_namespaceObject.RawHTML, null, external_wp_blocks_namespaceObject.children.toHTML(value)); 59664 } else if (typeof value === 'string') { 59665 // To do: deprecate. 59666 value = (0,external_React_.createElement)(external_wp_element_namespaceObject.RawHTML, null, value); 59667 } else { 59668 // To do: create a toReactComponent method on RichTextData, which we 59669 // might in the future also use for the editable tree. See 59670 // https://github.com/WordPress/gutenberg/pull/41655. 59671 value = (0,external_React_.createElement)(external_wp_element_namespaceObject.RawHTML, null, value.toHTMLString()); 59672 } 59673 return Tag ? (0,external_React_.createElement)(Tag, { 59674 ...props 59675 }, value) : value; 59676 } 59677 59678 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/multiline.js 59679 59680 /** 59681 * WordPress dependencies 59682 */ 59683 59684 59685 59686 59687 /** 59688 * Internal dependencies 59689 */ 59690 59691 59692 59693 59694 function RichTextMultiline({ 59695 children, 59696 identifier, 59697 tagName: TagName = 'div', 59698 value = '', 59699 onChange, 59700 multiline, 59701 ...props 59702 }, forwardedRef) { 59703 external_wp_deprecated_default()('wp.blockEditor.RichText multiline prop', { 59704 since: '6.1', 59705 version: '6.3', 59706 alternative: 'nested blocks (InnerBlocks)', 59707 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/nested-blocks-inner-blocks/' 59708 }); 59709 const { 59710 clientId 59711 } = useBlockEditContext(); 59712 const { 59713 selectionChange 59714 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 59715 const multilineTagName = getMultilineTag(multiline); 59716 value = value || `<$multilineTagName}></$multilineTagName}>`; 59717 const padded = `</$multilineTagName}>$value}<$multilineTagName}>`; 59718 const values = padded.split(`</$multilineTagName}><$multilineTagName}>`); 59719 values.shift(); 59720 values.pop(); 59721 function _onChange(newValues) { 59722 onChange(`<$multilineTagName}>$newValues.join(`</$multilineTagName}><$multilineTagName}>`)}</$multilineTagName}>`); 59723 } 59724 return (0,external_React_.createElement)(TagName, { 59725 ref: forwardedRef 59726 }, values.map((_value, index) => { 59727 return (0,external_React_.createElement)(RichTextWrapper, { 59728 key: index, 59729 identifier: `$identifier}-$index}`, 59730 tagName: multilineTagName, 59731 value: _value, 59732 onChange: newValue => { 59733 const newValues = values.slice(); 59734 newValues[index] = newValue; 59735 _onChange(newValues); 59736 }, 59737 isSelected: undefined, 59738 onSplit: v => v, 59739 onReplace: array => { 59740 const newValues = values.slice(); 59741 newValues.splice(index, 1, ...array); 59742 _onChange(newValues); 59743 selectionChange(clientId, `$identifier}-$index + 1}`, 0, 0); 59744 }, 59745 onMerge: forward => { 59746 const newValues = values.slice(); 59747 let offset = 0; 59748 if (forward) { 59749 if (!newValues[index + 1]) return; 59750 newValues.splice(index, 2, newValues[index] + newValues[index + 1]); 59751 offset = newValues[index].length - 1; 59752 } else { 59753 if (!newValues[index - 1]) return; 59754 newValues.splice(index - 1, 2, newValues[index - 1] + newValues[index]); 59755 offset = newValues[index - 1].length - 1; 59756 } 59757 _onChange(newValues); 59758 selectionChange(clientId, `$identifier}-$index - (forward ? 0 : 1)}`, offset, offset); 59759 }, 59760 ...props 59761 }); 59762 })); 59763 } 59764 /* harmony default export */ const multiline = ((0,external_wp_element_namespaceObject.forwardRef)(RichTextMultiline)); 59765 59766 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/with-deprecations.js 59767 59768 /** 59769 * WordPress dependencies 59770 */ 59771 59772 59773 59774 59775 59776 59777 /** 59778 * Internal dependencies 59779 */ 59780 59781 function withDeprecations(Component) { 59782 return (0,external_wp_element_namespaceObject.forwardRef)((props, ref) => { 59783 let value = props.value; 59784 let onChange = props.onChange; 59785 59786 // Handle deprecated format. 59787 if (Array.isArray(value)) { 59788 external_wp_deprecated_default()('wp.blockEditor.RichText value prop as children type', { 59789 since: '6.1', 59790 version: '6.3', 59791 alternative: 'value prop as string', 59792 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 59793 }); 59794 value = external_wp_blocks_namespaceObject.children.toHTML(props.value); 59795 onChange = newValue => props.onChange(external_wp_blocks_namespaceObject.children.fromDOM((0,external_wp_richText_namespaceObject.__unstableCreateElement)(document, newValue).childNodes)); 59796 } 59797 const NewComponent = props.multiline ? multiline : Component; 59798 const instanceId = (0,external_wp_compose_namespaceObject.useInstanceId)(NewComponent); 59799 return (0,external_React_.createElement)(NewComponent, { 59800 ...props, 59801 identifier: props.identifier || instanceId, 59802 value: value, 59803 onChange: onChange, 59804 ref: ref 59805 }); 59806 }); 59807 } 59808 59809 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/index.js 59810 59811 /** 59812 * External dependencies 59813 */ 59814 59815 59816 /** 59817 * WordPress dependencies 59818 */ 59819 59820 59821 59822 59823 59824 59825 59826 /** 59827 * Internal dependencies 59828 */ 59829 59830 59831 59832 59833 59834 59835 59836 59837 59838 59839 59840 59841 59842 59843 59844 59845 59846 59847 59848 59849 59850 59851 59852 59853 const keyboardShortcutContext = (0,external_wp_element_namespaceObject.createContext)(); 59854 const inputEventContext = (0,external_wp_element_namespaceObject.createContext)(); 59855 59856 /** 59857 * Removes props used for the native version of RichText so that they are not 59858 * passed to the DOM element and log warnings. 59859 * 59860 * @param {Object} props Props to filter. 59861 * 59862 * @return {Object} Filtered props. 59863 */ 59864 function removeNativeProps(props) { 59865 const { 59866 __unstableMobileNoFocusOnMount, 59867 deleteEnter, 59868 placeholderTextColor, 59869 textAlign, 59870 selectionColor, 59871 tagsToEliminate, 59872 disableEditingMenu, 59873 fontSize, 59874 fontFamily, 59875 fontWeight, 59876 fontStyle, 59877 minWidth, 59878 maxWidth, 59879 setRef, 59880 disableSuggestions, 59881 disableAutocorrection, 59882 ...restProps 59883 } = props; 59884 return restProps; 59885 } 59886 function RichTextWrapper({ 59887 children, 59888 tagName = 'div', 59889 value: adjustedValue = '', 59890 onChange: adjustedOnChange, 59891 isSelected: originalIsSelected, 59892 multiline, 59893 inlineToolbar, 59894 wrapperClassName, 59895 autocompleters, 59896 onReplace, 59897 placeholder, 59898 allowedFormats, 59899 withoutInteractiveFormatting, 59900 onRemove, 59901 onMerge, 59902 onSplit, 59903 __unstableOnSplitAtEnd: onSplitAtEnd, 59904 __unstableOnSplitAtDoubleLineEnd: onSplitAtDoubleLineEnd, 59905 identifier, 59906 preserveWhiteSpace, 59907 __unstablePastePlainText: pastePlainText, 59908 __unstableEmbedURLOnPaste, 59909 __unstableDisableFormats: disableFormats, 59910 disableLineBreaks, 59911 __unstableAllowPrefixTransformations, 59912 disableEditing, 59913 ...props 59914 }, forwardedRef) { 59915 props = removeNativeProps(props); 59916 const anchorRef = (0,external_wp_element_namespaceObject.useRef)(); 59917 const context = useBlockEditContext(); 59918 const { 59919 clientId, 59920 isSelected: isBlockSelected, 59921 name: blockName 59922 } = context; 59923 const blockBindings = context[blockBindingsKey]; 59924 const selector = select => { 59925 // Avoid subscribing to the block editor store if the block is not 59926 // selected. 59927 if (!isBlockSelected) { 59928 return { 59929 isSelected: false 59930 }; 59931 } 59932 const { 59933 getSelectionStart, 59934 getSelectionEnd 59935 } = select(store); 59936 const selectionStart = getSelectionStart(); 59937 const selectionEnd = getSelectionEnd(); 59938 let isSelected; 59939 if (originalIsSelected === undefined) { 59940 isSelected = selectionStart.clientId === clientId && selectionEnd.clientId === clientId && selectionStart.attributeKey === identifier; 59941 } else if (originalIsSelected) { 59942 isSelected = selectionStart.clientId === clientId; 59943 } 59944 return { 59945 selectionStart: isSelected ? selectionStart.offset : undefined, 59946 selectionEnd: isSelected ? selectionEnd.offset : undefined, 59947 isSelected 59948 }; 59949 }; 59950 const { 59951 selectionStart, 59952 selectionEnd, 59953 isSelected 59954 } = (0,external_wp_data_namespaceObject.useSelect)(selector, [clientId, identifier, originalIsSelected, isBlockSelected]); 59955 const disableBoundBlocks = (0,external_wp_data_namespaceObject.useSelect)(select => { 59956 // Disable Rich Text editing if block bindings specify that. 59957 let _disableBoundBlocks = false; 59958 if (blockBindings && canBindBlock(blockName)) { 59959 const blockTypeAttributes = (0,external_wp_blocks_namespaceObject.getBlockType)(blockName).attributes; 59960 const { 59961 getBlockBindingsSource 59962 } = unlock(select(external_wp_blocks_namespaceObject.store)); 59963 for (const [attribute, args] of Object.entries(blockBindings)) { 59964 if (blockTypeAttributes?.[attribute]?.source !== 'rich-text') { 59965 break; 59966 } 59967 59968 // If the source is not defined, or if its value of `lockAttributesEditing` is `true`, disable it. 59969 const blockBindingsSource = getBlockBindingsSource(args.source); 59970 if (!blockBindingsSource || blockBindingsSource.lockAttributesEditing) { 59971 _disableBoundBlocks = true; 59972 break; 59973 } 59974 } 59975 } 59976 return _disableBoundBlocks; 59977 }, [blockBindings, blockName]); 59978 const shouldDisableEditing = disableEditing || disableBoundBlocks; 59979 const { 59980 getSelectionStart, 59981 getSelectionEnd, 59982 getBlockRootClientId 59983 } = (0,external_wp_data_namespaceObject.useSelect)(store); 59984 const { 59985 selectionChange 59986 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 59987 const adjustedAllowedFormats = getAllowedFormats({ 59988 allowedFormats, 59989 disableFormats 59990 }); 59991 const hasFormats = !adjustedAllowedFormats || adjustedAllowedFormats.length > 0; 59992 const onSelectionChange = (0,external_wp_element_namespaceObject.useCallback)((start, end) => { 59993 const selection = {}; 59994 const unset = start === undefined && end === undefined; 59995 if (typeof start === 'number' || unset) { 59996 // If we are only setting the start (or the end below), which 59997 // means a partial selection, and we're not updating a selection 59998 // with the same client ID, abort. This means the selected block 59999 // is a parent block. 60000 if (end === undefined && getBlockRootClientId(clientId) !== getBlockRootClientId(getSelectionEnd().clientId)) { 60001 return; 60002 } 60003 selection.start = { 60004 clientId, 60005 attributeKey: identifier, 60006 offset: start 60007 }; 60008 } 60009 if (typeof end === 'number' || unset) { 60010 if (start === undefined && getBlockRootClientId(clientId) !== getBlockRootClientId(getSelectionStart().clientId)) { 60011 return; 60012 } 60013 selection.end = { 60014 clientId, 60015 attributeKey: identifier, 60016 offset: end 60017 }; 60018 } 60019 selectionChange(selection); 60020 }, [clientId, identifier]); 60021 const { 60022 formatTypes, 60023 prepareHandlers, 60024 valueHandlers, 60025 changeHandlers, 60026 dependencies 60027 } = useFormatTypes({ 60028 clientId, 60029 identifier, 60030 withoutInteractiveFormatting, 60031 allowedFormats: adjustedAllowedFormats 60032 }); 60033 function addEditorOnlyFormats(value) { 60034 return valueHandlers.reduce((accumulator, fn) => fn(accumulator, value.text), value.formats); 60035 } 60036 function removeEditorOnlyFormats(value) { 60037 formatTypes.forEach(formatType => { 60038 // Remove formats created by prepareEditableTree, because they are editor only. 60039 if (formatType.__experimentalCreatePrepareEditableTree) { 60040 value = (0,external_wp_richText_namespaceObject.removeFormat)(value, formatType.name, 0, value.text.length); 60041 } 60042 }); 60043 return value.formats; 60044 } 60045 function addInvisibleFormats(value) { 60046 return prepareHandlers.reduce((accumulator, fn) => fn(accumulator, value.text), value.formats); 60047 } 60048 const { 60049 value, 60050 getValue, 60051 onChange, 60052 ref: richTextRef 60053 } = (0,external_wp_richText_namespaceObject.__unstableUseRichText)({ 60054 value: adjustedValue, 60055 onChange(html, { 60056 __unstableFormats, 60057 __unstableText 60058 }) { 60059 adjustedOnChange(html); 60060 Object.values(changeHandlers).forEach(changeHandler => { 60061 changeHandler(__unstableFormats, __unstableText); 60062 }); 60063 }, 60064 selectionStart, 60065 selectionEnd, 60066 onSelectionChange, 60067 placeholder, 60068 __unstableIsSelected: isSelected, 60069 __unstableDisableFormats: disableFormats, 60070 preserveWhiteSpace, 60071 __unstableDependencies: [...dependencies, tagName], 60072 __unstableAfterParse: addEditorOnlyFormats, 60073 __unstableBeforeSerialize: removeEditorOnlyFormats, 60074 __unstableAddInvisibleFormats: addInvisibleFormats 60075 }); 60076 const autocompleteProps = useBlockEditorAutocompleteProps({ 60077 onReplace, 60078 completers: autocompleters, 60079 record: value, 60080 onChange 60081 }); 60082 useMarkPersistent({ 60083 html: adjustedValue, 60084 value 60085 }); 60086 const keyboardShortcuts = (0,external_wp_element_namespaceObject.useRef)(new Set()); 60087 const inputEvents = (0,external_wp_element_namespaceObject.useRef)(new Set()); 60088 function onFocus() { 60089 anchorRef.current?.focus(); 60090 } 60091 const TagName = tagName; 60092 return (0,external_React_.createElement)(external_React_.Fragment, null, isSelected && (0,external_React_.createElement)(keyboardShortcutContext.Provider, { 60093 value: keyboardShortcuts 60094 }, (0,external_React_.createElement)(inputEventContext.Provider, { 60095 value: inputEvents 60096 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Popover.__unstableSlotNameProvider, { 60097 value: "__unstable-block-tools-after" 60098 }, children && children({ 60099 value, 60100 onChange, 60101 onFocus 60102 }), (0,external_React_.createElement)(FormatEdit, { 60103 value: value, 60104 onChange: onChange, 60105 onFocus: onFocus, 60106 formatTypes: formatTypes, 60107 forwardedRef: anchorRef 60108 })))), isSelected && hasFormats && (0,external_React_.createElement)(format_toolbar_container, { 60109 inline: inlineToolbar, 60110 editableContentElement: anchorRef.current, 60111 value: value 60112 }), (0,external_React_.createElement)(TagName 60113 // Overridable props. 60114 , { 60115 role: "textbox", 60116 "aria-multiline": !disableLineBreaks, 60117 "aria-label": placeholder, 60118 "aria-readonly": shouldDisableEditing, 60119 ...props, 60120 ...autocompleteProps, 60121 ref: (0,external_wp_compose_namespaceObject.useMergeRefs)([ 60122 // Rich text ref must be first because its focus listener 60123 // must be set up before any other ref calls .focus() on 60124 // mount. 60125 richTextRef, forwardedRef, autocompleteProps.ref, props.ref, useBeforeInputRules({ 60126 value, 60127 onChange 60128 }), useInputRules({ 60129 getValue, 60130 onChange, 60131 __unstableAllowPrefixTransformations, 60132 formatTypes, 60133 onReplace, 60134 selectionChange 60135 }), useInsertReplacementText(), useRemoveBrowserShortcuts(), useShortcuts(keyboardShortcuts), useInputEvents(inputEvents), useUndoAutomaticChange(), usePasteHandler({ 60136 isSelected, 60137 disableFormats, 60138 onChange, 60139 value, 60140 formatTypes, 60141 tagName, 60142 onReplace, 60143 onSplit, 60144 __unstableEmbedURLOnPaste, 60145 pastePlainText 60146 }), useDelete({ 60147 value, 60148 onMerge, 60149 onRemove 60150 }), useEnter({ 60151 removeEditorOnlyFormats, 60152 value, 60153 onReplace, 60154 onSplit, 60155 onChange, 60156 disableLineBreaks, 60157 onSplitAtEnd, 60158 onSplitAtDoubleLineEnd 60159 }), useFirefoxCompat(), anchorRef]), 60160 contentEditable: !shouldDisableEditing, 60161 suppressContentEditableWarning: true, 60162 className: classnames_default()('block-editor-rich-text__editable', props.className, 'rich-text') 60163 // Setting tabIndex to 0 is unnecessary, the element is already 60164 // focusable because it's contentEditable. This also fixes a 60165 // Safari bug where it's not possible to Shift+Click multi 60166 // select blocks when Shift Clicking into an element with 60167 // tabIndex because Safari will focus the element. However, 60168 // Safari will correctly ignore nested contentEditable elements. 60169 , 60170 tabIndex: props.tabIndex === 0 && !shouldDisableEditing ? null : props.tabIndex, 60171 "data-wp-block-attribute-key": identifier 60172 })); 60173 } 60174 60175 // This is the private API for the RichText component. 60176 // It allows access to all props, not just the public ones. 60177 const PrivateRichText = withDeprecations((0,external_wp_element_namespaceObject.forwardRef)(RichTextWrapper)); 60178 PrivateRichText.Content = Content; 60179 PrivateRichText.isEmpty = value => { 60180 return !value || value.length === 0; 60181 }; 60182 60183 // This is the public API for the RichText component. 60184 // We wrap the PrivateRichText component to hide some props from the public API. 60185 /** 60186 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/rich-text/README.md 60187 */ 60188 const PublicForwardedRichTextContainer = (0,external_wp_element_namespaceObject.forwardRef)((props, ref) => { 60189 return (0,external_React_.createElement)(PrivateRichText, { 60190 ref: ref, 60191 ...props, 60192 disableEditing: false 60193 }); 60194 }); 60195 PublicForwardedRichTextContainer.Content = Content; 60196 PublicForwardedRichTextContainer.isEmpty = value => { 60197 return !value || value.length === 0; 60198 }; 60199 /* harmony default export */ const rich_text = (PublicForwardedRichTextContainer); 60200 60201 60202 60203 60204 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/editable-text/index.js 60205 60206 /** 60207 * WordPress dependencies 60208 */ 60209 60210 60211 /** 60212 * Internal dependencies 60213 */ 60214 60215 const EditableText = (0,external_wp_element_namespaceObject.forwardRef)((props, ref) => { 60216 return (0,external_React_.createElement)(rich_text, { 60217 ref: ref, 60218 ...props, 60219 __unstableDisableFormats: true 60220 }); 60221 }); 60222 EditableText.Content = ({ 60223 value = '', 60224 tagName: Tag = 'div', 60225 ...props 60226 }) => { 60227 return (0,external_React_.createElement)(Tag, { 60228 ...props 60229 }, value); 60230 }; 60231 60232 /** 60233 * Renders an editable text input in which text formatting is not allowed. 60234 */ 60235 /* harmony default export */ const editable_text = (EditableText); 60236 60237 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/plain-text/index.js 60238 60239 /** 60240 * External dependencies 60241 */ 60242 60243 60244 60245 /** 60246 * WordPress dependencies 60247 */ 60248 60249 60250 /** 60251 * Internal dependencies 60252 */ 60253 60254 60255 /** 60256 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/plain-text/README.md 60257 */ 60258 const PlainText = (0,external_wp_element_namespaceObject.forwardRef)(({ 60259 __experimentalVersion, 60260 ...props 60261 }, ref) => { 60262 if (__experimentalVersion === 2) { 60263 return (0,external_React_.createElement)(editable_text, { 60264 ref: ref, 60265 ...props 60266 }); 60267 } 60268 const { 60269 className, 60270 onChange, 60271 ...remainingProps 60272 } = props; 60273 return (0,external_React_.createElement)(react_autosize_textarea_lib/* default */.A, { 60274 ref: ref, 60275 className: classnames_default()('block-editor-plain-text', className), 60276 onChange: event => onChange(event.target.value), 60277 ...remainingProps 60278 }); 60279 }); 60280 /* harmony default export */ const plain_text = (PlainText); 60281 60282 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/responsive-block-control/label.js 60283 60284 /** 60285 * WordPress dependencies 60286 */ 60287 60288 60289 60290 function ResponsiveBlockControlLabel({ 60291 property, 60292 viewport, 60293 desc 60294 }) { 60295 const instanceId = (0,external_wp_compose_namespaceObject.useInstanceId)(ResponsiveBlockControlLabel); 60296 const accessibleLabel = desc || (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: 1: property name. 2: viewport name. */ 60297 (0,external_wp_i18n_namespaceObject._x)('Controls the %1$s property for %2$s viewports.', 'Text labelling a interface as controlling a given layout property (eg: margin) for a given screen size.'), property, viewport.label); 60298 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)("span", { 60299 "aria-describedby": `rbc-desc-$instanceId}` 60300 }, viewport.label), (0,external_React_.createElement)(external_wp_components_namespaceObject.VisuallyHidden, { 60301 as: "span", 60302 id: `rbc-desc-$instanceId}` 60303 }, accessibleLabel)); 60304 } 60305 60306 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/responsive-block-control/index.js 60307 60308 /** 60309 * External dependencies 60310 */ 60311 60312 60313 /** 60314 * WordPress dependencies 60315 */ 60316 60317 60318 60319 60320 /** 60321 * Internal dependencies 60322 */ 60323 60324 function ResponsiveBlockControl(props) { 60325 const { 60326 title, 60327 property, 60328 toggleLabel, 60329 onIsResponsiveChange, 60330 renderDefaultControl, 60331 renderResponsiveControls, 60332 isResponsive = false, 60333 defaultLabel = { 60334 id: 'all', 60335 label: (0,external_wp_i18n_namespaceObject._x)('All', 'screen sizes') 60336 }, 60337 viewports = [{ 60338 id: 'small', 60339 label: (0,external_wp_i18n_namespaceObject.__)('Small screens') 60340 }, { 60341 id: 'medium', 60342 label: (0,external_wp_i18n_namespaceObject.__)('Medium screens') 60343 }, { 60344 id: 'large', 60345 label: (0,external_wp_i18n_namespaceObject.__)('Large screens') 60346 }] 60347 } = props; 60348 if (!title || !property || !renderDefaultControl) { 60349 return null; 60350 } 60351 const toggleControlLabel = toggleLabel || (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: Property value for the control (eg: margin, padding, etc.). */ 60352 (0,external_wp_i18n_namespaceObject.__)('Use the same %s on all screensizes.'), property); 60353 const toggleHelpText = (0,external_wp_i18n_namespaceObject.__)('Toggle between using the same value for all screen sizes or using a unique value per screen size.'); 60354 const defaultControl = renderDefaultControl((0,external_React_.createElement)(ResponsiveBlockControlLabel, { 60355 property: property, 60356 viewport: defaultLabel 60357 }), defaultLabel); 60358 const defaultResponsiveControls = () => { 60359 return viewports.map(viewport => (0,external_React_.createElement)(external_wp_element_namespaceObject.Fragment, { 60360 key: viewport.id 60361 }, renderDefaultControl((0,external_React_.createElement)(ResponsiveBlockControlLabel, { 60362 property: property, 60363 viewport: viewport 60364 }), viewport))); 60365 }; 60366 return (0,external_React_.createElement)("fieldset", { 60367 className: "block-editor-responsive-block-control" 60368 }, (0,external_React_.createElement)("legend", { 60369 className: "block-editor-responsive-block-control__title" 60370 }, title), (0,external_React_.createElement)("div", { 60371 className: "block-editor-responsive-block-control__inner" 60372 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.ToggleControl, { 60373 __nextHasNoMarginBottom: true, 60374 className: "block-editor-responsive-block-control__toggle", 60375 label: toggleControlLabel, 60376 checked: !isResponsive, 60377 onChange: onIsResponsiveChange, 60378 help: toggleHelpText 60379 }), (0,external_React_.createElement)("div", { 60380 className: classnames_default()('block-editor-responsive-block-control__group', { 60381 'is-responsive': isResponsive 60382 }) 60383 }, !isResponsive && defaultControl, isResponsive && (renderResponsiveControls ? renderResponsiveControls(viewports) : defaultResponsiveControls())))); 60384 } 60385 /* harmony default export */ const responsive_block_control = (ResponsiveBlockControl); 60386 60387 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/shortcut.js 60388 /** 60389 * WordPress dependencies 60390 */ 60391 60392 60393 60394 /** 60395 * Internal dependencies 60396 */ 60397 60398 function RichTextShortcut({ 60399 character, 60400 type, 60401 onUse 60402 }) { 60403 const keyboardShortcuts = (0,external_wp_element_namespaceObject.useContext)(keyboardShortcutContext); 60404 const onUseRef = (0,external_wp_element_namespaceObject.useRef)(); 60405 onUseRef.current = onUse; 60406 (0,external_wp_element_namespaceObject.useEffect)(() => { 60407 function callback(event) { 60408 if (external_wp_keycodes_namespaceObject.isKeyboardEvent[type](event, character)) { 60409 onUseRef.current(); 60410 event.preventDefault(); 60411 } 60412 } 60413 keyboardShortcuts.current.add(callback); 60414 return () => { 60415 keyboardShortcuts.current.delete(callback); 60416 }; 60417 }, [character, type]); 60418 return null; 60419 } 60420 60421 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/toolbar-button.js 60422 60423 /** 60424 * WordPress dependencies 60425 */ 60426 60427 60428 function RichTextToolbarButton({ 60429 name, 60430 shortcutType, 60431 shortcutCharacter, 60432 ...props 60433 }) { 60434 let shortcut; 60435 let fillName = 'RichText.ToolbarControls'; 60436 if (name) { 60437 fillName += `.$name}`; 60438 } 60439 if (shortcutType && shortcutCharacter) { 60440 shortcut = external_wp_keycodes_namespaceObject.displayShortcut[shortcutType](shortcutCharacter); 60441 } 60442 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Fill, { 60443 name: fillName 60444 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarButton, { 60445 ...props, 60446 shortcut: shortcut 60447 })); 60448 } 60449 60450 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/input-event.js 60451 /** 60452 * WordPress dependencies 60453 */ 60454 60455 60456 /** 60457 * Internal dependencies 60458 */ 60459 60460 function __unstableRichTextInputEvent({ 60461 inputType, 60462 onInput 60463 }) { 60464 const callbacks = (0,external_wp_element_namespaceObject.useContext)(inputEventContext); 60465 const onInputRef = (0,external_wp_element_namespaceObject.useRef)(); 60466 onInputRef.current = onInput; 60467 (0,external_wp_element_namespaceObject.useEffect)(() => { 60468 function callback(event) { 60469 if (event.inputType === inputType) { 60470 onInputRef.current(); 60471 event.preventDefault(); 60472 } 60473 } 60474 callbacks.current.add(callback); 60475 return () => { 60476 callbacks.current.delete(callback); 60477 }; 60478 }, [inputType]); 60479 return null; 60480 } 60481 60482 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/tool-selector/index.js 60483 60484 /** 60485 * WordPress dependencies 60486 */ 60487 60488 60489 60490 60491 60492 60493 /** 60494 * Internal dependencies 60495 */ 60496 60497 const selectIcon = (0,external_React_.createElement)(external_wp_components_namespaceObject.SVG, { 60498 xmlns: "http://www.w3.org/2000/svg", 60499 width: "24", 60500 height: "24", 60501 viewBox: "0 0 24 24" 60502 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Path, { 60503 d: "M9.4 20.5L5.2 3.8l14.6 9-2 .3c-.2 0-.4.1-.7.1-.9.2-1.6.3-2.2.5-.8.3-1.4.5-1.8.8-.4.3-.8.8-1.3 1.5-.4.5-.8 1.2-1.2 2l-.3.6-.9 1.9zM7.6 7.1l2.4 9.3c.2-.4.5-.8.7-1.1.6-.8 1.1-1.4 1.6-1.8.5-.4 1.3-.8 2.2-1.1l1.2-.3-8.1-5z" 60504 })); 60505 function ToolSelector(props, ref) { 60506 const mode = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).__unstableGetEditorMode(), []); 60507 const { 60508 __unstableSetEditorMode 60509 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 60510 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Dropdown, { 60511 renderToggle: ({ 60512 isOpen, 60513 onToggle 60514 }) => (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 60515 ...props, 60516 ref: ref, 60517 icon: mode === 'navigation' ? selectIcon : edit, 60518 "aria-expanded": isOpen, 60519 "aria-haspopup": "true", 60520 onClick: onToggle 60521 /* translators: button label text should, if possible, be under 16 characters. */, 60522 label: (0,external_wp_i18n_namespaceObject.__)('Tools') 60523 }), 60524 popoverProps: { 60525 placement: 'bottom-start' 60526 }, 60527 renderContent: () => (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.NavigableMenu, { 60528 role: "menu", 60529 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Tools') 60530 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItemsChoice, { 60531 value: mode === 'navigation' ? 'navigation' : 'edit', 60532 onSelect: __unstableSetEditorMode, 60533 choices: [{ 60534 value: 'edit', 60535 label: (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(build_module_icon, { 60536 icon: edit 60537 }), (0,external_wp_i18n_namespaceObject.__)('Edit')) 60538 }, { 60539 value: 'navigation', 60540 label: (0,external_React_.createElement)(external_React_.Fragment, null, selectIcon, (0,external_wp_i18n_namespaceObject.__)('Select')) 60541 }] 60542 })), (0,external_React_.createElement)("div", { 60543 className: "block-editor-tool-selector__help" 60544 }, (0,external_wp_i18n_namespaceObject.__)('Tools provide different interactions for selecting, navigating, and editing blocks. Toggle between select and edit by pressing Escape and Enter.'))) 60545 }); 60546 } 60547 /* harmony default export */ const tool_selector = ((0,external_wp_element_namespaceObject.forwardRef)(ToolSelector)); 60548 60549 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/unit-control/index.js 60550 60551 /** 60552 * WordPress dependencies 60553 */ 60554 60555 60556 /** 60557 * Internal dependencies 60558 */ 60559 60560 function UnitControl({ 60561 units: unitsProp, 60562 ...props 60563 }) { 60564 const [availableUnits] = use_settings_useSettings('spacing.units'); 60565 const units = (0,external_wp_components_namespaceObject.__experimentalUseCustomUnits)({ 60566 availableUnits: availableUnits || ['%', 'px', 'em', 'rem', 'vw'], 60567 units: unitsProp 60568 }); 60569 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalUnitControl, { 60570 units: units, 60571 ...props 60572 }); 60573 } 60574 60575 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/arrow-left.js 60576 60577 /** 60578 * WordPress dependencies 60579 */ 60580 60581 const arrowLeft = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 60582 xmlns: "http://www.w3.org/2000/svg", 60583 viewBox: "0 0 24 24" 60584 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 60585 d: "M20 11.2H6.8l3.7-3.7-1-1L3.9 12l5.6 5.5 1-1-3.7-3.7H20z" 60586 })); 60587 /* harmony default export */ const arrow_left = (arrowLeft); 60588 60589 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/url-input/button.js 60590 60591 /** 60592 * WordPress dependencies 60593 */ 60594 60595 60596 60597 60598 60599 /** 60600 * Internal dependencies 60601 */ 60602 60603 class URLInputButton extends external_wp_element_namespaceObject.Component { 60604 constructor() { 60605 super(...arguments); 60606 this.toggle = this.toggle.bind(this); 60607 this.submitLink = this.submitLink.bind(this); 60608 this.state = { 60609 expanded: false 60610 }; 60611 } 60612 toggle() { 60613 this.setState({ 60614 expanded: !this.state.expanded 60615 }); 60616 } 60617 submitLink(event) { 60618 event.preventDefault(); 60619 this.toggle(); 60620 } 60621 render() { 60622 const { 60623 url, 60624 onChange 60625 } = this.props; 60626 const { 60627 expanded 60628 } = this.state; 60629 const buttonLabel = url ? (0,external_wp_i18n_namespaceObject.__)('Edit link') : (0,external_wp_i18n_namespaceObject.__)('Insert link'); 60630 return (0,external_React_.createElement)("div", { 60631 className: "block-editor-url-input__button" 60632 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 60633 icon: library_link, 60634 label: buttonLabel, 60635 onClick: this.toggle, 60636 className: "components-toolbar__control", 60637 isPressed: !!url 60638 }), expanded && (0,external_React_.createElement)("form", { 60639 className: "block-editor-url-input__button-modal", 60640 onSubmit: this.submitLink 60641 }, (0,external_React_.createElement)("div", { 60642 className: "block-editor-url-input__button-modal-line" 60643 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 60644 className: "block-editor-url-input__back", 60645 icon: arrow_left, 60646 label: (0,external_wp_i18n_namespaceObject.__)('Close'), 60647 onClick: this.toggle 60648 }), (0,external_React_.createElement)(url_input, { 60649 __nextHasNoMarginBottom: true, 60650 value: url || '', 60651 onChange: onChange 60652 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 60653 icon: keyboard_return, 60654 label: (0,external_wp_i18n_namespaceObject.__)('Submit'), 60655 type: "submit" 60656 })))); 60657 } 60658 } 60659 60660 /** 60661 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/url-input/README.md 60662 */ 60663 /* harmony default export */ const url_input_button = (URLInputButton); 60664 60665 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/image.js 60666 60667 /** 60668 * WordPress dependencies 60669 */ 60670 60671 const image_image = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 60672 viewBox: "0 0 24 24", 60673 xmlns: "http://www.w3.org/2000/svg" 60674 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 60675 d: "M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM5 4.5h14c.3 0 .5.2.5.5v8.4l-3-2.9c-.3-.3-.8-.3-1 0L11.9 14 9 12c-.3-.2-.6-.2-.8 0l-3.6 2.6V5c-.1-.3.1-.5.4-.5zm14 15H5c-.3 0-.5-.2-.5-.5v-2.4l4.1-3 3 1.9c.3.2.7.2.9-.1L16 12l3.5 3.4V19c0 .3-.2.5-.5.5z" 60676 })); 60677 /* harmony default export */ const library_image = (image_image); 60678 60679 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/url-popover/image-url-input-ui.js 60680 60681 /** 60682 * WordPress dependencies 60683 */ 60684 60685 60686 60687 60688 60689 60690 /** 60691 * Internal dependencies 60692 */ 60693 60694 const LINK_DESTINATION_NONE = 'none'; 60695 const LINK_DESTINATION_CUSTOM = 'custom'; 60696 const LINK_DESTINATION_MEDIA = 'media'; 60697 const LINK_DESTINATION_ATTACHMENT = 'attachment'; 60698 const NEW_TAB_REL = ['noreferrer', 'noopener']; 60699 const ImageURLInputUI = ({ 60700 linkDestination, 60701 onChangeUrl, 60702 url, 60703 mediaType = 'image', 60704 mediaUrl, 60705 mediaLink, 60706 linkTarget, 60707 linkClass, 60708 rel, 60709 showLightboxSetting, 60710 lightboxEnabled, 60711 onSetLightbox, 60712 resetLightbox 60713 }) => { 60714 const [isOpen, setIsOpen] = (0,external_wp_element_namespaceObject.useState)(false); 60715 // Use internal state instead of a ref to make sure that the component 60716 // re-renders when the popover's anchor updates. 60717 const [popoverAnchor, setPopoverAnchor] = (0,external_wp_element_namespaceObject.useState)(null); 60718 const openLinkUI = () => { 60719 setIsOpen(true); 60720 }; 60721 const [isEditingLink, setIsEditingLink] = (0,external_wp_element_namespaceObject.useState)(false); 60722 const [urlInput, setUrlInput] = (0,external_wp_element_namespaceObject.useState)(null); 60723 const autocompleteRef = (0,external_wp_element_namespaceObject.useRef)(null); 60724 const wrapperRef = (0,external_wp_element_namespaceObject.useRef)(); 60725 (0,external_wp_element_namespaceObject.useEffect)(() => { 60726 if (!wrapperRef.current) { 60727 return; 60728 } 60729 const nextFocusTarget = external_wp_dom_namespaceObject.focus.focusable.find(wrapperRef.current)[0] || wrapperRef.current; 60730 nextFocusTarget.focus(); 60731 }, [isEditingLink, url, lightboxEnabled]); 60732 const startEditLink = () => { 60733 if (linkDestination === LINK_DESTINATION_MEDIA || linkDestination === LINK_DESTINATION_ATTACHMENT) { 60734 setUrlInput(''); 60735 } 60736 setIsEditingLink(true); 60737 }; 60738 const stopEditLink = () => { 60739 setIsEditingLink(false); 60740 }; 60741 const closeLinkUI = () => { 60742 setUrlInput(null); 60743 stopEditLink(); 60744 setIsOpen(false); 60745 }; 60746 const getUpdatedLinkTargetSettings = value => { 60747 const newLinkTarget = value ? '_blank' : undefined; 60748 let updatedRel; 60749 if (newLinkTarget) { 60750 const rels = (rel !== null && rel !== void 0 ? rel : '').split(' '); 60751 NEW_TAB_REL.forEach(relVal => { 60752 if (!rels.includes(relVal)) { 60753 rels.push(relVal); 60754 } 60755 }); 60756 updatedRel = rels.join(' '); 60757 } else { 60758 const rels = (rel !== null && rel !== void 0 ? rel : '').split(' ').filter(relVal => NEW_TAB_REL.includes(relVal) === false); 60759 updatedRel = rels.length ? rels.join(' ') : undefined; 60760 } 60761 return { 60762 linkTarget: newLinkTarget, 60763 rel: updatedRel 60764 }; 60765 }; 60766 const onFocusOutside = () => { 60767 return event => { 60768 // The autocomplete suggestions list renders in a separate popover (in a portal), 60769 // so onFocusOutside fails to detect that a click on a suggestion occurred in the 60770 // LinkContainer. Detect clicks on autocomplete suggestions using a ref here, and 60771 // return to avoid the popover being closed. 60772 const autocompleteElement = autocompleteRef.current; 60773 if (autocompleteElement && autocompleteElement.contains(event.target)) { 60774 return; 60775 } 60776 setIsOpen(false); 60777 setUrlInput(null); 60778 stopEditLink(); 60779 }; 60780 }; 60781 const onSubmitLinkChange = () => { 60782 return event => { 60783 if (urlInput) { 60784 // It is possible the entered URL actually matches a named link destination. 60785 // This check will ensure our link destination is correct. 60786 const selectedDestination = getLinkDestinations().find(destination => destination.url === urlInput)?.linkDestination || LINK_DESTINATION_CUSTOM; 60787 onChangeUrl({ 60788 href: urlInput, 60789 linkDestination: selectedDestination, 60790 lightbox: { 60791 enabled: false 60792 } 60793 }); 60794 } 60795 stopEditLink(); 60796 setUrlInput(null); 60797 event.preventDefault(); 60798 }; 60799 }; 60800 const onLinkRemove = () => { 60801 onChangeUrl({ 60802 linkDestination: LINK_DESTINATION_NONE, 60803 href: '' 60804 }); 60805 }; 60806 const getLinkDestinations = () => { 60807 const linkDestinations = [{ 60808 linkDestination: LINK_DESTINATION_MEDIA, 60809 title: (0,external_wp_i18n_namespaceObject.__)('Link to image file'), 60810 url: mediaType === 'image' ? mediaUrl : undefined, 60811 icon: library_image 60812 }]; 60813 if (mediaType === 'image' && mediaLink) { 60814 linkDestinations.push({ 60815 linkDestination: LINK_DESTINATION_ATTACHMENT, 60816 title: (0,external_wp_i18n_namespaceObject.__)('Link to attachment page'), 60817 url: mediaType === 'image' ? mediaLink : undefined, 60818 icon: library_page 60819 }); 60820 } 60821 return linkDestinations; 60822 }; 60823 const onSetHref = value => { 60824 const linkDestinations = getLinkDestinations(); 60825 let linkDestinationInput; 60826 if (!value) { 60827 linkDestinationInput = LINK_DESTINATION_NONE; 60828 } else { 60829 linkDestinationInput = (linkDestinations.find(destination => { 60830 return destination.url === value; 60831 }) || { 60832 linkDestination: LINK_DESTINATION_CUSTOM 60833 }).linkDestination; 60834 } 60835 onChangeUrl({ 60836 linkDestination: linkDestinationInput, 60837 href: value 60838 }); 60839 }; 60840 const onSetNewTab = value => { 60841 const updatedLinkTarget = getUpdatedLinkTargetSettings(value); 60842 onChangeUrl(updatedLinkTarget); 60843 }; 60844 const onSetLinkRel = value => { 60845 onChangeUrl({ 60846 rel: value 60847 }); 60848 }; 60849 const onSetLinkClass = value => { 60850 onChangeUrl({ 60851 linkClass: value 60852 }); 60853 }; 60854 const advancedOptions = (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalVStack, { 60855 spacing: "3" 60856 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.ToggleControl, { 60857 __nextHasNoMarginBottom: true, 60858 label: (0,external_wp_i18n_namespaceObject.__)('Open in new tab'), 60859 onChange: onSetNewTab, 60860 checked: linkTarget === '_blank' 60861 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.TextControl, { 60862 __nextHasNoMarginBottom: true, 60863 label: (0,external_wp_i18n_namespaceObject.__)('Link rel'), 60864 value: rel !== null && rel !== void 0 ? rel : '', 60865 onChange: onSetLinkRel 60866 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.TextControl, { 60867 __nextHasNoMarginBottom: true, 60868 label: (0,external_wp_i18n_namespaceObject.__)('Link CSS class'), 60869 value: linkClass || '', 60870 onChange: onSetLinkClass 60871 })); 60872 const linkEditorValue = urlInput !== null ? urlInput : url; 60873 const hideLightboxPanel = !lightboxEnabled || lightboxEnabled && !showLightboxSetting; 60874 const showLinkEditor = !linkEditorValue && hideLightboxPanel; 60875 const urlLabel = (getLinkDestinations().find(destination => destination.linkDestination === linkDestination) || {}).title; 60876 const PopoverChildren = () => { 60877 if (lightboxEnabled && showLightboxSetting && !url && !isEditingLink) { 60878 return (0,external_React_.createElement)("div", { 60879 className: "block-editor-url-popover__expand-on-click" 60880 }, (0,external_React_.createElement)(build_module_icon, { 60881 icon: library_fullscreen 60882 }), (0,external_React_.createElement)("div", { 60883 className: "text" 60884 }, (0,external_React_.createElement)("p", null, (0,external_wp_i18n_namespaceObject.__)('Expand on click')), (0,external_React_.createElement)("p", { 60885 className: "description" 60886 }, (0,external_wp_i18n_namespaceObject.__)('Scales the image with a lightbox effect'))), (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 60887 icon: link_off, 60888 label: (0,external_wp_i18n_namespaceObject.__)('Disable expand on click'), 60889 onClick: () => { 60890 onSetLightbox(false); 60891 }, 60892 size: "compact" 60893 })); 60894 } else if (!url || isEditingLink) { 60895 return (0,external_React_.createElement)(url_popover.LinkEditor, { 60896 className: "block-editor-format-toolbar__link-container-content", 60897 value: linkEditorValue, 60898 onChangeInputValue: setUrlInput, 60899 onSubmit: onSubmitLinkChange(), 60900 autocompleteRef: autocompleteRef 60901 }); 60902 } else if (url && !isEditingLink) { 60903 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(url_popover.LinkViewer, { 60904 className: "block-editor-format-toolbar__link-container-content", 60905 url: url, 60906 onEditLinkClick: startEditLink, 60907 urlLabel: urlLabel 60908 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 60909 icon: link_off, 60910 label: (0,external_wp_i18n_namespaceObject.__)('Remove link'), 60911 onClick: () => { 60912 onLinkRemove(); 60913 resetLightbox(); 60914 }, 60915 size: "compact" 60916 })); 60917 } 60918 }; 60919 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.ToolbarButton, { 60920 icon: library_link, 60921 className: "components-toolbar__control", 60922 label: (0,external_wp_i18n_namespaceObject.__)('Link'), 60923 "aria-expanded": isOpen, 60924 onClick: openLinkUI, 60925 ref: setPopoverAnchor, 60926 isActive: !!url || lightboxEnabled && showLightboxSetting 60927 }), isOpen && (0,external_React_.createElement)(url_popover, { 60928 ref: wrapperRef, 60929 anchor: popoverAnchor, 60930 onFocusOutside: onFocusOutside(), 60931 onClose: closeLinkUI, 60932 renderSettings: hideLightboxPanel ? () => advancedOptions : null, 60933 additionalControls: showLinkEditor && (0,external_React_.createElement)(external_wp_components_namespaceObject.NavigableMenu, null, getLinkDestinations().map(link => (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 60934 key: link.linkDestination, 60935 icon: link.icon, 60936 iconPosition: "left", 60937 onClick: () => { 60938 setUrlInput(null); 60939 onSetHref(link.url); 60940 stopEditLink(); 60941 } 60942 }, link.title)), showLightboxSetting && (0,external_React_.createElement)(external_wp_components_namespaceObject.MenuItem, { 60943 key: "expand-on-click", 60944 className: "block-editor-url-popover__expand-on-click", 60945 icon: library_fullscreen, 60946 info: (0,external_wp_i18n_namespaceObject.__)('Scale the image with a lightbox effect.'), 60947 iconPosition: "left", 60948 onClick: () => { 60949 setUrlInput(null); 60950 onChangeUrl({ 60951 linkDestination: LINK_DESTINATION_NONE, 60952 href: '' 60953 }); 60954 onSetLightbox(true); 60955 stopEditLink(); 60956 } 60957 }, (0,external_wp_i18n_namespaceObject.__)('Expand on click'))), 60958 offset: 13 60959 }, PopoverChildren())); 60960 }; 60961 60962 60963 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/preview-options/index.js 60964 /** 60965 * WordPress dependencies 60966 */ 60967 60968 function PreviewOptions() { 60969 external_wp_deprecated_default()('wp.blockEditor.PreviewOptions', { 60970 version: '6.5' 60971 }); 60972 return null; 60973 } 60974 60975 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/use-resize-canvas/index.js 60976 /** 60977 * WordPress dependencies 60978 */ 60979 60980 60981 /** 60982 * Function to resize the editor window. 60983 * 60984 * @param {string} deviceType Used for determining the size of the container (e.g. Desktop, Tablet, Mobile) 60985 * 60986 * @return {Object} Inline styles to be added to resizable container. 60987 */ 60988 function useResizeCanvas(deviceType) { 60989 const [actualWidth, updateActualWidth] = (0,external_wp_element_namespaceObject.useState)(window.innerWidth); 60990 (0,external_wp_element_namespaceObject.useEffect)(() => { 60991 if (deviceType === 'Desktop') { 60992 return; 60993 } 60994 const resizeListener = () => updateActualWidth(window.innerWidth); 60995 window.addEventListener('resize', resizeListener); 60996 return () => { 60997 window.removeEventListener('resize', resizeListener); 60998 }; 60999 }, [deviceType]); 61000 const getCanvasWidth = device => { 61001 let deviceWidth; 61002 switch (device) { 61003 case 'Tablet': 61004 deviceWidth = 780; 61005 break; 61006 case 'Mobile': 61007 deviceWidth = 360; 61008 break; 61009 default: 61010 return null; 61011 } 61012 return deviceWidth < actualWidth ? deviceWidth : actualWidth; 61013 }; 61014 const marginValue = () => window.innerHeight < 800 ? 36 : 72; 61015 const contentInlineStyles = device => { 61016 const height = device === 'Mobile' ? '768px' : '1024px'; 61017 const marginVertical = marginValue() + 'px'; 61018 const marginHorizontal = 'auto'; 61019 switch (device) { 61020 case 'Tablet': 61021 case 'Mobile': 61022 return { 61023 width: getCanvasWidth(device), 61024 // Keeping margin styles separate to avoid warnings 61025 // when those props get overridden in the iframe component 61026 marginTop: marginVertical, 61027 marginBottom: marginVertical, 61028 marginLeft: marginHorizontal, 61029 marginRight: marginHorizontal, 61030 height, 61031 borderRadius: '2px 2px 2px 2px', 61032 border: '1px solid #ddd', 61033 overflowY: 'auto' 61034 }; 61035 default: 61036 return { 61037 marginLeft: marginHorizontal, 61038 marginRight: marginHorizontal 61039 }; 61040 } 61041 }; 61042 return contentInlineStyles(deviceType); 61043 } 61044 61045 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/skip-to-selected-block/index.js 61046 61047 /** 61048 * WordPress dependencies 61049 */ 61050 61051 61052 61053 61054 /** 61055 * Internal dependencies 61056 */ 61057 61058 61059 const SkipToSelectedBlock = ({ 61060 selectedBlockClientId 61061 }) => { 61062 const ref = useBlockRef(selectedBlockClientId); 61063 const onClick = () => { 61064 ref.current.focus(); 61065 }; 61066 return selectedBlockClientId ? (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 61067 variant: "secondary", 61068 className: "block-editor-skip-to-selected-block", 61069 onClick: onClick 61070 }, (0,external_wp_i18n_namespaceObject.__)('Skip to the selected block')) : null; 61071 }; 61072 61073 /** 61074 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/skip-to-selected-block/README.md 61075 */ 61076 /* harmony default export */ const skip_to_selected_block = ((0,external_wp_data_namespaceObject.withSelect)(select => { 61077 return { 61078 selectedBlockClientId: select(store).getBlockSelectionStart() 61079 }; 61080 })(SkipToSelectedBlock)); 61081 61082 ;// CONCATENATED MODULE: external ["wp","wordcount"] 61083 const external_wp_wordcount_namespaceObject = window["wp"]["wordcount"]; 61084 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/multi-selection-inspector/index.js 61085 61086 /** 61087 * WordPress dependencies 61088 */ 61089 61090 61091 61092 61093 61094 61095 /** 61096 * Internal dependencies 61097 */ 61098 61099 61100 function MultiSelectionInspector({ 61101 blocks 61102 }) { 61103 const words = (0,external_wp_wordcount_namespaceObject.count)((0,external_wp_blocks_namespaceObject.serialize)(blocks), 'words'); 61104 return (0,external_React_.createElement)("div", { 61105 className: "block-editor-multi-selection-inspector__card" 61106 }, (0,external_React_.createElement)(block_icon, { 61107 icon: library_copy, 61108 showColors: true 61109 }), (0,external_React_.createElement)("div", { 61110 className: "block-editor-multi-selection-inspector__card-content" 61111 }, (0,external_React_.createElement)("div", { 61112 className: "block-editor-multi-selection-inspector__card-title" 61113 }, (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %d: number of blocks */ 61114 (0,external_wp_i18n_namespaceObject._n)('%d Block', '%d Blocks', blocks.length), blocks.length)), (0,external_React_.createElement)("div", { 61115 className: "block-editor-multi-selection-inspector__card-description" 61116 }, (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %d: number of words */ 61117 (0,external_wp_i18n_namespaceObject._n)('%d word selected.', '%d words selected.', words), words)))); 61118 } 61119 /* harmony default export */ const multi_selection_inspector = ((0,external_wp_data_namespaceObject.withSelect)(select => { 61120 const { 61121 getMultiSelectedBlocks 61122 } = select(store); 61123 return { 61124 blocks: getMultiSelectedBlocks() 61125 }; 61126 })(MultiSelectionInspector)); 61127 61128 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/default-style-picker/index.js 61129 61130 /** 61131 * WordPress dependencies 61132 */ 61133 61134 61135 61136 61137 61138 61139 /** 61140 * Internal dependencies 61141 */ 61142 61143 61144 function DefaultStylePicker({ 61145 blockName 61146 }) { 61147 const { 61148 preferredStyle, 61149 onUpdatePreferredStyleVariations, 61150 styles 61151 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 61152 var _preferredStyleVariat; 61153 const settings = select(store).getSettings(); 61154 const preferredStyleVariations = settings.__experimentalPreferredStyleVariations; 61155 return { 61156 preferredStyle: preferredStyleVariations?.value?.[blockName], 61157 onUpdatePreferredStyleVariations: (_preferredStyleVariat = preferredStyleVariations?.onChange) !== null && _preferredStyleVariat !== void 0 ? _preferredStyleVariat : null, 61158 styles: select(external_wp_blocks_namespaceObject.store).getBlockStyles(blockName) 61159 }; 61160 }, [blockName]); 61161 const selectOptions = (0,external_wp_element_namespaceObject.useMemo)(() => [{ 61162 label: (0,external_wp_i18n_namespaceObject.__)('Not set'), 61163 value: '' 61164 }, ...styles.map(({ 61165 label, 61166 name 61167 }) => ({ 61168 label, 61169 value: name 61170 }))], [styles]); 61171 const defaultStyleName = (0,external_wp_element_namespaceObject.useMemo)(() => getDefaultStyle(styles)?.name, [styles]); 61172 const selectOnChange = (0,external_wp_element_namespaceObject.useCallback)(blockStyle => { 61173 onUpdatePreferredStyleVariations(blockName, blockStyle); 61174 }, [blockName, onUpdatePreferredStyleVariations]); 61175 61176 // Until the functionality is migrated to global styles, 61177 // only show the default style picker if a non-default style has already been selected. 61178 if (!preferredStyle || preferredStyle === defaultStyleName) { 61179 return null; 61180 } 61181 return onUpdatePreferredStyleVariations && (0,external_React_.createElement)("div", { 61182 className: "default-style-picker__default-switcher" 61183 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.SelectControl, { 61184 __nextHasNoMarginBottom: true, 61185 options: selectOptions, 61186 value: preferredStyle || '', 61187 label: (0,external_wp_i18n_namespaceObject.__)('Default Style'), 61188 onChange: selectOnChange 61189 })); 61190 } 61191 61192 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/cog.js 61193 61194 /** 61195 * WordPress dependencies 61196 */ 61197 61198 const cog = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 61199 xmlns: "http://www.w3.org/2000/svg", 61200 viewBox: "0 0 24 24" 61201 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 61202 fillRule: "evenodd", 61203 d: "M10.289 4.836A1 1 0 0111.275 4h1.306a1 1 0 01.987.836l.244 1.466c.787.26 1.503.679 2.108 1.218l1.393-.522a1 1 0 011.216.437l.653 1.13a1 1 0 01-.23 1.273l-1.148.944a6.025 6.025 0 010 2.435l1.149.946a1 1 0 01.23 1.272l-.653 1.13a1 1 0 01-1.216.437l-1.394-.522c-.605.54-1.32.958-2.108 1.218l-.244 1.466a1 1 0 01-.987.836h-1.306a1 1 0 01-.986-.836l-.244-1.466a5.995 5.995 0 01-2.108-1.218l-1.394.522a1 1 0 01-1.217-.436l-.653-1.131a1 1 0 01.23-1.272l1.149-.946a6.026 6.026 0 010-2.435l-1.148-.944a1 1 0 01-.23-1.272l.653-1.131a1 1 0 011.217-.437l1.393.522a5.994 5.994 0 012.108-1.218l.244-1.466zM14.929 12a3 3 0 11-6 0 3 3 0 016 0z", 61204 clipRule: "evenodd" 61205 })); 61206 /* harmony default export */ const library_cog = (cog); 61207 61208 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/styles.js 61209 61210 /** 61211 * WordPress dependencies 61212 */ 61213 61214 const styles = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 61215 viewBox: "0 0 24 24", 61216 xmlns: "http://www.w3.org/2000/svg" 61217 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 61218 d: "M12 4c-4.4 0-8 3.6-8 8v.1c0 4.1 3.2 7.5 7.2 7.9h.8c4.4 0 8-3.6 8-8s-3.6-8-8-8zm0 15V5c3.9 0 7 3.1 7 7s-3.1 7-7 7z" 61219 })); 61220 /* harmony default export */ const library_styles = (styles); 61221 61222 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls-tabs/utils.js 61223 /** 61224 * WordPress dependencies 61225 */ 61226 61227 61228 const TAB_SETTINGS = { 61229 name: 'settings', 61230 title: (0,external_wp_i18n_namespaceObject.__)('Settings'), 61231 value: 'settings', 61232 icon: library_cog, 61233 className: 'block-editor-block-inspector__tab-item' 61234 }; 61235 const TAB_STYLES = { 61236 name: 'styles', 61237 title: (0,external_wp_i18n_namespaceObject.__)('Styles'), 61238 value: 'styles', 61239 icon: library_styles, 61240 className: 'block-editor-block-inspector__tab-item' 61241 }; 61242 const TAB_LIST_VIEW = { 61243 name: 'list', 61244 title: (0,external_wp_i18n_namespaceObject.__)('List View'), 61245 value: 'list-view', 61246 icon: list_view, 61247 className: 'block-editor-block-inspector__tab-item' 61248 }; 61249 61250 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls-tabs/advanced-controls-panel.js 61251 61252 /** 61253 * WordPress dependencies 61254 */ 61255 61256 61257 61258 /** 61259 * Internal dependencies 61260 */ 61261 61262 const AdvancedControls = () => { 61263 const fills = (0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(InspectorAdvancedControls.slotName); 61264 const hasFills = Boolean(fills && fills.length); 61265 if (!hasFills) { 61266 return null; 61267 } 61268 return (0,external_React_.createElement)(external_wp_components_namespaceObject.PanelBody, { 61269 className: "block-editor-block-inspector__advanced", 61270 title: (0,external_wp_i18n_namespaceObject.__)('Advanced'), 61271 initialOpen: false 61272 }, (0,external_React_.createElement)(inspector_controls.Slot, { 61273 group: "advanced" 61274 })); 61275 }; 61276 /* harmony default export */ const advanced_controls_panel = (AdvancedControls); 61277 61278 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls-tabs/position-controls-panel.js 61279 61280 /** 61281 * WordPress dependencies 61282 */ 61283 61284 61285 61286 61287 61288 /** 61289 * Internal dependencies 61290 */ 61291 61292 61293 61294 const PositionControlsPanel = () => { 61295 const [initialOpen, setInitialOpen] = (0,external_wp_element_namespaceObject.useState)(); 61296 61297 // Determine whether the panel should be expanded. 61298 const { 61299 multiSelectedBlocks 61300 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 61301 const { 61302 getBlocksByClientId, 61303 getSelectedBlockClientIds 61304 } = select(store); 61305 const clientIds = getSelectedBlockClientIds(); 61306 return { 61307 multiSelectedBlocks: getBlocksByClientId(clientIds) 61308 }; 61309 }, []); 61310 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 61311 // If any selected block has a position set, open the panel by default. 61312 // The first block's value will still be used within the control though. 61313 if (initialOpen === undefined) { 61314 setInitialOpen(multiSelectedBlocks.some(({ 61315 attributes 61316 }) => !!attributes?.style?.position?.type)); 61317 } 61318 }, [initialOpen, multiSelectedBlocks, setInitialOpen]); 61319 return (0,external_React_.createElement)(external_wp_components_namespaceObject.PanelBody, { 61320 className: "block-editor-block-inspector__position", 61321 title: (0,external_wp_i18n_namespaceObject.__)('Position'), 61322 initialOpen: initialOpen !== null && initialOpen !== void 0 ? initialOpen : false 61323 }, (0,external_React_.createElement)(inspector_controls.Slot, { 61324 group: "position" 61325 })); 61326 }; 61327 const PositionControls = () => { 61328 const fills = (0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(inspector_controls_groups.position.Slot.__unstableName); 61329 const hasFills = Boolean(fills && fills.length); 61330 if (!hasFills) { 61331 return null; 61332 } 61333 return (0,external_React_.createElement)(PositionControlsPanel, null); 61334 }; 61335 /* harmony default export */ const position_controls_panel = (PositionControls); 61336 61337 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/close.js 61338 61339 /** 61340 * WordPress dependencies 61341 */ 61342 61343 const close_close = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 61344 xmlns: "http://www.w3.org/2000/svg", 61345 viewBox: "0 0 24 24" 61346 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 61347 d: "M13 11.8l6.1-6.3-1-1-6.1 6.2-6.1-6.2-1 1 6.1 6.3-6.5 6.7 1 1 6.5-6.6 6.5 6.6 1-1z" 61348 })); 61349 /* harmony default export */ const library_close = (close_close); 61350 61351 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls-tabs/settings-tab-hint.js 61352 61353 /** 61354 * WordPress dependencies 61355 */ 61356 61357 61358 61359 61360 61361 61362 61363 const PREFERENCE_NAME = 'isInspectorControlsTabsHintVisible'; 61364 function InspectorControlsTabsHint() { 61365 const isInspectorControlsTabsHintVisible = (0,external_wp_data_namespaceObject.useSelect)(select => { 61366 var _select$get; 61367 return (_select$get = select(external_wp_preferences_namespaceObject.store).get('core', PREFERENCE_NAME)) !== null && _select$get !== void 0 ? _select$get : true; 61368 }, []); 61369 const ref = (0,external_wp_element_namespaceObject.useRef)(); 61370 const { 61371 set: setPreference 61372 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_preferences_namespaceObject.store); 61373 if (!isInspectorControlsTabsHintVisible) { 61374 return null; 61375 } 61376 return (0,external_React_.createElement)("div", { 61377 ref: ref, 61378 className: "block-editor-inspector-controls-tabs__hint" 61379 }, (0,external_React_.createElement)("div", { 61380 className: "block-editor-inspector-controls-tabs__hint-content" 61381 }, (0,external_wp_i18n_namespaceObject.__)("Looking for other block settings? They've moved to the styles tab.")), (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 61382 className: "block-editor-inspector-controls-tabs__hint-dismiss", 61383 icon: library_close, 61384 iconSize: "16", 61385 label: (0,external_wp_i18n_namespaceObject.__)('Dismiss hint'), 61386 onClick: () => { 61387 // Retain focus when dismissing the element. 61388 const previousElement = external_wp_dom_namespaceObject.focus.tabbable.findPrevious(ref.current); 61389 previousElement?.focus(); 61390 setPreference('core', PREFERENCE_NAME, false); 61391 }, 61392 showTooltip: false 61393 })); 61394 } 61395 61396 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls-tabs/settings-tab.js 61397 61398 /** 61399 * Internal dependencies 61400 */ 61401 61402 61403 61404 61405 const SettingsTab = ({ 61406 showAdvancedControls = false 61407 }) => (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(inspector_controls.Slot, null), (0,external_React_.createElement)(position_controls_panel, null), showAdvancedControls && (0,external_React_.createElement)("div", null, (0,external_React_.createElement)(advanced_controls_panel, null)), (0,external_React_.createElement)(InspectorControlsTabsHint, null)); 61408 /* harmony default export */ const settings_tab = (SettingsTab); 61409 61410 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls-tabs/styles-tab.js 61411 61412 /** 61413 * WordPress dependencies 61414 */ 61415 61416 61417 61418 61419 /** 61420 * Internal dependencies 61421 */ 61422 61423 61424 61425 61426 const StylesTab = ({ 61427 blockName, 61428 clientId, 61429 hasBlockStyles 61430 }) => { 61431 const borderPanelLabel = useBorderPanelLabel({ 61432 blockName 61433 }); 61434 return (0,external_React_.createElement)(external_React_.Fragment, null, hasBlockStyles && (0,external_React_.createElement)("div", null, (0,external_React_.createElement)(external_wp_components_namespaceObject.PanelBody, { 61435 title: (0,external_wp_i18n_namespaceObject.__)('Styles') 61436 }, (0,external_React_.createElement)(block_styles, { 61437 clientId: clientId 61438 }), (0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockName, 'defaultStylePicker', true) && (0,external_React_.createElement)(DefaultStylePicker, { 61439 blockName: blockName 61440 }))), (0,external_React_.createElement)(inspector_controls.Slot, { 61441 group: "color", 61442 label: (0,external_wp_i18n_namespaceObject.__)('Color'), 61443 className: "color-block-support-panel__inner-wrapper" 61444 }), (0,external_React_.createElement)(inspector_controls.Slot, { 61445 group: "background", 61446 label: (0,external_wp_i18n_namespaceObject.__)('Background') 61447 }), (0,external_React_.createElement)(inspector_controls.Slot, { 61448 group: "filter" 61449 }), (0,external_React_.createElement)(inspector_controls.Slot, { 61450 group: "typography", 61451 label: (0,external_wp_i18n_namespaceObject.__)('Typography') 61452 }), (0,external_React_.createElement)(inspector_controls.Slot, { 61453 group: "dimensions", 61454 label: (0,external_wp_i18n_namespaceObject.__)('Dimensions') 61455 }), (0,external_React_.createElement)(inspector_controls.Slot, { 61456 group: "border", 61457 label: borderPanelLabel 61458 }), (0,external_React_.createElement)(inspector_controls.Slot, { 61459 group: "styles" 61460 })); 61461 }; 61462 /* harmony default export */ const styles_tab = (StylesTab); 61463 61464 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls-tabs/use-is-list-view-tab-disabled.js 61465 // List view tab restricts the blocks that may render to it via the 61466 // allowlist below. 61467 const allowlist = ['core/navigation']; 61468 const useIsListViewTabDisabled = blockName => { 61469 return !allowlist.includes(blockName); 61470 }; 61471 /* harmony default export */ const use_is_list_view_tab_disabled = (useIsListViewTabDisabled); 61472 61473 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls-tabs/index.js 61474 61475 /** 61476 * WordPress dependencies 61477 */ 61478 61479 61480 /** 61481 * Internal dependencies 61482 */ 61483 61484 61485 61486 61487 61488 61489 const { 61490 Tabs: inspector_controls_tabs_Tabs 61491 } = unlock(external_wp_components_namespaceObject.privateApis); 61492 function InspectorControlsTabs({ 61493 blockName, 61494 clientId, 61495 hasBlockStyles, 61496 tabs 61497 }) { 61498 // The tabs panel will mount before fills are rendered to the list view 61499 // slot. This means the list view tab isn't initially included in the 61500 // available tabs so the panel defaults selection to the settings tab 61501 // which at the time is the first tab. This check allows blocks known to 61502 // include the list view tab to set it as the tab selected by default. 61503 const initialTabName = !use_is_list_view_tab_disabled(blockName) ? TAB_LIST_VIEW.name : undefined; 61504 return (0,external_React_.createElement)("div", { 61505 className: "block-editor-block-inspector__tabs" 61506 }, (0,external_React_.createElement)(inspector_controls_tabs_Tabs, { 61507 initialTabId: initialTabName, 61508 key: clientId 61509 }, (0,external_React_.createElement)(inspector_controls_tabs_Tabs.TabList, null, tabs.map(tab => (0,external_React_.createElement)(inspector_controls_tabs_Tabs.Tab, { 61510 key: tab.name, 61511 tabId: tab.name, 61512 render: (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 61513 icon: tab.icon, 61514 label: tab.title, 61515 className: tab.className 61516 }) 61517 }))), (0,external_React_.createElement)(inspector_controls_tabs_Tabs.TabPanel, { 61518 tabId: TAB_SETTINGS.name, 61519 focusable: false 61520 }, (0,external_React_.createElement)(settings_tab, { 61521 showAdvancedControls: !!blockName 61522 })), (0,external_React_.createElement)(inspector_controls_tabs_Tabs.TabPanel, { 61523 tabId: TAB_STYLES.name, 61524 focusable: false 61525 }, (0,external_React_.createElement)(styles_tab, { 61526 blockName: blockName, 61527 clientId: clientId, 61528 hasBlockStyles: hasBlockStyles 61529 })), (0,external_React_.createElement)(inspector_controls_tabs_Tabs.TabPanel, { 61530 tabId: TAB_LIST_VIEW.name, 61531 focusable: false 61532 }, (0,external_React_.createElement)(inspector_controls.Slot, { 61533 group: "list" 61534 })))); 61535 } 61536 61537 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls-tabs/use-inspector-controls-tabs.js 61538 /** 61539 * WordPress dependencies 61540 */ 61541 61542 61543 61544 /** 61545 * Internal dependencies 61546 */ 61547 61548 61549 61550 61551 61552 const use_inspector_controls_tabs_EMPTY_ARRAY = []; 61553 function getShowTabs(blockName, tabSettings = {}) { 61554 // Block specific setting takes precedence over generic default. 61555 if (tabSettings[blockName] !== undefined) { 61556 return tabSettings[blockName]; 61557 } 61558 61559 // Use generic default if set over the Gutenberg experiment option. 61560 if (tabSettings.default !== undefined) { 61561 return tabSettings.default; 61562 } 61563 return true; 61564 } 61565 function useInspectorControlsTabs(blockName) { 61566 const tabs = []; 61567 const { 61568 border: borderGroup, 61569 color: colorGroup, 61570 default: defaultGroup, 61571 dimensions: dimensionsGroup, 61572 list: listGroup, 61573 position: positionGroup, 61574 styles: stylesGroup, 61575 typography: typographyGroup, 61576 effects: effectsGroup 61577 } = inspector_controls_groups; 61578 61579 // List View Tab: If there are any fills for the list group add that tab. 61580 const listViewDisabled = use_is_list_view_tab_disabled(blockName); 61581 const listFills = (0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(listGroup.Slot.__unstableName); 61582 const hasListFills = !listViewDisabled && !!listFills && listFills.length; 61583 61584 // Styles Tab: Add this tab if there are any fills for block supports 61585 // e.g. border, color, spacing, typography, etc. 61586 const styleFills = [...((0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(borderGroup.Slot.__unstableName) || []), ...((0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(colorGroup.Slot.__unstableName) || []), ...((0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(dimensionsGroup.Slot.__unstableName) || []), ...((0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(stylesGroup.Slot.__unstableName) || []), ...((0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(typographyGroup.Slot.__unstableName) || []), ...((0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(effectsGroup.Slot.__unstableName) || [])]; 61587 const hasStyleFills = styleFills.length; 61588 61589 // Settings Tab: If we don't have multiple tabs to display 61590 // (i.e. both list view and styles), check only the default and position 61591 // InspectorControls slots. If we have multiple tabs, we'll need to check 61592 // the advanced controls slot as well to ensure they are rendered. 61593 const advancedFills = (0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(InspectorAdvancedControls.slotName) || []; 61594 const settingsFills = [...((0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(defaultGroup.Slot.__unstableName) || []), ...((0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(positionGroup.Slot.__unstableName) || []), ...(hasListFills && hasStyleFills > 1 ? advancedFills : [])]; 61595 61596 // Add the tabs in the order that they will default to if available. 61597 // List View > Settings > Styles. 61598 if (hasListFills) { 61599 tabs.push(TAB_LIST_VIEW); 61600 } 61601 if (settingsFills.length) { 61602 tabs.push(TAB_SETTINGS); 61603 } 61604 if (hasStyleFills) { 61605 tabs.push(TAB_STYLES); 61606 } 61607 const tabSettings = (0,external_wp_data_namespaceObject.useSelect)(select => { 61608 return select(store).getSettings().blockInspectorTabs; 61609 }, []); 61610 const showTabs = getShowTabs(blockName, tabSettings); 61611 return showTabs ? tabs : use_inspector_controls_tabs_EMPTY_ARRAY; 61612 } 61613 61614 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-inspector/useBlockInspectorAnimationSettings.js 61615 /** 61616 * WordPress dependencies 61617 */ 61618 61619 61620 /** 61621 * Internal dependencies 61622 */ 61623 61624 function useBlockInspectorAnimationSettings(blockType, selectedBlockClientId) { 61625 return (0,external_wp_data_namespaceObject.useSelect)(select => { 61626 if (blockType) { 61627 const globalBlockInspectorAnimationSettings = select(store).getSettings().blockInspectorAnimation; 61628 61629 // Get the name of the block that will allow it's children to be animated. 61630 const animationParent = globalBlockInspectorAnimationSettings?.animationParent; 61631 61632 // Determine whether the animationParent block is a parent of the selected block. 61633 const { 61634 getSelectedBlockClientId, 61635 getBlockParentsByBlockName 61636 } = select(store); 61637 const _selectedBlockClientId = getSelectedBlockClientId(); 61638 const animationParentBlockClientId = getBlockParentsByBlockName(_selectedBlockClientId, animationParent, true)[0]; 61639 61640 // If the selected block is not a child of the animationParent block, 61641 // and not an animationParent block itself, don't animate. 61642 if (!animationParentBlockClientId && blockType.name !== animationParent) { 61643 return null; 61644 } 61645 return globalBlockInspectorAnimationSettings?.[blockType.name]; 61646 } 61647 return null; 61648 }, [selectedBlockClientId, blockType]); 61649 } 61650 61651 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-info-slot-fill/index.js 61652 61653 /** 61654 * WordPress dependencies 61655 */ 61656 61657 61658 /** 61659 * Internal dependencies 61660 */ 61661 61662 61663 const { 61664 createPrivateSlotFill 61665 } = unlock(external_wp_components_namespaceObject.privateApis); 61666 const { 61667 Fill: block_info_slot_fill_Fill, 61668 Slot: block_info_slot_fill_Slot 61669 } = createPrivateSlotFill('BlockInformation'); 61670 const BlockInfo = props => { 61671 const context = useBlockEditContext(); 61672 if (!context[mayDisplayControlsKey]) { 61673 return null; 61674 } 61675 return (0,external_React_.createElement)(block_info_slot_fill_Fill, { 61676 ...props 61677 }); 61678 }; 61679 BlockInfo.Slot = props => (0,external_React_.createElement)(block_info_slot_fill_Slot, { 61680 ...props 61681 }); 61682 /* harmony default export */ const block_info_slot_fill = (BlockInfo); 61683 61684 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-quick-navigation/index.js 61685 61686 /** 61687 * WordPress dependencies 61688 */ 61689 61690 61691 61692 61693 /** 61694 * Internal dependencies 61695 */ 61696 61697 61698 function BlockQuickNavigation({ 61699 clientIds 61700 }) { 61701 if (!clientIds.length) { 61702 return null; 61703 } 61704 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalVStack, { 61705 spacing: 1 61706 }, clientIds.map(clientId => (0,external_React_.createElement)(BlockQuickNavigationItem, { 61707 key: clientId, 61708 clientId: clientId 61709 }))); 61710 } 61711 function BlockQuickNavigationItem({ 61712 clientId 61713 }) { 61714 const { 61715 name, 61716 icon, 61717 isSelected 61718 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 61719 const { 61720 getBlockName, 61721 getBlockAttributes, 61722 isBlockSelected, 61723 hasSelectedInnerBlock 61724 } = select(store); 61725 const { 61726 getBlockType 61727 } = select(external_wp_blocks_namespaceObject.store); 61728 const blockType = getBlockType(getBlockName(clientId)); 61729 const attributes = getBlockAttributes(clientId); 61730 return { 61731 name: blockType && (0,external_wp_blocks_namespaceObject.__experimentalGetBlockLabel)(blockType, attributes, 'list-view'), 61732 icon: blockType?.icon, 61733 isSelected: isBlockSelected(clientId) || hasSelectedInnerBlock(clientId, /* deep: */true) 61734 }; 61735 }, [clientId]); 61736 const { 61737 selectBlock 61738 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 61739 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 61740 isPressed: isSelected, 61741 onClick: () => selectBlock(clientId) 61742 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Flex, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexItem, null, (0,external_React_.createElement)(block_icon, { 61743 icon: icon 61744 })), (0,external_React_.createElement)(external_wp_components_namespaceObject.FlexBlock, { 61745 style: { 61746 textAlign: 'left' 61747 } 61748 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalTruncate, null, name)))); 61749 } 61750 61751 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-inspector/index.js 61752 61753 /** 61754 * WordPress dependencies 61755 */ 61756 61757 61758 61759 61760 61761 /** 61762 * Internal dependencies 61763 */ 61764 61765 61766 61767 61768 61769 61770 61771 61772 61773 61774 61775 61776 61777 61778 61779 61780 61781 function BlockInspectorLockedBlocks({ 61782 topLevelLockedBlock 61783 }) { 61784 const contentClientIds = (0,external_wp_data_namespaceObject.useSelect)(select => { 61785 const { 61786 getClientIdsOfDescendants, 61787 getBlockName, 61788 getBlockEditingMode 61789 } = select(store); 61790 return getClientIdsOfDescendants(topLevelLockedBlock).filter(clientId => getBlockName(clientId) !== 'core/list-item' && getBlockEditingMode(clientId) === 'contentOnly'); 61791 }, [topLevelLockedBlock]); 61792 const blockInformation = useBlockDisplayInformation(topLevelLockedBlock); 61793 return (0,external_React_.createElement)("div", { 61794 className: "block-editor-block-inspector" 61795 }, (0,external_React_.createElement)(block_card, { 61796 ...blockInformation, 61797 className: blockInformation.isSynced && 'is-synced' 61798 }), (0,external_React_.createElement)(block_variation_transforms, { 61799 blockClientId: topLevelLockedBlock 61800 }), (0,external_React_.createElement)(block_info_slot_fill.Slot, null), contentClientIds.length > 0 && (0,external_React_.createElement)(external_wp_components_namespaceObject.PanelBody, { 61801 title: (0,external_wp_i18n_namespaceObject.__)('Content') 61802 }, (0,external_React_.createElement)(BlockQuickNavigation, { 61803 clientIds: contentClientIds 61804 }))); 61805 } 61806 const BlockInspector = ({ 61807 showNoBlockSelectedMessage = true 61808 }) => { 61809 const { 61810 count, 61811 selectedBlockName, 61812 selectedBlockClientId, 61813 blockType, 61814 topLevelLockedBlock 61815 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 61816 const { 61817 getSelectedBlockClientId, 61818 getSelectedBlockCount, 61819 getBlockName, 61820 __unstableGetContentLockingParent, 61821 getTemplateLock 61822 } = select(store); 61823 const _selectedBlockClientId = getSelectedBlockClientId(); 61824 const _selectedBlockName = _selectedBlockClientId && getBlockName(_selectedBlockClientId); 61825 const _blockType = _selectedBlockName && (0,external_wp_blocks_namespaceObject.getBlockType)(_selectedBlockName); 61826 return { 61827 count: getSelectedBlockCount(), 61828 selectedBlockClientId: _selectedBlockClientId, 61829 selectedBlockName: _selectedBlockName, 61830 blockType: _blockType, 61831 topLevelLockedBlock: __unstableGetContentLockingParent(_selectedBlockClientId) || (getTemplateLock(_selectedBlockClientId) === 'contentOnly' || _selectedBlockName === 'core/block' ? _selectedBlockClientId : undefined) 61832 }; 61833 }, []); 61834 const availableTabs = useInspectorControlsTabs(blockType?.name); 61835 const showTabs = availableTabs?.length > 1; 61836 61837 // The block inspector animation settings will be completely 61838 // removed in the future to create an API which allows the block 61839 // inspector to transition between what it 61840 // displays based on the relationship between the selected block 61841 // and its parent, and only enable it if the parent is controlling 61842 // its children blocks. 61843 const blockInspectorAnimationSettings = useBlockInspectorAnimationSettings(blockType, selectedBlockClientId); 61844 const borderPanelLabel = useBorderPanelLabel({ 61845 blockName: selectedBlockName 61846 }); 61847 if (count > 1) { 61848 return (0,external_React_.createElement)("div", { 61849 className: "block-editor-block-inspector" 61850 }, (0,external_React_.createElement)(multi_selection_inspector, null), showTabs ? (0,external_React_.createElement)(InspectorControlsTabs, { 61851 tabs: availableTabs 61852 }) : (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(inspector_controls.Slot, null), (0,external_React_.createElement)(inspector_controls.Slot, { 61853 group: "color", 61854 label: (0,external_wp_i18n_namespaceObject.__)('Color'), 61855 className: "color-block-support-panel__inner-wrapper" 61856 }), (0,external_React_.createElement)(inspector_controls.Slot, { 61857 group: "typography", 61858 label: (0,external_wp_i18n_namespaceObject.__)('Typography') 61859 }), (0,external_React_.createElement)(inspector_controls.Slot, { 61860 group: "dimensions", 61861 label: (0,external_wp_i18n_namespaceObject.__)('Dimensions') 61862 }), (0,external_React_.createElement)(inspector_controls.Slot, { 61863 group: "border", 61864 label: borderPanelLabel 61865 }), (0,external_React_.createElement)(inspector_controls.Slot, { 61866 group: "styles" 61867 }))); 61868 } 61869 const isSelectedBlockUnregistered = selectedBlockName === (0,external_wp_blocks_namespaceObject.getUnregisteredTypeHandlerName)(); 61870 61871 /* 61872 * If the selected block is of an unregistered type, avoid showing it as an actual selection 61873 * because we want the user to focus on the unregistered block warning, not block settings. 61874 */ 61875 if (!blockType || !selectedBlockClientId || isSelectedBlockUnregistered) { 61876 if (showNoBlockSelectedMessage) { 61877 return (0,external_React_.createElement)("span", { 61878 className: "block-editor-block-inspector__no-blocks" 61879 }, (0,external_wp_i18n_namespaceObject.__)('No block selected.')); 61880 } 61881 return null; 61882 } 61883 if (topLevelLockedBlock) { 61884 return (0,external_React_.createElement)(BlockInspectorLockedBlocks, { 61885 topLevelLockedBlock: topLevelLockedBlock 61886 }); 61887 } 61888 return (0,external_React_.createElement)(BlockInspectorSingleBlockWrapper, { 61889 animate: blockInspectorAnimationSettings, 61890 wrapper: children => (0,external_React_.createElement)(AnimatedContainer, { 61891 blockInspectorAnimationSettings: blockInspectorAnimationSettings, 61892 selectedBlockClientId: selectedBlockClientId 61893 }, children) 61894 }, (0,external_React_.createElement)(BlockInspectorSingleBlock, { 61895 clientId: selectedBlockClientId, 61896 blockName: blockType.name 61897 })); 61898 }; 61899 const BlockInspectorSingleBlockWrapper = ({ 61900 animate, 61901 wrapper, 61902 children 61903 }) => { 61904 return animate ? wrapper(children) : children; 61905 }; 61906 const AnimatedContainer = ({ 61907 blockInspectorAnimationSettings, 61908 selectedBlockClientId, 61909 children 61910 }) => { 61911 const animationOrigin = blockInspectorAnimationSettings && blockInspectorAnimationSettings.enterDirection === 'leftToRight' ? -50 : 50; 61912 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__unstableMotion.div, { 61913 animate: { 61914 x: 0, 61915 opacity: 1, 61916 transition: { 61917 ease: 'easeInOut', 61918 duration: 0.14 61919 } 61920 }, 61921 initial: { 61922 x: animationOrigin, 61923 opacity: 0 61924 }, 61925 key: selectedBlockClientId 61926 }, children); 61927 }; 61928 const BlockInspectorSingleBlock = ({ 61929 clientId, 61930 blockName 61931 }) => { 61932 const availableTabs = useInspectorControlsTabs(blockName); 61933 const showTabs = availableTabs?.length > 1; 61934 const hasBlockStyles = (0,external_wp_data_namespaceObject.useSelect)(select => { 61935 const { 61936 getBlockStyles 61937 } = select(external_wp_blocks_namespaceObject.store); 61938 const blockStyles = getBlockStyles(blockName); 61939 return blockStyles && blockStyles.length > 0; 61940 }, [blockName]); 61941 const blockInformation = useBlockDisplayInformation(clientId); 61942 const borderPanelLabel = useBorderPanelLabel({ 61943 blockName 61944 }); 61945 return (0,external_React_.createElement)("div", { 61946 className: "block-editor-block-inspector" 61947 }, (0,external_React_.createElement)(block_card, { 61948 ...blockInformation, 61949 className: blockInformation.isSynced && 'is-synced' 61950 }), (0,external_React_.createElement)(block_variation_transforms, { 61951 blockClientId: clientId 61952 }), (0,external_React_.createElement)(block_info_slot_fill.Slot, null), showTabs && (0,external_React_.createElement)(InspectorControlsTabs, { 61953 hasBlockStyles: hasBlockStyles, 61954 clientId: clientId, 61955 blockName: blockName, 61956 tabs: availableTabs 61957 }), !showTabs && (0,external_React_.createElement)(external_React_.Fragment, null, hasBlockStyles && (0,external_React_.createElement)("div", null, (0,external_React_.createElement)(external_wp_components_namespaceObject.PanelBody, { 61958 title: (0,external_wp_i18n_namespaceObject.__)('Styles') 61959 }, (0,external_React_.createElement)(block_styles, { 61960 clientId: clientId 61961 }), (0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockName, 'defaultStylePicker', true) && (0,external_React_.createElement)(DefaultStylePicker, { 61962 blockName: blockName 61963 }))), (0,external_React_.createElement)(inspector_controls.Slot, null), (0,external_React_.createElement)(inspector_controls.Slot, { 61964 group: "list" 61965 }), (0,external_React_.createElement)(inspector_controls.Slot, { 61966 group: "color", 61967 label: (0,external_wp_i18n_namespaceObject.__)('Color'), 61968 className: "color-block-support-panel__inner-wrapper" 61969 }), (0,external_React_.createElement)(inspector_controls.Slot, { 61970 group: "typography", 61971 label: (0,external_wp_i18n_namespaceObject.__)('Typography') 61972 }), (0,external_React_.createElement)(inspector_controls.Slot, { 61973 group: "dimensions", 61974 label: (0,external_wp_i18n_namespaceObject.__)('Dimensions') 61975 }), (0,external_React_.createElement)(inspector_controls.Slot, { 61976 group: "border", 61977 label: borderPanelLabel 61978 }), (0,external_React_.createElement)(inspector_controls.Slot, { 61979 group: "styles" 61980 }), (0,external_React_.createElement)(inspector_controls.Slot, { 61981 group: "background", 61982 label: (0,external_wp_i18n_namespaceObject.__)('Background') 61983 }), (0,external_React_.createElement)(position_controls_panel, null), (0,external_React_.createElement)("div", null, (0,external_React_.createElement)(advanced_controls_panel, null))), (0,external_React_.createElement)(skip_to_selected_block, { 61984 key: "back" 61985 })); 61986 }; 61987 61988 /** 61989 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-inspector/README.md 61990 */ 61991 /* harmony default export */ const block_inspector = (BlockInspector); 61992 61993 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/copy-handler/index.js 61994 61995 /** 61996 * WordPress dependencies 61997 */ 61998 61999 62000 /** 62001 * Internal dependencies 62002 */ 62003 62004 62005 /** 62006 * @deprecated 62007 */ 62008 const __unstableUseClipboardHandler = () => { 62009 external_wp_deprecated_default()('__unstableUseClipboardHandler', { 62010 alternative: 'BlockCanvas or WritingFlow', 62011 since: '6.4', 62012 version: '6.7' 62013 }); 62014 return useClipboardHandler(); 62015 }; 62016 62017 /** 62018 * @deprecated 62019 * @param {Object} props 62020 */ 62021 function CopyHandler(props) { 62022 external_wp_deprecated_default()('CopyHandler', { 62023 alternative: 'BlockCanvas or WritingFlow', 62024 since: '6.4', 62025 version: '6.7' 62026 }); 62027 return (0,external_React_.createElement)("div", { 62028 ...props, 62029 ref: useClipboardHandler() 62030 }); 62031 } 62032 62033 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/library.js 62034 62035 /** 62036 * WordPress dependencies 62037 */ 62038 62039 62040 62041 /** 62042 * Internal dependencies 62043 */ 62044 62045 62046 const library_noop = () => {}; 62047 function InserterLibrary({ 62048 rootClientId, 62049 clientId, 62050 isAppender, 62051 showInserterHelpPanel, 62052 showMostUsedBlocks = false, 62053 __experimentalInsertionIndex, 62054 __experimentalFilterValue, 62055 onSelect = library_noop, 62056 shouldFocusBlock = false 62057 }, ref) { 62058 const { 62059 destinationRootClientId 62060 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 62061 const { 62062 getBlockRootClientId 62063 } = select(store); 62064 const _rootClientId = rootClientId || getBlockRootClientId(clientId) || undefined; 62065 return { 62066 destinationRootClientId: _rootClientId 62067 }; 62068 }, [clientId, rootClientId]); 62069 return (0,external_React_.createElement)(menu, { 62070 onSelect: onSelect, 62071 rootClientId: destinationRootClientId, 62072 clientId: clientId, 62073 isAppender: isAppender, 62074 showInserterHelpPanel: showInserterHelpPanel, 62075 showMostUsedBlocks: showMostUsedBlocks, 62076 __experimentalInsertionIndex: __experimentalInsertionIndex, 62077 __experimentalFilterValue: __experimentalFilterValue, 62078 shouldFocusBlock: shouldFocusBlock, 62079 ref: ref 62080 }); 62081 } 62082 /* harmony default export */ const library = ((0,external_wp_element_namespaceObject.forwardRef)(InserterLibrary)); 62083 62084 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/selection-scroll-into-view/index.js 62085 /** 62086 * WordPress dependencies 62087 */ 62088 62089 62090 /** 62091 * Scrolls the multi block selection end into view if not in view already. This 62092 * is important to do after selection by keyboard. 62093 * 62094 * @deprecated 62095 */ 62096 function MultiSelectScrollIntoView() { 62097 external_wp_deprecated_default()('wp.blockEditor.MultiSelectScrollIntoView', { 62098 hint: 'This behaviour is now built-in.', 62099 since: '5.8' 62100 }); 62101 return null; 62102 } 62103 62104 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/typewriter/index.js 62105 62106 /** 62107 * WordPress dependencies 62108 */ 62109 62110 62111 62112 62113 62114 /** 62115 * Internal dependencies 62116 */ 62117 62118 const isIE = window.navigator.userAgent.indexOf('Trident') !== -1; 62119 const arrowKeyCodes = new Set([external_wp_keycodes_namespaceObject.UP, external_wp_keycodes_namespaceObject.DOWN, external_wp_keycodes_namespaceObject.LEFT, external_wp_keycodes_namespaceObject.RIGHT]); 62120 const initialTriggerPercentage = 0.75; 62121 function useTypewriter() { 62122 const hasSelectedBlock = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).hasSelectedBlock(), []); 62123 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 62124 if (!hasSelectedBlock) { 62125 return; 62126 } 62127 const { 62128 ownerDocument 62129 } = node; 62130 const { 62131 defaultView 62132 } = ownerDocument; 62133 let scrollResizeRafId; 62134 let onKeyDownRafId; 62135 let caretRect; 62136 function onScrollResize() { 62137 if (scrollResizeRafId) { 62138 return; 62139 } 62140 scrollResizeRafId = defaultView.requestAnimationFrame(() => { 62141 computeCaretRectangle(); 62142 scrollResizeRafId = null; 62143 }); 62144 } 62145 function onKeyDown(event) { 62146 // Ensure the any remaining request is cancelled. 62147 if (onKeyDownRafId) { 62148 defaultView.cancelAnimationFrame(onKeyDownRafId); 62149 } 62150 62151 // Use an animation frame for a smooth result. 62152 onKeyDownRafId = defaultView.requestAnimationFrame(() => { 62153 maintainCaretPosition(event); 62154 onKeyDownRafId = null; 62155 }); 62156 } 62157 62158 /** 62159 * Maintains the scroll position after a selection change caused by a 62160 * keyboard event. 62161 * 62162 * @param {KeyboardEvent} event Keyboard event. 62163 */ 62164 function maintainCaretPosition({ 62165 keyCode 62166 }) { 62167 if (!isSelectionEligibleForScroll()) { 62168 return; 62169 } 62170 const currentCaretRect = (0,external_wp_dom_namespaceObject.computeCaretRect)(defaultView); 62171 if (!currentCaretRect) { 62172 return; 62173 } 62174 62175 // If for some reason there is no position set to be scrolled to, let 62176 // this be the position to be scrolled to in the future. 62177 if (!caretRect) { 62178 caretRect = currentCaretRect; 62179 return; 62180 } 62181 62182 // Even though enabling the typewriter effect for arrow keys results in 62183 // a pleasant experience, it may not be the case for everyone, so, for 62184 // now, let's disable it. 62185 if (arrowKeyCodes.has(keyCode)) { 62186 // Reset the caret position to maintain. 62187 caretRect = currentCaretRect; 62188 return; 62189 } 62190 const diff = currentCaretRect.top - caretRect.top; 62191 if (diff === 0) { 62192 return; 62193 } 62194 const scrollContainer = (0,external_wp_dom_namespaceObject.getScrollContainer)(node); 62195 62196 // The page must be scrollable. 62197 if (!scrollContainer) { 62198 return; 62199 } 62200 const windowScroll = scrollContainer === ownerDocument.body || scrollContainer === ownerDocument.documentElement; 62201 const scrollY = windowScroll ? defaultView.scrollY : scrollContainer.scrollTop; 62202 const scrollContainerY = windowScroll ? 0 : scrollContainer.getBoundingClientRect().top; 62203 const relativeScrollPosition = windowScroll ? caretRect.top / defaultView.innerHeight : (caretRect.top - scrollContainerY) / (defaultView.innerHeight - scrollContainerY); 62204 62205 // If the scroll position is at the start, the active editable element 62206 // is the last one, and the caret is positioned within the initial 62207 // trigger percentage of the page, do not scroll the page. 62208 // The typewriter effect should not kick in until an empty page has been 62209 // filled with the initial trigger percentage or the user scrolls 62210 // intentionally down. 62211 if (scrollY === 0 && relativeScrollPosition < initialTriggerPercentage && isLastEditableNode()) { 62212 // Reset the caret position to maintain. 62213 caretRect = currentCaretRect; 62214 return; 62215 } 62216 const scrollContainerHeight = windowScroll ? defaultView.innerHeight : scrollContainer.clientHeight; 62217 62218 // Abort if the target scroll position would scroll the caret out of 62219 // view. 62220 if ( 62221 // The caret is under the lower fold. 62222 caretRect.top + caretRect.height > scrollContainerY + scrollContainerHeight || 62223 // The caret is above the upper fold. 62224 caretRect.top < scrollContainerY) { 62225 // Reset the caret position to maintain. 62226 caretRect = currentCaretRect; 62227 return; 62228 } 62229 if (windowScroll) { 62230 defaultView.scrollBy(0, diff); 62231 } else { 62232 scrollContainer.scrollTop += diff; 62233 } 62234 } 62235 62236 /** 62237 * Adds a `selectionchange` listener to reset the scroll position to be 62238 * maintained. 62239 */ 62240 function addSelectionChangeListener() { 62241 ownerDocument.addEventListener('selectionchange', computeCaretRectOnSelectionChange); 62242 } 62243 62244 /** 62245 * Resets the scroll position to be maintained during a `selectionchange` 62246 * event. Also removes the listener, so it acts as a one-time listener. 62247 */ 62248 function computeCaretRectOnSelectionChange() { 62249 ownerDocument.removeEventListener('selectionchange', computeCaretRectOnSelectionChange); 62250 computeCaretRectangle(); 62251 } 62252 62253 /** 62254 * Resets the scroll position to be maintained. 62255 */ 62256 function computeCaretRectangle() { 62257 if (isSelectionEligibleForScroll()) { 62258 caretRect = (0,external_wp_dom_namespaceObject.computeCaretRect)(defaultView); 62259 } 62260 } 62261 62262 /** 62263 * Checks if the current situation is elegible for scroll: 62264 * - There should be one and only one block selected. 62265 * - The component must contain the selection. 62266 * - The active element must be contenteditable. 62267 */ 62268 function isSelectionEligibleForScroll() { 62269 return node.contains(ownerDocument.activeElement) && ownerDocument.activeElement.isContentEditable; 62270 } 62271 function isLastEditableNode() { 62272 const editableNodes = node.querySelectorAll('[contenteditable="true"]'); 62273 const lastEditableNode = editableNodes[editableNodes.length - 1]; 62274 return lastEditableNode === ownerDocument.activeElement; 62275 } 62276 62277 // When the user scrolls or resizes, the scroll position should be 62278 // reset. 62279 defaultView.addEventListener('scroll', onScrollResize, true); 62280 defaultView.addEventListener('resize', onScrollResize, true); 62281 node.addEventListener('keydown', onKeyDown); 62282 node.addEventListener('keyup', maintainCaretPosition); 62283 node.addEventListener('mousedown', addSelectionChangeListener); 62284 node.addEventListener('touchstart', addSelectionChangeListener); 62285 return () => { 62286 defaultView.removeEventListener('scroll', onScrollResize, true); 62287 defaultView.removeEventListener('resize', onScrollResize, true); 62288 node.removeEventListener('keydown', onKeyDown); 62289 node.removeEventListener('keyup', maintainCaretPosition); 62290 node.removeEventListener('mousedown', addSelectionChangeListener); 62291 node.removeEventListener('touchstart', addSelectionChangeListener); 62292 ownerDocument.removeEventListener('selectionchange', computeCaretRectOnSelectionChange); 62293 defaultView.cancelAnimationFrame(scrollResizeRafId); 62294 defaultView.cancelAnimationFrame(onKeyDownRafId); 62295 }; 62296 }, [hasSelectedBlock]); 62297 } 62298 function Typewriter({ 62299 children 62300 }) { 62301 return (0,external_React_.createElement)("div", { 62302 ref: useTypewriter(), 62303 className: "block-editor__typewriter" 62304 }, children); 62305 } 62306 62307 /** 62308 * The exported component. The implementation of Typewriter faced technical 62309 * challenges in Internet Explorer, and is simply skipped, rendering the given 62310 * props children instead. 62311 * 62312 * @type {Component} 62313 */ 62314 const TypewriterOrIEBypass = isIE ? props => props.children : Typewriter; 62315 62316 /** 62317 * Ensures that the text selection keeps the same vertical distance from the 62318 * viewport during keyboard events within this component. The vertical distance 62319 * can vary. It is the last clicked or scrolled to position. 62320 */ 62321 /* harmony default export */ const typewriter = (TypewriterOrIEBypass); 62322 62323 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/recursion-provider/index.js 62324 62325 /** 62326 * WordPress dependencies 62327 */ 62328 62329 62330 62331 /** 62332 * Internal dependencies 62333 */ 62334 62335 const RenderedRefsContext = (0,external_wp_element_namespaceObject.createContext)({}); 62336 62337 /** 62338 * Immutably adds an unique identifier to a set scoped for a given block type. 62339 * 62340 * @param {Object} renderedBlocks Rendered blocks grouped by block name 62341 * @param {string} blockName Name of the block. 62342 * @param {*} uniqueId Any value that acts as a unique identifier for a block instance. 62343 * 62344 * @return {Object} The list of rendered blocks grouped by block name. 62345 */ 62346 function addToBlockType(renderedBlocks, blockName, uniqueId) { 62347 const result = { 62348 ...renderedBlocks, 62349 [blockName]: renderedBlocks[blockName] ? new Set(renderedBlocks[blockName]) : new Set() 62350 }; 62351 result[blockName].add(uniqueId); 62352 return result; 62353 } 62354 62355 /** 62356 * A React context provider for use with the `useHasRecursion` hook to prevent recursive 62357 * renders. 62358 * 62359 * Wrap block content with this provider and provide the same `uniqueId` prop as used 62360 * with `useHasRecursion`. 62361 * 62362 * @param {Object} props 62363 * @param {*} props.uniqueId Any value that acts as a unique identifier for a block instance. 62364 * @param {string} props.blockName Optional block name. 62365 * @param {JSX.Element} props.children React children. 62366 * 62367 * @return {JSX.Element} A React element. 62368 */ 62369 function RecursionProvider({ 62370 children, 62371 uniqueId, 62372 blockName = '' 62373 }) { 62374 const previouslyRenderedBlocks = (0,external_wp_element_namespaceObject.useContext)(RenderedRefsContext); 62375 const { 62376 name 62377 } = useBlockEditContext(); 62378 blockName = blockName || name; 62379 const newRenderedBlocks = (0,external_wp_element_namespaceObject.useMemo)(() => addToBlockType(previouslyRenderedBlocks, blockName, uniqueId), [previouslyRenderedBlocks, blockName, uniqueId]); 62380 return (0,external_React_.createElement)(RenderedRefsContext.Provider, { 62381 value: newRenderedBlocks 62382 }, children); 62383 } 62384 62385 /** 62386 * A React hook for keeping track of blocks previously rendered up in the block 62387 * tree. Blocks susceptible to recursion can use this hook in their `Edit` 62388 * function to prevent said recursion. 62389 * 62390 * Use this with the `RecursionProvider` component, using the same `uniqueId` value 62391 * for both the hook and the provider. 62392 * 62393 * @param {*} uniqueId Any value that acts as a unique identifier for a block instance. 62394 * @param {string} blockName Optional block name. 62395 * 62396 * @return {boolean} A boolean describing whether the provided id has already been rendered. 62397 */ 62398 function useHasRecursion(uniqueId, blockName = '') { 62399 const previouslyRenderedBlocks = (0,external_wp_element_namespaceObject.useContext)(RenderedRefsContext); 62400 const { 62401 name 62402 } = useBlockEditContext(); 62403 blockName = blockName || name; 62404 return Boolean(previouslyRenderedBlocks[blockName]?.has(uniqueId)); 62405 } 62406 const DeprecatedExperimentalRecursionProvider = props => { 62407 external_wp_deprecated_default()('wp.blockEditor.__experimentalRecursionProvider', { 62408 since: '6.5', 62409 alternative: 'wp.blockEditor.RecursionProvider' 62410 }); 62411 return (0,external_React_.createElement)(RecursionProvider, { 62412 ...props 62413 }); 62414 }; 62415 const DeprecatedExperimentalUseHasRecursion = (...args) => { 62416 external_wp_deprecated_default()('wp.blockEditor.__experimentalUseHasRecursion', { 62417 since: '6.5', 62418 alternative: 'wp.blockEditor.useHasRecursion' 62419 }); 62420 return useHasRecursion(...args); 62421 }; 62422 62423 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/close-small.js 62424 62425 /** 62426 * WordPress dependencies 62427 */ 62428 62429 const closeSmall = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 62430 xmlns: "http://www.w3.org/2000/svg", 62431 viewBox: "0 0 24 24" 62432 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 62433 d: "M12 13.06l3.712 3.713 1.061-1.06L13.061 12l3.712-3.712-1.06-1.06L12 10.938 8.288 7.227l-1.061 1.06L10.939 12l-3.712 3.712 1.06 1.061L12 13.061z" 62434 })); 62435 /* harmony default export */ const close_small = (closeSmall); 62436 62437 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inspector-popover-header/index.js 62438 62439 /** 62440 * WordPress dependencies 62441 */ 62442 62443 62444 62445 function InspectorPopoverHeader({ 62446 title, 62447 help, 62448 actions = [], 62449 onClose 62450 }) { 62451 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalVStack, { 62452 className: "block-editor-inspector-popover-header", 62453 spacing: 4 62454 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, { 62455 alignment: "center" 62456 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHeading, { 62457 className: "block-editor-inspector-popover-header__heading", 62458 level: 2, 62459 size: 13 62460 }, title), (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalSpacer, null), actions.map(({ 62461 label, 62462 icon, 62463 onClick 62464 }) => (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 62465 key: label, 62466 className: "block-editor-inspector-popover-header__action", 62467 label: label, 62468 icon: icon, 62469 variant: !icon && 'tertiary', 62470 onClick: onClick 62471 }, !icon && label)), onClose && (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 62472 className: "block-editor-inspector-popover-header__action", 62473 label: (0,external_wp_i18n_namespaceObject.__)('Close'), 62474 icon: close_small, 62475 onClick: onClose 62476 })), help && (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalText, null, help)); 62477 } 62478 62479 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/publish-date-time-picker/index.js 62480 62481 /** 62482 * WordPress dependencies 62483 */ 62484 62485 62486 62487 62488 62489 /** 62490 * Internal dependencies 62491 */ 62492 62493 function PublishDateTimePicker({ 62494 onClose, 62495 onChange, 62496 ...additionalProps 62497 }, ref) { 62498 return (0,external_React_.createElement)("div", { 62499 ref: ref, 62500 className: "block-editor-publish-date-time-picker" 62501 }, (0,external_React_.createElement)(InspectorPopoverHeader, { 62502 title: (0,external_wp_i18n_namespaceObject.__)('Publish'), 62503 actions: [{ 62504 label: (0,external_wp_i18n_namespaceObject.__)('Now'), 62505 onClick: () => onChange?.(null) 62506 }], 62507 onClose: onClose 62508 }), (0,external_React_.createElement)(external_wp_components_namespaceObject.DateTimePicker, { 62509 startOfWeek: (0,external_wp_date_namespaceObject.getSettings)().l10n.startOfWeek, 62510 onChange: onChange, 62511 ...additionalProps 62512 })); 62513 } 62514 /* harmony default export */ const publish_date_time_picker = ((0,external_wp_element_namespaceObject.forwardRef)(PublishDateTimePicker)); 62515 62516 ;// CONCATENATED MODULE: external ["wp","commands"] 62517 const external_wp_commands_namespaceObject = window["wp"]["commands"]; 62518 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/move-to.js 62519 62520 /** 62521 * WordPress dependencies 62522 */ 62523 62524 const move_to_moveTo = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 62525 xmlns: "http://www.w3.org/2000/svg", 62526 viewBox: "0 0 24 24" 62527 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 62528 d: "M19.75 9c0-1.257-.565-2.197-1.39-2.858-.797-.64-1.827-1.017-2.815-1.247-1.802-.42-3.703-.403-4.383-.396L11 4.5V6l.177-.001c.696-.006 2.416-.02 4.028.356.887.207 1.67.518 2.216.957.52.416.829.945.829 1.688 0 .592-.167.966-.407 1.23-.255.281-.656.508-1.236.674-1.19.34-2.82.346-4.607.346h-.077c-1.692 0-3.527 0-4.942.404-.732.209-1.424.545-1.935 1.108-.526.579-.796 1.33-.796 2.238 0 1.257.565 2.197 1.39 2.858.797.64 1.827 1.017 2.815 1.247 1.802.42 3.703.403 4.383.396L13 19.5h.714V22L18 18.5 13.714 15v3H13l-.177.001c-.696.006-2.416.02-4.028-.356-.887-.207-1.67-.518-2.216-.957-.52-.416-.829-.945-.829-1.688 0-.592.167-.966.407-1.23.255-.281.656-.508 1.237-.674 1.189-.34 2.819-.346 4.606-.346h.077c1.692 0 3.527 0 4.941-.404.732-.209 1.425-.545 1.936-1.108.526-.579.796-1.33.796-2.238z" 62529 })); 62530 /* harmony default export */ const move_to = (move_to_moveTo); 62531 62532 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/ungroup.js 62533 62534 /** 62535 * WordPress dependencies 62536 */ 62537 62538 const ungroup = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 62539 xmlns: "http://www.w3.org/2000/svg", 62540 viewBox: "0 0 24 24" 62541 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 62542 d: "M18 4h-7c-1.1 0-2 .9-2 2v7c0 1.1.9 2 2 2h7c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm.5 9c0 .3-.2.5-.5.5h-7c-.3 0-.5-.2-.5-.5V6c0-.3.2-.5.5-.5h7c.3 0 .5.2.5.5v7zm-5 5c0 .3-.2.5-.5.5H6c-.3 0-.5-.2-.5-.5v-7c0-.3.2-.5.5-.5h1V9H6c-1.1 0-2 .9-2 2v7c0 1.1.9 2 2 2h7c1.1 0 2-.9 2-2v-1h-1.5v1z" 62543 })); 62544 /* harmony default export */ const library_ungroup = (ungroup); 62545 62546 ;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/trash.js 62547 62548 /** 62549 * WordPress dependencies 62550 */ 62551 62552 const trash = (0,external_React_.createElement)(external_wp_primitives_namespaceObject.SVG, { 62553 xmlns: "http://www.w3.org/2000/svg", 62554 viewBox: "0 0 24 24" 62555 }, (0,external_React_.createElement)(external_wp_primitives_namespaceObject.Path, { 62556 fillRule: "evenodd", 62557 clipRule: "evenodd", 62558 d: "M12 5.5A2.25 2.25 0 0 0 9.878 7h4.244A2.251 2.251 0 0 0 12 5.5ZM12 4a3.751 3.751 0 0 0-3.675 3H5v1.5h1.27l.818 8.997a2.75 2.75 0 0 0 2.739 2.501h4.347a2.75 2.75 0 0 0 2.738-2.5L17.73 8.5H19V7h-3.325A3.751 3.751 0 0 0 12 4Zm4.224 4.5H7.776l.806 8.861a1.25 1.25 0 0 0 1.245 1.137h4.347a1.25 1.25 0 0 0 1.245-1.137l.805-8.861Z" 62559 })); 62560 /* harmony default export */ const library_trash = (trash); 62561 62562 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/use-block-commands/index.js 62563 62564 /** 62565 * WordPress dependencies 62566 */ 62567 62568 62569 62570 62571 62572 62573 /** 62574 * Internal dependencies 62575 */ 62576 62577 62578 const useTransformCommands = () => { 62579 const { 62580 replaceBlocks, 62581 multiSelect 62582 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 62583 const { 62584 blocks, 62585 clientIds, 62586 canRemove, 62587 possibleBlockTransformations 62588 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 62589 const { 62590 getBlockRootClientId, 62591 getBlockTransformItems, 62592 getSelectedBlockClientIds, 62593 getBlocksByClientId, 62594 canRemoveBlocks 62595 } = select(store); 62596 const selectedBlockClientIds = getSelectedBlockClientIds(); 62597 const selectedBlocks = getBlocksByClientId(selectedBlockClientIds); 62598 const rootClientId = getBlockRootClientId(selectedBlockClientIds[0]); 62599 return { 62600 blocks: selectedBlocks, 62601 clientIds: selectedBlockClientIds, 62602 possibleBlockTransformations: getBlockTransformItems(selectedBlocks, rootClientId), 62603 canRemove: canRemoveBlocks(selectedBlockClientIds, rootClientId) 62604 }; 62605 }, []); 62606 const isTemplate = blocks.length === 1 && (0,external_wp_blocks_namespaceObject.isTemplatePart)(blocks[0]); 62607 function selectForMultipleBlocks(insertedBlocks) { 62608 if (insertedBlocks.length > 1) { 62609 multiSelect(insertedBlocks[0].clientId, insertedBlocks[insertedBlocks.length - 1].clientId); 62610 } 62611 } 62612 62613 // Simple block tranformation based on the `Block Transforms` API. 62614 function onBlockTransform(name) { 62615 const newBlocks = (0,external_wp_blocks_namespaceObject.switchToBlockType)(blocks, name); 62616 replaceBlocks(clientIds, newBlocks); 62617 selectForMultipleBlocks(newBlocks); 62618 } 62619 62620 /** 62621 * The `isTemplate` check is a stopgap solution here. 62622 * Ideally, the Transforms API should handle this 62623 * by allowing to exclude blocks from wildcard transformations. 62624 */ 62625 const hasPossibleBlockTransformations = !!possibleBlockTransformations.length && canRemove && !isTemplate; 62626 if (!clientIds || clientIds.length < 1 || !hasPossibleBlockTransformations) { 62627 return { 62628 isLoading: false, 62629 commands: [] 62630 }; 62631 } 62632 const commands = possibleBlockTransformations.map(transformation => { 62633 const { 62634 name, 62635 title, 62636 icon 62637 } = transformation; 62638 return { 62639 name: 'core/block-editor/transform-to-' + name.replace('/', '-'), 62640 // translators: %s: block title/name. 62641 label: (0,external_wp_i18n_namespaceObject.sprintf)((0,external_wp_i18n_namespaceObject.__)('Transform to %s'), title), 62642 icon: (0,external_React_.createElement)(block_icon, { 62643 icon: icon 62644 }), 62645 callback: ({ 62646 close 62647 }) => { 62648 onBlockTransform(name); 62649 close(); 62650 } 62651 }; 62652 }); 62653 return { 62654 isLoading: false, 62655 commands 62656 }; 62657 }; 62658 const useActionsCommands = () => { 62659 const { 62660 clientIds 62661 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 62662 const { 62663 getSelectedBlockClientIds 62664 } = select(store); 62665 const selectedBlockClientIds = getSelectedBlockClientIds(); 62666 return { 62667 clientIds: selectedBlockClientIds 62668 }; 62669 }, []); 62670 const { 62671 getBlockRootClientId, 62672 canMoveBlocks, 62673 getBlockCount 62674 } = (0,external_wp_data_namespaceObject.useSelect)(store); 62675 const { 62676 setBlockMovingClientId, 62677 setNavigationMode, 62678 selectBlock 62679 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 62680 if (!clientIds || clientIds.length < 1) { 62681 return { 62682 isLoading: false, 62683 commands: [] 62684 }; 62685 } 62686 const rootClientId = getBlockRootClientId(clientIds[0]); 62687 const canMove = canMoveBlocks(clientIds, rootClientId) && getBlockCount(rootClientId) !== 1; 62688 const commands = []; 62689 if (canMove) { 62690 commands.push({ 62691 name: 'move-to', 62692 label: (0,external_wp_i18n_namespaceObject.__)('Move to'), 62693 callback: () => { 62694 setNavigationMode(true); 62695 selectBlock(clientIds[0]); 62696 setBlockMovingClientId(clientIds[0]); 62697 }, 62698 icon: move_to 62699 }); 62700 } 62701 return { 62702 isLoading: false, 62703 commands: commands.map(command => ({ 62704 ...command, 62705 name: 'core/block-editor/action-' + command.name, 62706 callback: ({ 62707 close 62708 }) => { 62709 command.callback(); 62710 close(); 62711 } 62712 })) 62713 }; 62714 }; 62715 const useQuickActionsCommands = () => { 62716 const { 62717 clientIds, 62718 isUngroupable, 62719 isGroupable 62720 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 62721 const { 62722 getSelectedBlockClientIds, 62723 isUngroupable: _isUngroupable, 62724 isGroupable: _isGroupable 62725 } = select(store); 62726 const selectedBlockClientIds = getSelectedBlockClientIds(); 62727 return { 62728 clientIds: selectedBlockClientIds, 62729 isUngroupable: _isUngroupable(), 62730 isGroupable: _isGroupable() 62731 }; 62732 }, []); 62733 const { 62734 canInsertBlockType, 62735 getBlockRootClientId, 62736 getBlocksByClientId, 62737 canRemoveBlocks 62738 } = (0,external_wp_data_namespaceObject.useSelect)(store); 62739 const { 62740 getDefaultBlockName, 62741 getGroupingBlockName 62742 } = (0,external_wp_data_namespaceObject.useSelect)(external_wp_blocks_namespaceObject.store); 62743 const blocks = getBlocksByClientId(clientIds); 62744 const { 62745 removeBlocks, 62746 replaceBlocks, 62747 duplicateBlocks, 62748 insertAfterBlock, 62749 insertBeforeBlock 62750 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 62751 const onGroup = () => { 62752 if (!blocks.length) { 62753 return; 62754 } 62755 const groupingBlockName = getGroupingBlockName(); 62756 62757 // Activate the `transform` on `core/group` which does the conversion. 62758 const newBlocks = (0,external_wp_blocks_namespaceObject.switchToBlockType)(blocks, groupingBlockName); 62759 if (!newBlocks) { 62760 return; 62761 } 62762 replaceBlocks(clientIds, newBlocks); 62763 }; 62764 const onUngroup = () => { 62765 if (!blocks.length) { 62766 return; 62767 } 62768 const innerBlocks = blocks[0].innerBlocks; 62769 if (!innerBlocks.length) { 62770 return; 62771 } 62772 replaceBlocks(clientIds, innerBlocks); 62773 }; 62774 if (!clientIds || clientIds.length < 1) { 62775 return { 62776 isLoading: false, 62777 commands: [] 62778 }; 62779 } 62780 const rootClientId = getBlockRootClientId(clientIds[0]); 62781 const canInsertDefaultBlock = canInsertBlockType(getDefaultBlockName(), rootClientId); 62782 const canDuplicate = blocks.every(block => { 62783 return !!block && (0,external_wp_blocks_namespaceObject.hasBlockSupport)(block.name, 'multiple', true) && canInsertBlockType(block.name, rootClientId); 62784 }); 62785 const canRemove = canRemoveBlocks(clientIds, rootClientId); 62786 const commands = []; 62787 if (canDuplicate) { 62788 commands.push({ 62789 name: 'duplicate', 62790 label: (0,external_wp_i18n_namespaceObject.__)('Duplicate'), 62791 callback: () => duplicateBlocks(clientIds, true), 62792 icon: library_copy 62793 }); 62794 } 62795 if (canInsertDefaultBlock) { 62796 commands.push({ 62797 name: 'add-before', 62798 label: (0,external_wp_i18n_namespaceObject.__)('Add before'), 62799 callback: () => { 62800 const clientId = Array.isArray(clientIds) ? clientIds[0] : clientId; 62801 insertBeforeBlock(clientId); 62802 }, 62803 icon: library_plus 62804 }, { 62805 name: 'add-after', 62806 label: (0,external_wp_i18n_namespaceObject.__)('Add after'), 62807 callback: () => { 62808 const clientId = Array.isArray(clientIds) ? clientIds[clientIds.length - 1] : clientId; 62809 insertAfterBlock(clientId); 62810 }, 62811 icon: library_plus 62812 }); 62813 } 62814 if (isGroupable) { 62815 commands.push({ 62816 name: 'Group', 62817 label: (0,external_wp_i18n_namespaceObject.__)('Group'), 62818 callback: onGroup, 62819 icon: library_group 62820 }); 62821 } 62822 if (isUngroupable) { 62823 commands.push({ 62824 name: 'ungroup', 62825 label: (0,external_wp_i18n_namespaceObject.__)('Ungroup'), 62826 callback: onUngroup, 62827 icon: library_ungroup 62828 }); 62829 } 62830 if (canRemove) { 62831 commands.push({ 62832 name: 'remove', 62833 label: (0,external_wp_i18n_namespaceObject.__)('Delete'), 62834 callback: () => removeBlocks(clientIds, true), 62835 icon: library_trash 62836 }); 62837 } 62838 return { 62839 isLoading: false, 62840 commands: commands.map(command => ({ 62841 ...command, 62842 name: 'core/block-editor/action-' + command.name, 62843 callback: ({ 62844 close 62845 }) => { 62846 command.callback(); 62847 close(); 62848 } 62849 })) 62850 }; 62851 }; 62852 const useBlockCommands = () => { 62853 (0,external_wp_commands_namespaceObject.useCommandLoader)({ 62854 name: 'core/block-editor/blockTransforms', 62855 hook: useTransformCommands 62856 }); 62857 (0,external_wp_commands_namespaceObject.useCommandLoader)({ 62858 name: 'core/block-editor/blockActions', 62859 hook: useActionsCommands 62860 }); 62861 (0,external_wp_commands_namespaceObject.useCommandLoader)({ 62862 name: 'core/block-editor/blockQuickActions', 62863 hook: useQuickActionsCommands, 62864 context: 'block-selection-edit' 62865 }); 62866 }; 62867 62868 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/reusable-block-rename-hint.js 62869 62870 /** 62871 * WordPress dependencies 62872 */ 62873 62874 62875 62876 62877 62878 62879 62880 const reusable_block_rename_hint_PREFERENCE_NAME = 'isResuableBlocksrRenameHintVisible'; 62881 /* 62882 * This hook was added in 6.3 to help users with the transition from Reusable blocks to Patterns. 62883 * It is only exported for use in the reusable-blocks package as well as block-editor. 62884 * It will be removed in 6.4. and should not be used in any new code. 62885 */ 62886 function useReusableBlocksRenameHint() { 62887 return (0,external_wp_data_namespaceObject.useSelect)(select => { 62888 var _select$get; 62889 return (_select$get = select(external_wp_preferences_namespaceObject.store).get('core', reusable_block_rename_hint_PREFERENCE_NAME)) !== null && _select$get !== void 0 ? _select$get : true; 62890 }, []); 62891 } 62892 62893 /* 62894 * This component was added in 6.3 to help users with the transition from Reusable blocks to Patterns. 62895 * It is only exported for use in the reusable-blocks package as well as block-editor. 62896 * It will be removed in 6.4. and should not be used in any new code. 62897 */ 62898 function ReusableBlocksRenameHint() { 62899 const isReusableBlocksRenameHint = (0,external_wp_data_namespaceObject.useSelect)(select => { 62900 var _select$get2; 62901 return (_select$get2 = select(external_wp_preferences_namespaceObject.store).get('core', reusable_block_rename_hint_PREFERENCE_NAME)) !== null && _select$get2 !== void 0 ? _select$get2 : true; 62902 }, []); 62903 const ref = (0,external_wp_element_namespaceObject.useRef)(); 62904 const { 62905 set: setPreference 62906 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_preferences_namespaceObject.store); 62907 if (!isReusableBlocksRenameHint) { 62908 return null; 62909 } 62910 return (0,external_React_.createElement)("div", { 62911 ref: ref, 62912 className: "reusable-blocks-menu-items__rename-hint" 62913 }, (0,external_React_.createElement)("div", { 62914 className: "reusable-blocks-menu-items__rename-hint-content" 62915 }, (0,external_wp_i18n_namespaceObject.__)('Reusable blocks are now synced patterns. A synced pattern will behave in exactly the same way as a reusable block.')), (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 62916 className: "reusable-blocks-menu-items__rename-hint-dismiss", 62917 icon: library_close, 62918 iconSize: "16", 62919 label: (0,external_wp_i18n_namespaceObject.__)('Dismiss hint'), 62920 onClick: () => { 62921 // Retain focus when dismissing the element. 62922 const previousElement = external_wp_dom_namespaceObject.focus.tabbable.findPrevious(ref.current); 62923 previousElement?.focus(); 62924 setPreference('core', reusable_block_rename_hint_PREFERENCE_NAME, false); 62925 }, 62926 showTooltip: false 62927 })); 62928 } 62929 62930 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/index.js 62931 /* 62932 * Block Creation Components 62933 */ 62934 62935 62936 62937 62938 62939 62940 62941 62942 62943 62944 62945 62946 62947 62948 62949 62950 62951 62952 62953 62954 62955 62956 62957 62958 62959 62960 62961 62962 62963 62964 62965 62966 62967 62968 62969 62970 62971 62972 62973 62974 62975 62976 62977 62978 62979 62980 62981 62982 62983 62984 62985 62986 62987 62988 62989 62990 62991 62992 62993 62994 62995 62996 62997 62998 62999 63000 63001 63002 63003 63004 /* 63005 * Content Related Components 63006 */ 63007 63008 63009 63010 63011 63012 63013 63014 63015 63016 63017 63018 63019 63020 63021 63022 63023 63024 63025 63026 63027 63028 63029 63030 63031 63032 63033 63034 63035 63036 63037 63038 63039 63040 63041 63042 63043 63044 63045 63046 /* 63047 * State Related Components 63048 */ 63049 63050 63051 63052 63053 63054 /* 63055 * The following rename hint component can be removed in 6.4. 63056 */ 63057 63058 63059 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/elements/index.js 63060 const ELEMENT_CLASS_NAMES = { 63061 button: 'wp-element-button', 63062 caption: 'wp-element-caption' 63063 }; 63064 const __experimentalGetElementClassName = element => { 63065 return ELEMENT_CLASS_NAMES[element] ? ELEMENT_CLASS_NAMES[element] : ''; 63066 }; 63067 63068 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/get-px-from-css-unit.js 63069 /** 63070 * This function was accidentially exposed for mobile/native usage. 63071 * 63072 * @deprecated 63073 * 63074 * @return {string} Empty string. 63075 */ 63076 /* harmony default export */ const get_px_from_css_unit = (() => ''); 63077 63078 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/index.js 63079 63080 63081 63082 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/global-styles/use-global-styles-output.js 63083 /** 63084 * WordPress dependencies 63085 */ 63086 63087 63088 63089 63090 63091 63092 /** 63093 * Internal dependencies 63094 */ 63095 63096 63097 63098 63099 63100 63101 63102 63103 63104 63105 63106 63107 63108 // List of block support features that can have their related styles 63109 // generated under their own feature level selector rather than the block's. 63110 const BLOCK_SUPPORT_FEATURE_LEVEL_SELECTORS = { 63111 __experimentalBorder: 'border', 63112 color: 'color', 63113 spacing: 'spacing', 63114 typography: 'typography' 63115 }; 63116 function compileStyleValue(uncompiledValue) { 63117 const VARIABLE_REFERENCE_PREFIX = 'var:'; 63118 const VARIABLE_PATH_SEPARATOR_TOKEN_ATTRIBUTE = '|'; 63119 const VARIABLE_PATH_SEPARATOR_TOKEN_STYLE = '--'; 63120 if (uncompiledValue?.startsWith?.(VARIABLE_REFERENCE_PREFIX)) { 63121 const variable = uncompiledValue.slice(VARIABLE_REFERENCE_PREFIX.length).split(VARIABLE_PATH_SEPARATOR_TOKEN_ATTRIBUTE).join(VARIABLE_PATH_SEPARATOR_TOKEN_STYLE); 63122 return `var(--wp--$variable})`; 63123 } 63124 return uncompiledValue; 63125 } 63126 63127 /** 63128 * Transform given preset tree into a set of style declarations. 63129 * 63130 * @param {Object} blockPresets 63131 * @param {Object} mergedSettings Merged theme.json settings. 63132 * 63133 * @return {Array<Object>} An array of style declarations. 63134 */ 63135 function getPresetsDeclarations(blockPresets = {}, mergedSettings) { 63136 const { 63137 kebabCase 63138 } = unlock(external_wp_components_namespaceObject.privateApis); 63139 return PRESET_METADATA.reduce((declarations, { 63140 path, 63141 valueKey, 63142 valueFunc, 63143 cssVarInfix 63144 }) => { 63145 const presetByOrigin = getValueFromObjectPath(blockPresets, path, []); 63146 ['default', 'theme', 'custom'].forEach(origin => { 63147 if (presetByOrigin[origin]) { 63148 presetByOrigin[origin].forEach(value => { 63149 if (valueKey && !valueFunc) { 63150 declarations.push(`--wp--preset--$cssVarInfix}--$kebabCase(value.slug)}: $value[valueKey]}`); 63151 } else if (valueFunc && typeof valueFunc === 'function') { 63152 declarations.push(`--wp--preset--$cssVarInfix}--$kebabCase(value.slug)}: $valueFunc(value, mergedSettings)}`); 63153 } 63154 }); 63155 } 63156 }); 63157 return declarations; 63158 }, []); 63159 } 63160 63161 /** 63162 * Transform given preset tree into a set of preset class declarations. 63163 * 63164 * @param {?string} blockSelector 63165 * @param {Object} blockPresets 63166 * @return {string} CSS declarations for the preset classes. 63167 */ 63168 function getPresetsClasses(blockSelector = '*', blockPresets = {}) { 63169 const { 63170 kebabCase 63171 } = unlock(external_wp_components_namespaceObject.privateApis); 63172 return PRESET_METADATA.reduce((declarations, { 63173 path, 63174 cssVarInfix, 63175 classes 63176 }) => { 63177 if (!classes) { 63178 return declarations; 63179 } 63180 const presetByOrigin = getValueFromObjectPath(blockPresets, path, []); 63181 ['default', 'theme', 'custom'].forEach(origin => { 63182 if (presetByOrigin[origin]) { 63183 presetByOrigin[origin].forEach(({ 63184 slug 63185 }) => { 63186 classes.forEach(({ 63187 classSuffix, 63188 propertyName 63189 }) => { 63190 const classSelectorToUse = `.has-$kebabCase(slug)}-$classSuffix}`; 63191 const selectorToUse = blockSelector.split(',') // Selector can be "h1, h2, h3" 63192 .map(selector => `$selector}$classSelectorToUse}`).join(','); 63193 const value = `var(--wp--preset--$cssVarInfix}--$kebabCase(slug)})`; 63194 declarations += `$selectorToUse}{$propertyName}: $value} !important;}`; 63195 }); 63196 }); 63197 } 63198 }); 63199 return declarations; 63200 }, ''); 63201 } 63202 function getPresetsSvgFilters(blockPresets = {}) { 63203 return PRESET_METADATA.filter( 63204 // Duotone are the only type of filters for now. 63205 metadata => metadata.path.at(-1) === 'duotone').flatMap(metadata => { 63206 const presetByOrigin = getValueFromObjectPath(blockPresets, metadata.path, {}); 63207 return ['default', 'theme'].filter(origin => presetByOrigin[origin]).flatMap(origin => presetByOrigin[origin].map(preset => getDuotoneFilter(`wp-duotone-$preset.slug}`, preset.colors))).join(''); 63208 }); 63209 } 63210 function flattenTree(input = {}, prefix, token) { 63211 const { 63212 kebabCase 63213 } = unlock(external_wp_components_namespaceObject.privateApis); 63214 let result = []; 63215 Object.keys(input).forEach(key => { 63216 const newKey = prefix + kebabCase(key.replace('/', '-')); 63217 const newLeaf = input[key]; 63218 if (newLeaf instanceof Object) { 63219 const newPrefix = newKey + token; 63220 result = [...result, ...flattenTree(newLeaf, newPrefix, token)]; 63221 } else { 63222 result.push(`$newKey}: $newLeaf}`); 63223 } 63224 }); 63225 return result; 63226 } 63227 63228 /** 63229 * Gets variation selector string from feature selector. 63230 * 63231 * @param {string} featureSelector The feature selector. 63232 * 63233 * @param {string} styleVariationSelector The style variation selector. 63234 * @return {string} Combined selector string. 63235 */ 63236 function concatFeatureVariationSelectorString(featureSelector, styleVariationSelector) { 63237 const featureSelectors = featureSelector.split(','); 63238 const combinedSelectors = []; 63239 featureSelectors.forEach(selector => { 63240 combinedSelectors.push(`$styleVariationSelector.trim()}$selector.trim()}`); 63241 }); 63242 return combinedSelectors.join(', '); 63243 } 63244 63245 /** 63246 * Generate style declarations for a block's custom feature and subfeature 63247 * selectors. 63248 * 63249 * NOTE: The passed `styles` object will be mutated by this function. 63250 * 63251 * @param {Object} selectors Custom selectors object for a block. 63252 * @param {Object} styles A block's styles object. 63253 * 63254 * @return {Object} Style declarations. 63255 */ 63256 const getFeatureDeclarations = (selectors, styles) => { 63257 const declarations = {}; 63258 Object.entries(selectors).forEach(([feature, selector]) => { 63259 // We're only processing features/subfeatures that have styles. 63260 if (feature === 'root' || !styles?.[feature]) { 63261 return; 63262 } 63263 const isShorthand = typeof selector === 'string'; 63264 63265 // If we have a selector object instead of shorthand process it. 63266 if (!isShorthand) { 63267 Object.entries(selector).forEach(([subfeature, subfeatureSelector]) => { 63268 // Don't process root feature selector yet or any 63269 // subfeature that doesn't have a style. 63270 if (subfeature === 'root' || !styles?.[feature][subfeature]) { 63271 return; 63272 } 63273 63274 // Create a temporary styles object and build 63275 // declarations for subfeature. 63276 const subfeatureStyles = { 63277 [feature]: { 63278 [subfeature]: styles[feature][subfeature] 63279 } 63280 }; 63281 const newDeclarations = getStylesDeclarations(subfeatureStyles); 63282 63283 // Merge new declarations in with any others that 63284 // share the same selector. 63285 declarations[subfeatureSelector] = [...(declarations[subfeatureSelector] || []), ...newDeclarations]; 63286 63287 // Remove the subfeature's style now it will be 63288 // included under its own selector not the block's. 63289 delete styles[feature][subfeature]; 63290 }); 63291 } 63292 63293 // Now subfeatures have been processed and removed, we can 63294 // process root, or shorthand, feature selectors. 63295 if (isShorthand || selector.root) { 63296 const featureSelector = isShorthand ? selector : selector.root; 63297 63298 // Create temporary style object and build declarations for feature. 63299 const featureStyles = { 63300 [feature]: styles[feature] 63301 }; 63302 const newDeclarations = getStylesDeclarations(featureStyles); 63303 63304 // Merge new declarations with any others that share the selector. 63305 declarations[featureSelector] = [...(declarations[featureSelector] || []), ...newDeclarations]; 63306 63307 // Remove the feature from the block's styles now as it will be 63308 // included under its own selector not the block's. 63309 delete styles[feature]; 63310 } 63311 }); 63312 return declarations; 63313 }; 63314 63315 /** 63316 * Transform given style tree into a set of style declarations. 63317 * 63318 * @param {Object} blockStyles Block styles. 63319 * 63320 * @param {string} selector The selector these declarations should attach to. 63321 * 63322 * @param {boolean} useRootPaddingAlign Whether to use CSS custom properties in root selector. 63323 * 63324 * @param {Object} tree A theme.json tree containing layout definitions. 63325 * 63326 * @param {boolean} isTemplate Whether the entity being edited is a full template or a pattern. 63327 * @return {Array} An array of style declarations. 63328 */ 63329 function getStylesDeclarations(blockStyles = {}, selector = '', useRootPaddingAlign, tree = {}, isTemplate = true) { 63330 const { 63331 kebabCase 63332 } = unlock(external_wp_components_namespaceObject.privateApis); 63333 const isRoot = ROOT_BLOCK_SELECTOR === selector; 63334 const output = Object.entries(external_wp_blocks_namespaceObject.__EXPERIMENTAL_STYLE_PROPERTY).reduce((declarations, [key, { 63335 value, 63336 properties, 63337 useEngine, 63338 rootOnly 63339 }]) => { 63340 if (rootOnly && !isRoot) { 63341 return declarations; 63342 } 63343 const pathToValue = value; 63344 if (pathToValue[0] === 'elements' || useEngine) { 63345 return declarations; 63346 } 63347 const styleValue = getValueFromObjectPath(blockStyles, pathToValue); 63348 63349 // Root-level padding styles don't currently support strings with CSS shorthand values. 63350 // This may change: https://github.com/WordPress/gutenberg/issues/40132. 63351 if (key === '--wp--style--root--padding' && (typeof styleValue === 'string' || !useRootPaddingAlign)) { 63352 return declarations; 63353 } 63354 if (properties && typeof styleValue !== 'string') { 63355 Object.entries(properties).forEach(entry => { 63356 const [name, prop] = entry; 63357 if (!getValueFromObjectPath(styleValue, [prop], false)) { 63358 // Do not create a declaration 63359 // for sub-properties that don't have any value. 63360 return; 63361 } 63362 const cssProperty = name.startsWith('--') ? name : kebabCase(name); 63363 declarations.push(`$cssProperty}: $compileStyleValue(getValueFromObjectPath(styleValue, [prop]))}`); 63364 }); 63365 } else if (getValueFromObjectPath(blockStyles, pathToValue, false)) { 63366 const cssProperty = key.startsWith('--') ? key : kebabCase(key); 63367 declarations.push(`$cssProperty}: $compileStyleValue(getValueFromObjectPath(blockStyles, pathToValue))}`); 63368 } 63369 return declarations; 63370 }, []); 63371 63372 // The goal is to move everything to server side generated engine styles 63373 // This is temporary as we absorb more and more styles into the engine. 63374 const extraRules = (0,external_wp_styleEngine_namespaceObject.getCSSRules)(blockStyles); 63375 extraRules.forEach(rule => { 63376 // Don't output padding properties if padding variables are set or if we're not editing a full template. 63377 if (isRoot && (useRootPaddingAlign || !isTemplate) && rule.key.startsWith('padding')) { 63378 return; 63379 } 63380 const cssProperty = rule.key.startsWith('--') ? rule.key : kebabCase(rule.key); 63381 let ruleValue = rule.value; 63382 if (typeof ruleValue !== 'string' && ruleValue?.ref) { 63383 const refPath = ruleValue.ref.split('.'); 63384 ruleValue = getValueFromObjectPath(tree, refPath); 63385 // Presence of another ref indicates a reference to another dynamic value. 63386 // Pointing to another dynamic value is not supported. 63387 if (!ruleValue || ruleValue?.ref) { 63388 return; 63389 } 63390 } 63391 63392 // Calculate fluid typography rules where available. 63393 if (cssProperty === 'font-size') { 63394 /* 63395 * getTypographyFontSizeValue() will check 63396 * if fluid typography has been activated and also 63397 * whether the incoming value can be converted to a fluid value. 63398 * Values that already have a "clamp()" function will not pass the test, 63399 * and therefore the original $value will be returned. 63400 */ 63401 ruleValue = getTypographyFontSizeValue({ 63402 size: ruleValue 63403 }, getFluidTypographyOptionsFromSettings(tree?.settings)); 63404 } 63405 63406 // For aspect ratio to work, other dimensions rules (and Cover block defaults) must be unset. 63407 // This ensures that a fixed height does not override the aspect ratio. 63408 if (cssProperty === 'aspect-ratio') { 63409 output.push('min-height: unset'); 63410 } 63411 output.push(`$cssProperty}: $ruleValue}`); 63412 }); 63413 return output; 63414 } 63415 63416 /** 63417 * Get generated CSS for layout styles by looking up layout definitions provided 63418 * in theme.json, and outputting common layout styles, and specific blockGap values. 63419 * 63420 * @param {Object} props 63421 * @param {Object} props.layoutDefinitions Layout definitions, keyed by layout type. 63422 * @param {Object} props.style A style object containing spacing values. 63423 * @param {string} props.selector Selector used to group together layout styling rules. 63424 * @param {boolean} props.hasBlockGapSupport Whether or not the theme opts-in to blockGap support. 63425 * @param {boolean} props.hasFallbackGapSupport Whether or not the theme allows fallback gap styles. 63426 * @param {?string} props.fallbackGapValue An optional fallback gap value if no real gap value is available. 63427 * @return {string} Generated CSS rules for the layout styles. 63428 */ 63429 function getLayoutStyles({ 63430 layoutDefinitions = LAYOUT_DEFINITIONS, 63431 style, 63432 selector, 63433 hasBlockGapSupport, 63434 hasFallbackGapSupport, 63435 fallbackGapValue 63436 }) { 63437 let ruleset = ''; 63438 let gapValue = hasBlockGapSupport ? getGapCSSValue(style?.spacing?.blockGap) : ''; 63439 63440 // Ensure a fallback gap value for the root layout definitions, 63441 // and use a fallback value if one is provided for the current block. 63442 if (hasFallbackGapSupport) { 63443 if (selector === ROOT_BLOCK_SELECTOR) { 63444 gapValue = !gapValue ? '0.5em' : gapValue; 63445 } else if (!hasBlockGapSupport && fallbackGapValue) { 63446 gapValue = fallbackGapValue; 63447 } 63448 } 63449 if (gapValue && layoutDefinitions) { 63450 Object.values(layoutDefinitions).forEach(({ 63451 className, 63452 name, 63453 spacingStyles 63454 }) => { 63455 // Allow outputting fallback gap styles for flex layout type when block gap support isn't available. 63456 if (!hasBlockGapSupport && 'flex' !== name && 'grid' !== name) { 63457 return; 63458 } 63459 if (spacingStyles?.length) { 63460 spacingStyles.forEach(spacingStyle => { 63461 const declarations = []; 63462 if (spacingStyle.rules) { 63463 Object.entries(spacingStyle.rules).forEach(([cssProperty, cssValue]) => { 63464 declarations.push(`$cssProperty}: $cssValue ? cssValue : gapValue}`); 63465 }); 63466 } 63467 if (declarations.length) { 63468 let combinedSelector = ''; 63469 if (!hasBlockGapSupport) { 63470 // For fallback gap styles, use lower specificity, to ensure styles do not unintentionally override theme styles. 63471 combinedSelector = selector === ROOT_BLOCK_SELECTOR ? `:where(.$className}$spacingStyle?.selector || ''})` : `:where($selector}.$className}$spacingStyle?.selector || ''})`; 63472 } else { 63473 combinedSelector = selector === ROOT_BLOCK_SELECTOR ? `:where($selector} .$className})$spacingStyle?.selector || ''}` : `$selector}-$className}$spacingStyle?.selector || ''}`; 63474 } 63475 ruleset += `$combinedSelector} { $declarations.join('; ')}; }`; 63476 } 63477 }); 63478 } 63479 }); 63480 // For backwards compatibility, ensure the legacy block gap CSS variable is still available. 63481 if (selector === ROOT_BLOCK_SELECTOR && hasBlockGapSupport) { 63482 ruleset += `$selector} { --wp--style--block-gap: $gapValue}; }`; 63483 } 63484 } 63485 63486 // Output base styles 63487 if (selector === ROOT_BLOCK_SELECTOR && layoutDefinitions) { 63488 const validDisplayModes = ['block', 'flex', 'grid']; 63489 Object.values(layoutDefinitions).forEach(({ 63490 className, 63491 displayMode, 63492 baseStyles 63493 }) => { 63494 if (displayMode && validDisplayModes.includes(displayMode)) { 63495 ruleset += `$selector} .$className} { display:$displayMode}; }`; 63496 } 63497 if (baseStyles?.length) { 63498 baseStyles.forEach(baseStyle => { 63499 const declarations = []; 63500 if (baseStyle.rules) { 63501 Object.entries(baseStyle.rules).forEach(([cssProperty, cssValue]) => { 63502 declarations.push(`$cssProperty}: $cssValue}`); 63503 }); 63504 } 63505 if (declarations.length) { 63506 const combinedSelector = `$selector} .$className}$baseStyle?.selector || ''}`; 63507 ruleset += `$combinedSelector} { $declarations.join('; ')}; }`; 63508 } 63509 }); 63510 } 63511 }); 63512 } 63513 return ruleset; 63514 } 63515 const STYLE_KEYS = ['border', 'color', 'dimensions', 'spacing', 'typography', 'filter', 'outline', 'shadow']; 63516 function pickStyleKeys(treeToPickFrom) { 63517 if (!treeToPickFrom) { 63518 return {}; 63519 } 63520 const entries = Object.entries(treeToPickFrom); 63521 const pickedEntries = entries.filter(([key]) => STYLE_KEYS.includes(key)); 63522 // clone the style objects so that `getFeatureDeclarations` can remove consumed keys from it 63523 const clonedEntries = pickedEntries.map(([key, style]) => [key, JSON.parse(JSON.stringify(style))]); 63524 return Object.fromEntries(clonedEntries); 63525 } 63526 const getNodesWithStyles = (tree, blockSelectors) => { 63527 var _tree$styles$blocks; 63528 const nodes = []; 63529 if (!tree?.styles) { 63530 return nodes; 63531 } 63532 63533 // Top-level. 63534 const styles = pickStyleKeys(tree.styles); 63535 if (styles) { 63536 nodes.push({ 63537 styles, 63538 selector: ROOT_BLOCK_SELECTOR 63539 }); 63540 } 63541 Object.entries(external_wp_blocks_namespaceObject.__EXPERIMENTAL_ELEMENTS).forEach(([name, selector]) => { 63542 if (tree.styles?.elements?.[name]) { 63543 nodes.push({ 63544 styles: tree.styles?.elements?.[name], 63545 selector 63546 }); 63547 } 63548 }); 63549 63550 // Iterate over blocks: they can have styles & elements. 63551 Object.entries((_tree$styles$blocks = tree.styles?.blocks) !== null && _tree$styles$blocks !== void 0 ? _tree$styles$blocks : {}).forEach(([blockName, node]) => { 63552 var _node$elements; 63553 const blockStyles = pickStyleKeys(node); 63554 if (node?.variations) { 63555 const variations = {}; 63556 Object.keys(node.variations).forEach(variation => { 63557 variations[variation] = pickStyleKeys(node.variations[variation]); 63558 }); 63559 blockStyles.variations = variations; 63560 } 63561 if (blockStyles && blockSelectors?.[blockName]?.selector) { 63562 nodes.push({ 63563 duotoneSelector: blockSelectors[blockName].duotoneSelector, 63564 fallbackGapValue: blockSelectors[blockName].fallbackGapValue, 63565 hasLayoutSupport: blockSelectors[blockName].hasLayoutSupport, 63566 selector: blockSelectors[blockName].selector, 63567 styles: blockStyles, 63568 featureSelectors: blockSelectors[blockName].featureSelectors, 63569 styleVariationSelectors: blockSelectors[blockName].styleVariationSelectors 63570 }); 63571 } 63572 Object.entries((_node$elements = node?.elements) !== null && _node$elements !== void 0 ? _node$elements : {}).forEach(([elementName, value]) => { 63573 if (value && blockSelectors?.[blockName] && external_wp_blocks_namespaceObject.__EXPERIMENTAL_ELEMENTS[elementName]) { 63574 nodes.push({ 63575 styles: value, 63576 selector: blockSelectors[blockName]?.selector.split(',').map(sel => { 63577 const elementSelectors = external_wp_blocks_namespaceObject.__EXPERIMENTAL_ELEMENTS[elementName].split(','); 63578 return elementSelectors.map(elementSelector => sel + ' ' + elementSelector); 63579 }).join(',') 63580 }); 63581 } 63582 }); 63583 }); 63584 return nodes; 63585 }; 63586 const getNodesWithSettings = (tree, blockSelectors) => { 63587 var _tree$settings$blocks; 63588 const nodes = []; 63589 if (!tree?.settings) { 63590 return nodes; 63591 } 63592 const pickPresets = treeToPickFrom => { 63593 let presets = {}; 63594 PRESET_METADATA.forEach(({ 63595 path 63596 }) => { 63597 const value = getValueFromObjectPath(treeToPickFrom, path, false); 63598 if (value !== false) { 63599 presets = setImmutably(presets, path, value); 63600 } 63601 }); 63602 return presets; 63603 }; 63604 63605 // Top-level. 63606 const presets = pickPresets(tree.settings); 63607 const custom = tree.settings?.custom; 63608 if (Object.keys(presets).length > 0 || custom) { 63609 nodes.push({ 63610 presets, 63611 custom, 63612 selector: ROOT_BLOCK_SELECTOR 63613 }); 63614 } 63615 63616 // Blocks. 63617 Object.entries((_tree$settings$blocks = tree.settings?.blocks) !== null && _tree$settings$blocks !== void 0 ? _tree$settings$blocks : {}).forEach(([blockName, node]) => { 63618 const blockPresets = pickPresets(node); 63619 const blockCustom = node.custom; 63620 if (Object.keys(blockPresets).length > 0 || blockCustom) { 63621 nodes.push({ 63622 presets: blockPresets, 63623 custom: blockCustom, 63624 selector: blockSelectors[blockName]?.selector 63625 }); 63626 } 63627 }); 63628 return nodes; 63629 }; 63630 const toCustomProperties = (tree, blockSelectors) => { 63631 const settings = getNodesWithSettings(tree, blockSelectors); 63632 let ruleset = ''; 63633 settings.forEach(({ 63634 presets, 63635 custom, 63636 selector 63637 }) => { 63638 const declarations = getPresetsDeclarations(presets, tree?.settings); 63639 const customProps = flattenTree(custom, '--wp--custom--', '--'); 63640 if (customProps.length > 0) { 63641 declarations.push(...customProps); 63642 } 63643 if (declarations.length > 0) { 63644 ruleset += `$selector}{$declarations.join(';')};}`; 63645 } 63646 }); 63647 return ruleset; 63648 }; 63649 const toStyles = (tree, blockSelectors, hasBlockGapSupport, hasFallbackGapSupport, disableLayoutStyles = false, isTemplate = true) => { 63650 const nodesWithStyles = getNodesWithStyles(tree, blockSelectors); 63651 const nodesWithSettings = getNodesWithSettings(tree, blockSelectors); 63652 const useRootPaddingAlign = tree?.settings?.useRootPaddingAwareAlignments; 63653 const { 63654 contentSize, 63655 wideSize 63656 } = tree?.settings?.layout || {}; 63657 63658 /* 63659 * Reset default browser margin on the root body element. 63660 * This is set on the root selector **before** generating the ruleset 63661 * from the `theme.json`. This is to ensure that if the `theme.json` declares 63662 * `margin` in its `spacing` declaration for the `body` element then these 63663 * user-generated values take precedence in the CSS cascade. 63664 * @link https://github.com/WordPress/gutenberg/issues/36147. 63665 */ 63666 let ruleset = 'body {margin: 0;'; 63667 if (contentSize) { 63668 ruleset += ` --wp--style--global--content-size: $contentSize};`; 63669 } 63670 if (wideSize) { 63671 ruleset += ` --wp--style--global--wide-size: $wideSize};`; 63672 } 63673 63674 // Root padding styles should only be output for full templates, not patterns or template parts. 63675 if (useRootPaddingAlign && isTemplate) { 63676 /* 63677 * These rules reproduce the ones from https://github.com/WordPress/gutenberg/blob/79103f124925d1f457f627e154f52a56228ed5ad/lib/class-wp-theme-json-gutenberg.php#L2508 63678 * almost exactly, but for the selectors that target block wrappers in the front end. This code only runs in the editor, so it doesn't need those selectors. 63679 */ 63680 ruleset += `padding-right: 0; padding-left: 0; padding-top: var(--wp--style--root--padding-top); padding-bottom: var(--wp--style--root--padding-bottom) } 63681 .has-global-padding { padding-right: var(--wp--style--root--padding-right); padding-left: var(--wp--style--root--padding-left); } 63682 .has-global-padding :where(.has-global-padding:not(.wp-block-block)) { padding-right: 0; padding-left: 0; } 63683 .has-global-padding > .alignfull { margin-right: calc(var(--wp--style--root--padding-right) * -1); margin-left: calc(var(--wp--style--root--padding-left) * -1); } 63684 .has-global-padding :where(.has-global-padding:not(.wp-block-block)) > .alignfull { margin-right: 0; margin-left: 0; } 63685 .has-global-padding > .alignfull:where(:not(.has-global-padding):not(.is-layout-flex):not(.is-layout-grid)) > :where(.wp-block:not(.alignfull),p,h1,h2,h3,h4,h5,h6,ul,ol) { padding-right: var(--wp--style--root--padding-right); padding-left: var(--wp--style--root--padding-left); } 63686 .has-global-padding :where(.has-global-padding) > .alignfull:where(:not(.has-global-padding)) > :where(.wp-block:not(.alignfull),p,h1,h2,h3,h4,h5,h6,ul,ol) { padding-right: 0; padding-left: 0;`; 63687 } 63688 ruleset += '}'; 63689 nodesWithStyles.forEach(({ 63690 selector, 63691 duotoneSelector, 63692 styles, 63693 fallbackGapValue, 63694 hasLayoutSupport, 63695 featureSelectors, 63696 styleVariationSelectors 63697 }) => { 63698 // Process styles for block support features with custom feature level 63699 // CSS selectors set. 63700 if (featureSelectors) { 63701 const featureDeclarations = getFeatureDeclarations(featureSelectors, styles); 63702 Object.entries(featureDeclarations).forEach(([cssSelector, declarations]) => { 63703 if (declarations.length) { 63704 const rules = declarations.join(';'); 63705 ruleset += `$cssSelector}{$rules};}`; 63706 } 63707 }); 63708 } 63709 if (styleVariationSelectors) { 63710 Object.entries(styleVariationSelectors).forEach(([styleVariationName, styleVariationSelector]) => { 63711 const styleVariations = styles?.variations?.[styleVariationName]; 63712 if (styleVariations) { 63713 // If the block uses any custom selectors for block support, add those first. 63714 if (featureSelectors) { 63715 const featureDeclarations = getFeatureDeclarations(featureSelectors, styleVariations); 63716 Object.entries(featureDeclarations).forEach(([baseSelector, declarations]) => { 63717 if (declarations.length) { 63718 const cssSelector = concatFeatureVariationSelectorString(baseSelector, styleVariationSelector); 63719 const rules = declarations.join(';'); 63720 ruleset += `$cssSelector}{$rules};}`; 63721 } 63722 }); 63723 } 63724 63725 // Otherwise add regular selectors. 63726 const styleVariationDeclarations = getStylesDeclarations(styleVariations, styleVariationSelector, useRootPaddingAlign, tree); 63727 if (styleVariationDeclarations.length) { 63728 ruleset += `$styleVariationSelector}{$styleVariationDeclarations.join(';')};}`; 63729 } 63730 } 63731 }); 63732 } 63733 63734 // Process duotone styles. 63735 if (duotoneSelector) { 63736 const duotoneStyles = {}; 63737 if (styles?.filter) { 63738 duotoneStyles.filter = styles.filter; 63739 delete styles.filter; 63740 } 63741 const duotoneDeclarations = getStylesDeclarations(duotoneStyles); 63742 if (duotoneDeclarations.length) { 63743 ruleset += `$duotoneSelector}{$duotoneDeclarations.join(';')};}`; 63744 } 63745 } 63746 63747 // Process blockGap and layout styles. 63748 if (!disableLayoutStyles && (ROOT_BLOCK_SELECTOR === selector || hasLayoutSupport)) { 63749 ruleset += getLayoutStyles({ 63750 style: styles, 63751 selector, 63752 hasBlockGapSupport, 63753 hasFallbackGapSupport, 63754 fallbackGapValue 63755 }); 63756 } 63757 63758 // Process the remaining block styles (they use either normal block class or __experimentalSelector). 63759 const declarations = getStylesDeclarations(styles, selector, useRootPaddingAlign, tree, isTemplate); 63760 if (declarations?.length) { 63761 ruleset += `$selector}{$declarations.join(';')};}`; 63762 } 63763 63764 // Check for pseudo selector in `styles` and handle separately. 63765 const pseudoSelectorStyles = Object.entries(styles).filter(([key]) => key.startsWith(':')); 63766 if (pseudoSelectorStyles?.length) { 63767 pseudoSelectorStyles.forEach(([pseudoKey, pseudoStyle]) => { 63768 const pseudoDeclarations = getStylesDeclarations(pseudoStyle); 63769 if (!pseudoDeclarations?.length) { 63770 return; 63771 } 63772 63773 // `selector` maybe provided in a form 63774 // where block level selectors have sub element 63775 // selectors appended to them as a comma separated 63776 // string. 63777 // e.g. `h1 a,h2 a,h3 a,h4 a,h5 a,h6 a`; 63778 // Split and append pseudo selector to create 63779 // the proper rules to target the elements. 63780 const _selector = selector.split(',').map(sel => sel + pseudoKey).join(','); 63781 const pseudoRule = `$_selector}{$pseudoDeclarations.join(';')};}`; 63782 ruleset += pseudoRule; 63783 }); 63784 } 63785 }); 63786 63787 /* Add alignment / layout styles */ 63788 ruleset = ruleset + '.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }'; 63789 ruleset = ruleset + '.wp-site-blocks > .alignright { float: right; margin-left: 2em; }'; 63790 ruleset = ruleset + '.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }'; 63791 if (hasBlockGapSupport) { 63792 // Use fallback of `0.5em` just in case, however if there is blockGap support, there should nearly always be a real value. 63793 const gapValue = getGapCSSValue(tree?.styles?.spacing?.blockGap) || '0.5em'; 63794 ruleset = ruleset + `:where(.wp-site-blocks) > * { margin-block-start: $gapValue}; margin-block-end: 0; }`; 63795 ruleset = ruleset + ':where(.wp-site-blocks) > :first-child:first-child { margin-block-start: 0; }'; 63796 ruleset = ruleset + ':where(.wp-site-blocks) > :last-child:last-child { margin-block-end: 0; }'; 63797 } 63798 nodesWithSettings.forEach(({ 63799 selector, 63800 presets 63801 }) => { 63802 if (ROOT_BLOCK_SELECTOR === selector) { 63803 // Do not add extra specificity for top-level classes. 63804 selector = ''; 63805 } 63806 const classes = getPresetsClasses(selector, presets); 63807 if (classes.length > 0) { 63808 ruleset += classes; 63809 } 63810 }); 63811 return ruleset; 63812 }; 63813 function toSvgFilters(tree, blockSelectors) { 63814 const nodesWithSettings = getNodesWithSettings(tree, blockSelectors); 63815 return nodesWithSettings.flatMap(({ 63816 presets 63817 }) => { 63818 return getPresetsSvgFilters(presets); 63819 }); 63820 } 63821 const getSelectorsConfig = (blockType, rootSelector) => { 63822 if (blockType?.selectors && Object.keys(blockType.selectors).length > 0) { 63823 return blockType.selectors; 63824 } 63825 const config = { 63826 root: rootSelector 63827 }; 63828 Object.entries(BLOCK_SUPPORT_FEATURE_LEVEL_SELECTORS).forEach(([featureKey, featureName]) => { 63829 const featureSelector = getBlockCSSSelector(blockType, featureKey); 63830 if (featureSelector) { 63831 config[featureName] = featureSelector; 63832 } 63833 }); 63834 return config; 63835 }; 63836 const getBlockSelectors = (blockTypes, getBlockStyles) => { 63837 const result = {}; 63838 blockTypes.forEach(blockType => { 63839 const name = blockType.name; 63840 const selector = getBlockCSSSelector(blockType); 63841 let duotoneSelector = getBlockCSSSelector(blockType, 'filter.duotone'); 63842 63843 // Keep backwards compatibility for support.color.__experimentalDuotone. 63844 if (!duotoneSelector) { 63845 const rootSelector = getBlockCSSSelector(blockType); 63846 const duotoneSupport = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockType, 'color.__experimentalDuotone', false); 63847 duotoneSelector = duotoneSupport && scopeSelector(rootSelector, duotoneSupport); 63848 } 63849 const hasLayoutSupport = !!blockType?.supports?.layout || !!blockType?.supports?.__experimentalLayout; 63850 const fallbackGapValue = blockType?.supports?.spacing?.blockGap?.__experimentalDefault; 63851 const blockStyleVariations = getBlockStyles(name); 63852 const styleVariationSelectors = {}; 63853 if (blockStyleVariations?.length) { 63854 blockStyleVariations.forEach(variation => { 63855 const styleVariationSelector = getBlockStyleVariationSelector(variation.name, selector); 63856 styleVariationSelectors[variation.name] = styleVariationSelector; 63857 }); 63858 } 63859 // For each block support feature add any custom selectors. 63860 const featureSelectors = getSelectorsConfig(blockType, selector); 63861 result[name] = { 63862 duotoneSelector, 63863 fallbackGapValue, 63864 featureSelectors: Object.keys(featureSelectors).length ? featureSelectors : undefined, 63865 hasLayoutSupport, 63866 name, 63867 selector, 63868 styleVariationSelectors: Object.keys(styleVariationSelectors).length ? styleVariationSelectors : undefined 63869 }; 63870 }); 63871 return result; 63872 }; 63873 63874 /** 63875 * If there is a separator block whose color is defined in theme.json via background, 63876 * update the separator color to the same value by using border color. 63877 * 63878 * @param {Object} config Theme.json configuration file object. 63879 * @return {Object} configTheme.json configuration file object updated. 63880 */ 63881 function updateConfigWithSeparator(config) { 63882 const needsSeparatorStyleUpdate = config.styles?.blocks?.['core/separator'] && config.styles?.blocks?.['core/separator'].color?.background && !config.styles?.blocks?.['core/separator'].color?.text && !config.styles?.blocks?.['core/separator'].border?.color; 63883 if (needsSeparatorStyleUpdate) { 63884 return { 63885 ...config, 63886 styles: { 63887 ...config.styles, 63888 blocks: { 63889 ...config.styles.blocks, 63890 'core/separator': { 63891 ...config.styles.blocks['core/separator'], 63892 color: { 63893 ...config.styles.blocks['core/separator'].color, 63894 text: config.styles?.blocks['core/separator'].color.background 63895 } 63896 } 63897 } 63898 } 63899 }; 63900 } 63901 return config; 63902 } 63903 function processCSSNesting(css, blockSelector) { 63904 let processedCSS = ''; 63905 63906 // Split CSS nested rules. 63907 const parts = css.split('&'); 63908 parts.forEach(part => { 63909 const isRootCss = !part.includes('{'); 63910 if (isRootCss) { 63911 // If the part doesn't contain braces, it applies to the root level. 63912 processedCSS += `$blockSelector}{$part.trim()}}`; 63913 } else { 63914 // If the part contains braces, it's a nested CSS rule. 63915 const splittedPart = part.replace('}', '').split('{'); 63916 if (splittedPart.length !== 2) { 63917 return; 63918 } 63919 const [nestedSelector, cssValue] = splittedPart; 63920 const combinedSelector = nestedSelector.startsWith(' ') ? scopeSelector(blockSelector, nestedSelector) : appendToSelector(blockSelector, nestedSelector); 63921 processedCSS += `$combinedSelector}{$cssValue.trim()}}`; 63922 } 63923 }); 63924 return processedCSS; 63925 } 63926 63927 /** 63928 * Returns the global styles output using a global styles configuration. 63929 * If wishing to generate global styles and settings based on the 63930 * global styles config loaded in the editor context, use `useGlobalStylesOutput()`. 63931 * The use case for a custom config is to generate bespoke styles 63932 * and settings for previews, or other out-of-editor experiences. 63933 * 63934 * @param {Object} mergedConfig Global styles configuration. 63935 * @return {Array} Array of stylesheets and settings. 63936 */ 63937 function useGlobalStylesOutputWithConfig(mergedConfig = {}) { 63938 const [blockGap] = useGlobalSetting('spacing.blockGap'); 63939 const hasBlockGapSupport = blockGap !== null; 63940 const hasFallbackGapSupport = !hasBlockGapSupport; // This setting isn't useful yet: it exists as a placeholder for a future explicit fallback styles support. 63941 const disableLayoutStyles = (0,external_wp_data_namespaceObject.useSelect)(select => { 63942 const { 63943 getSettings 63944 } = select(store); 63945 return !!getSettings().disableLayoutStyles; 63946 }); 63947 const blockContext = (0,external_wp_element_namespaceObject.useContext)(block_context); 63948 const isTemplate = blockContext?.templateSlug !== undefined; 63949 const { 63950 getBlockStyles 63951 } = (0,external_wp_data_namespaceObject.useSelect)(external_wp_blocks_namespaceObject.store); 63952 return (0,external_wp_element_namespaceObject.useMemo)(() => { 63953 var _updatedConfig$styles; 63954 if (!mergedConfig?.styles || !mergedConfig?.settings) { 63955 return []; 63956 } 63957 const updatedConfig = updateConfigWithSeparator(mergedConfig); 63958 const blockSelectors = getBlockSelectors((0,external_wp_blocks_namespaceObject.getBlockTypes)(), getBlockStyles); 63959 const customProperties = toCustomProperties(updatedConfig, blockSelectors); 63960 const globalStyles = toStyles(updatedConfig, blockSelectors, hasBlockGapSupport, hasFallbackGapSupport, disableLayoutStyles, isTemplate); 63961 const svgs = toSvgFilters(updatedConfig, blockSelectors); 63962 const styles = [{ 63963 css: customProperties, 63964 isGlobalStyles: true 63965 }, { 63966 css: globalStyles, 63967 isGlobalStyles: true 63968 }, 63969 // Load custom CSS in own stylesheet so that any invalid CSS entered in the input won't break all the global styles in the editor. 63970 { 63971 css: (_updatedConfig$styles = updatedConfig.styles.css) !== null && _updatedConfig$styles !== void 0 ? _updatedConfig$styles : '', 63972 isGlobalStyles: true 63973 }, { 63974 assets: svgs, 63975 __unstableType: 'svg', 63976 isGlobalStyles: true 63977 }]; 63978 63979 // Loop through the blocks to check if there are custom CSS values. 63980 // If there are, get the block selector and push the selector together with 63981 // the CSS value to the 'stylesheets' array. 63982 (0,external_wp_blocks_namespaceObject.getBlockTypes)().forEach(blockType => { 63983 if (updatedConfig.styles.blocks[blockType.name]?.css) { 63984 const selector = blockSelectors[blockType.name].selector; 63985 styles.push({ 63986 css: processCSSNesting(updatedConfig.styles.blocks[blockType.name]?.css, selector), 63987 isGlobalStyles: true 63988 }); 63989 } 63990 }); 63991 return [styles, updatedConfig.settings]; 63992 }, [hasBlockGapSupport, hasFallbackGapSupport, mergedConfig, disableLayoutStyles, isTemplate, getBlockStyles]); 63993 } 63994 63995 /** 63996 * Returns the global styles output based on the current state of global styles config loaded in the editor context. 63997 * 63998 * @return {Array} Array of stylesheets and settings. 63999 */ 64000 function useGlobalStylesOutput() { 64001 const { 64002 merged: mergedConfig 64003 } = (0,external_wp_element_namespaceObject.useContext)(GlobalStylesContext); 64004 return useGlobalStylesOutputWithConfig(mergedConfig); 64005 } 64006 64007 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/global-styles/image-settings-panel.js 64008 64009 /** 64010 * WordPress dependencies 64011 */ 64012 64013 64014 64015 /** 64016 * Internal dependencies 64017 */ 64018 64019 function useHasImageSettingsPanel(name, value, inheritedValue) { 64020 // Note: If lightbox `value` exists, that means it was 64021 // defined via the the Global Styles UI and will NOT 64022 // be a boolean value or contain the `allowEditing` property, 64023 // so we should show the settings panel in those cases. 64024 return name === 'core/image' && inheritedValue?.lightbox?.allowEditing || !!value?.lightbox; 64025 } 64026 function ImageSettingsPanel({ 64027 onChange, 64028 value, 64029 inheritedValue, 64030 panelId 64031 }) { 64032 const resetLightbox = () => { 64033 onChange(undefined); 64034 }; 64035 const onChangeLightbox = newSetting => { 64036 onChange({ 64037 enabled: newSetting 64038 }); 64039 }; 64040 let lightboxChecked = false; 64041 if (inheritedValue?.lightbox?.enabled) { 64042 lightboxChecked = inheritedValue.lightbox.enabled; 64043 } 64044 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanel, { 64045 label: (0,external_wp_i18n_namespaceObject._x)('Settings', 'Image settings'), 64046 resetAll: resetLightbox, 64047 panelId: panelId, 64048 dropdownMenuProps: TOOLSPANEL_DROPDOWNMENU_PROPS 64049 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanelItem 64050 // We use the `userSettings` prop instead of `settings`, because `settings` 64051 // contains the core/theme values for the lightbox and we want to show the 64052 // "RESET" button ONLY when the user has explicitly set a value in the 64053 // Global Styles. 64054 , { 64055 hasValue: () => !!value?.lightbox, 64056 label: (0,external_wp_i18n_namespaceObject.__)('Expand on click'), 64057 onDeselect: resetLightbox, 64058 isShownByDefault: true, 64059 panelId: panelId 64060 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.ToggleControl, { 64061 label: (0,external_wp_i18n_namespaceObject.__)('Expand on click'), 64062 checked: lightboxChecked, 64063 onChange: onChangeLightbox 64064 })))); 64065 } 64066 64067 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/global-styles/advanced-panel.js 64068 64069 /** 64070 * WordPress dependencies 64071 */ 64072 64073 64074 64075 64076 /** 64077 * Internal dependencies 64078 */ 64079 64080 function AdvancedPanel({ 64081 value, 64082 onChange, 64083 inheritedValue = value 64084 }) { 64085 // Custom CSS 64086 const [cssError, setCSSError] = (0,external_wp_element_namespaceObject.useState)(null); 64087 const customCSS = inheritedValue?.css; 64088 function handleOnChange(newValue) { 64089 onChange({ 64090 ...value, 64091 css: newValue 64092 }); 64093 if (cssError) { 64094 const [transformed] = transform_styles([{ 64095 css: newValue 64096 }], '.editor-styles-wrapper'); 64097 if (transformed) { 64098 setCSSError(null); 64099 } 64100 } 64101 } 64102 function handleOnBlur(event) { 64103 if (!event?.target?.value) { 64104 setCSSError(null); 64105 return; 64106 } 64107 const [transformed] = transform_styles([{ 64108 css: event.target.value 64109 }], '.editor-styles-wrapper'); 64110 setCSSError(transformed === null ? (0,external_wp_i18n_namespaceObject.__)('There is an error with your CSS structure.') : null); 64111 } 64112 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalVStack, { 64113 spacing: 3 64114 }, cssError && (0,external_React_.createElement)(external_wp_components_namespaceObject.Notice, { 64115 status: "error", 64116 onRemove: () => setCSSError(null) 64117 }, cssError), (0,external_React_.createElement)(external_wp_components_namespaceObject.TextareaControl, { 64118 label: (0,external_wp_i18n_namespaceObject.__)('Additional CSS'), 64119 __nextHasNoMarginBottom: true, 64120 value: customCSS, 64121 onChange: newValue => handleOnChange(newValue), 64122 onBlur: handleOnBlur, 64123 className: "block-editor-global-styles-advanced-panel__custom-css-input", 64124 spellCheck: false 64125 })); 64126 } 64127 64128 ;// CONCATENATED MODULE: ./node_modules/memize/dist/index.js 64129 /** 64130 * Memize options object. 64131 * 64132 * @typedef MemizeOptions 64133 * 64134 * @property {number} [maxSize] Maximum size of the cache. 64135 */ 64136 64137 /** 64138 * Internal cache entry. 64139 * 64140 * @typedef MemizeCacheNode 64141 * 64142 * @property {?MemizeCacheNode|undefined} [prev] Previous node. 64143 * @property {?MemizeCacheNode|undefined} [next] Next node. 64144 * @property {Array<*>} args Function arguments for cache 64145 * entry. 64146 * @property {*} val Function result. 64147 */ 64148 64149 /** 64150 * Properties of the enhanced function for controlling cache. 64151 * 64152 * @typedef MemizeMemoizedFunction 64153 * 64154 * @property {()=>void} clear Clear the cache. 64155 */ 64156 64157 /** 64158 * Accepts a function to be memoized, and returns a new memoized function, with 64159 * optional options. 64160 * 64161 * @template {(...args: any[]) => any} F 64162 * 64163 * @param {F} fn Function to memoize. 64164 * @param {MemizeOptions} [options] Options object. 64165 * 64166 * @return {((...args: Parameters<F>) => ReturnType<F>) & MemizeMemoizedFunction} Memoized function. 64167 */ 64168 function memize(fn, options) { 64169 var size = 0; 64170 64171 /** @type {?MemizeCacheNode|undefined} */ 64172 var head; 64173 64174 /** @type {?MemizeCacheNode|undefined} */ 64175 var tail; 64176 64177 options = options || {}; 64178 64179 function memoized(/* ...args */) { 64180 var node = head, 64181 len = arguments.length, 64182 args, 64183 i; 64184 64185 searchCache: while (node) { 64186 // Perform a shallow equality test to confirm that whether the node 64187 // under test is a candidate for the arguments passed. Two arrays 64188 // are shallowly equal if their length matches and each entry is 64189 // strictly equal between the two sets. Avoid abstracting to a 64190 // function which could incur an arguments leaking deoptimization. 64191 64192 // Check whether node arguments match arguments length 64193 if (node.args.length !== arguments.length) { 64194 node = node.next; 64195 continue; 64196 } 64197 64198 // Check whether node arguments match arguments values 64199 for (i = 0; i < len; i++) { 64200 if (node.args[i] !== arguments[i]) { 64201 node = node.next; 64202 continue searchCache; 64203 } 64204 } 64205 64206 // At this point we can assume we've found a match 64207 64208 // Surface matched node to head if not already 64209 if (node !== head) { 64210 // As tail, shift to previous. Must only shift if not also 64211 // head, since if both head and tail, there is no previous. 64212 if (node === tail) { 64213 tail = node.prev; 64214 } 64215 64216 // Adjust siblings to point to each other. If node was tail, 64217 // this also handles new tail's empty `next` assignment. 64218 /** @type {MemizeCacheNode} */ (node.prev).next = node.next; 64219 if (node.next) { 64220 node.next.prev = node.prev; 64221 } 64222 64223 node.next = head; 64224 node.prev = null; 64225 /** @type {MemizeCacheNode} */ (head).prev = node; 64226 head = node; 64227 } 64228 64229 // Return immediately 64230 return node.val; 64231 } 64232 64233 // No cached value found. Continue to insertion phase: 64234 64235 // Create a copy of arguments (avoid leaking deoptimization) 64236 args = new Array(len); 64237 for (i = 0; i < len; i++) { 64238 args[i] = arguments[i]; 64239 } 64240 64241 node = { 64242 args: args, 64243 64244 // Generate the result from original function 64245 val: fn.apply(null, args), 64246 }; 64247 64248 // Don't need to check whether node is already head, since it would 64249 // have been returned above already if it was 64250 64251 // Shift existing head down list 64252 if (head) { 64253 head.prev = node; 64254 node.next = head; 64255 } else { 64256 // If no head, follows that there's no tail (at initial or reset) 64257 tail = node; 64258 } 64259 64260 // Trim tail if we're reached max size and are pending cache insertion 64261 if (size === /** @type {MemizeOptions} */ (options).maxSize) { 64262 tail = /** @type {MemizeCacheNode} */ (tail).prev; 64263 /** @type {MemizeCacheNode} */ (tail).next = null; 64264 } else { 64265 size++; 64266 } 64267 64268 head = node; 64269 64270 return node.val; 64271 } 64272 64273 memoized.clear = function () { 64274 head = null; 64275 tail = null; 64276 size = 0; 64277 }; 64278 64279 // Ignore reason: There's not a clear solution to create an intersection of 64280 // the function with additional properties, where the goal is to retain the 64281 // function signature of the incoming argument and add control properties 64282 // on the return value. 64283 64284 // @ts-ignore 64285 return memoized; 64286 } 64287 64288 64289 64290 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/global-styles/get-global-styles-changes.js 64291 /** 64292 * External dependencies 64293 */ 64294 64295 64296 /** 64297 * WordPress dependencies 64298 */ 64299 64300 64301 const globalStylesChangesCache = new Map(); 64302 const get_global_styles_changes_EMPTY_ARRAY = []; 64303 const translationMap = { 64304 caption: (0,external_wp_i18n_namespaceObject.__)('Caption'), 64305 link: (0,external_wp_i18n_namespaceObject.__)('Link'), 64306 button: (0,external_wp_i18n_namespaceObject.__)('Button'), 64307 heading: (0,external_wp_i18n_namespaceObject.__)('Heading'), 64308 h1: (0,external_wp_i18n_namespaceObject.__)('H1'), 64309 h2: (0,external_wp_i18n_namespaceObject.__)('H2'), 64310 h3: (0,external_wp_i18n_namespaceObject.__)('H3'), 64311 h4: (0,external_wp_i18n_namespaceObject.__)('H4'), 64312 h5: (0,external_wp_i18n_namespaceObject.__)('H5'), 64313 h6: (0,external_wp_i18n_namespaceObject.__)('H6'), 64314 'settings.color': (0,external_wp_i18n_namespaceObject.__)('Color'), 64315 'settings.typography': (0,external_wp_i18n_namespaceObject.__)('Typography'), 64316 'styles.color': (0,external_wp_i18n_namespaceObject.__)('Colors'), 64317 'styles.spacing': (0,external_wp_i18n_namespaceObject.__)('Spacing'), 64318 'styles.typography': (0,external_wp_i18n_namespaceObject.__)('Typography') 64319 }; 64320 const getBlockNames = memize(() => (0,external_wp_blocks_namespaceObject.getBlockTypes)().reduce((accumulator, { 64321 name, 64322 title 64323 }) => { 64324 accumulator[name] = title; 64325 return accumulator; 64326 }, {})); 64327 const isObject = obj => obj !== null && typeof obj === 'object'; 64328 64329 /** 64330 * Get the translation for a given global styles key. 64331 * @param {string} key A key representing a path to a global style property or setting. 64332 * @return {string|undefined} A translated key or undefined if no translation exists. 64333 */ 64334 function getTranslation(key) { 64335 if (translationMap[key]) { 64336 return translationMap[key]; 64337 } 64338 const keyArray = key.split('.'); 64339 if (keyArray?.[0] === 'blocks') { 64340 const blockName = getBlockNames()?.[keyArray[1]]; 64341 return blockName || keyArray[1]; 64342 } 64343 if (keyArray?.[0] === 'elements') { 64344 return translationMap[keyArray[1]] || keyArray[1]; 64345 } 64346 return undefined; 64347 } 64348 64349 /** 64350 * A deep comparison of two objects, optimized for comparing global styles. 64351 * @param {Object} changedObject The changed object to compare. 64352 * @param {Object} originalObject The original object to compare against. 64353 * @param {string} parentPath A key/value pair object of block names and their rendered titles. 64354 * @return {string[]} An array of paths whose values have changed. 64355 */ 64356 function deepCompare(changedObject, originalObject, parentPath = '') { 64357 // We have two non-object values to compare. 64358 if (!isObject(changedObject) && !isObject(originalObject)) { 64359 /* 64360 * Only return a path if the value has changed. 64361 * And then only the path name up to 2 levels deep. 64362 */ 64363 return changedObject !== originalObject ? parentPath.split('.').slice(0, 2).join('.') : undefined; 64364 } 64365 64366 // Enable comparison when an object doesn't have a corresponding property to compare. 64367 changedObject = isObject(changedObject) ? changedObject : {}; 64368 originalObject = isObject(originalObject) ? originalObject : {}; 64369 const allKeys = new Set([...Object.keys(changedObject), ...Object.keys(originalObject)]); 64370 let diffs = []; 64371 for (const key of allKeys) { 64372 const path = parentPath ? parentPath + '.' + key : key; 64373 const changedPath = deepCompare(changedObject[key], originalObject[key], path); 64374 if (changedPath) { 64375 diffs = diffs.concat(changedPath); 64376 } 64377 } 64378 return diffs; 64379 } 64380 64381 /** 64382 * Returns an array of translated summarized global styles changes. 64383 * Results are cached using a Map() key of `JSON.stringify( { next, previous } )`. 64384 * 64385 * @param {Object} next The changed object to compare. 64386 * @param {Object} previous The original object to compare against. 64387 * @return {Array[]} A 2-dimensional array of tuples: [ "group", "translated change" ]. 64388 */ 64389 function getGlobalStylesChangelist(next, previous) { 64390 const cacheKey = JSON.stringify({ 64391 next, 64392 previous 64393 }); 64394 if (globalStylesChangesCache.has(cacheKey)) { 64395 return globalStylesChangesCache.get(cacheKey); 64396 } 64397 64398 /* 64399 * Compare the two changesets with normalized keys. 64400 * The order of these keys determines the order in which 64401 * they'll appear in the results. 64402 */ 64403 const changedValueTree = deepCompare({ 64404 styles: { 64405 color: next?.styles?.color, 64406 typography: next?.styles?.typography, 64407 spacing: next?.styles?.spacing 64408 }, 64409 blocks: next?.styles?.blocks, 64410 elements: next?.styles?.elements, 64411 settings: next?.settings 64412 }, { 64413 styles: { 64414 color: previous?.styles?.color, 64415 typography: previous?.styles?.typography, 64416 spacing: previous?.styles?.spacing 64417 }, 64418 blocks: previous?.styles?.blocks, 64419 elements: previous?.styles?.elements, 64420 settings: previous?.settings 64421 }); 64422 if (!changedValueTree.length) { 64423 globalStylesChangesCache.set(cacheKey, get_global_styles_changes_EMPTY_ARRAY); 64424 return get_global_styles_changes_EMPTY_ARRAY; 64425 } 64426 64427 // Remove duplicate results. 64428 const result = [...new Set(changedValueTree)] 64429 /* 64430 * Translate the keys. 64431 * Remove empty translations. 64432 */.reduce((acc, curr) => { 64433 const translation = getTranslation(curr); 64434 if (translation) { 64435 acc.push([curr.split('.')[0], translation]); 64436 } 64437 return acc; 64438 }, []); 64439 globalStylesChangesCache.set(cacheKey, result); 64440 return result; 64441 } 64442 64443 /** 64444 * From a getGlobalStylesChangelist() result, returns an array of translated global styles changes, grouped by type. 64445 * The types are 'blocks', 'elements', 'settings', and 'styles'. 64446 * 64447 * @param {Object} next The changed object to compare. 64448 * @param {Object} previous The original object to compare against. 64449 * @param {{maxResults:number}} options Options. maxResults: results to return before truncating. 64450 * @return {string[]} An array of translated changes. 64451 */ 64452 function getGlobalStylesChanges(next, previous, options = {}) { 64453 let changeList = getGlobalStylesChangelist(next, previous); 64454 const changesLength = changeList.length; 64455 const { 64456 maxResults 64457 } = options; 64458 if (changesLength) { 64459 // Truncate to `n` results if necessary. 64460 if (!!maxResults && changesLength > maxResults) { 64461 changeList = changeList.slice(0, maxResults); 64462 } 64463 return Object.entries(changeList.reduce((acc, curr) => { 64464 const group = acc[curr[0]] || []; 64465 if (!group.includes(curr[1])) { 64466 acc[curr[0]] = [...group, curr[1]]; 64467 } 64468 return acc; 64469 }, {})).map(([key, changeValues]) => { 64470 const changeValuesLength = changeValues.length; 64471 const joinedChangesValue = changeValues.join((0,external_wp_i18n_namespaceObject.__)(', ')); 64472 switch (key) { 64473 case 'blocks': 64474 { 64475 return (0,external_wp_i18n_namespaceObject.sprintf)( 64476 // translators: %s: a list of block names separated by a comma. 64477 (0,external_wp_i18n_namespaceObject._n)('%s block.', '%s blocks.', changeValuesLength), joinedChangesValue); 64478 } 64479 case 'elements': 64480 { 64481 return (0,external_wp_i18n_namespaceObject.sprintf)( 64482 // translators: %s: a list of element names separated by a comma. 64483 (0,external_wp_i18n_namespaceObject._n)('%s element.', '%s elements.', changeValuesLength), joinedChangesValue); 64484 } 64485 case 'settings': 64486 { 64487 return (0,external_wp_i18n_namespaceObject.sprintf)( 64488 // translators: %s: a list of theme.json setting labels separated by a comma. 64489 (0,external_wp_i18n_namespaceObject.__)('%s settings.'), joinedChangesValue); 64490 } 64491 case 'styles': 64492 { 64493 return (0,external_wp_i18n_namespaceObject.sprintf)( 64494 // translators: %s: a list of theme.json top-level styles labels separated by a comma. 64495 (0,external_wp_i18n_namespaceObject.__)('%s styles.'), joinedChangesValue); 64496 } 64497 default: 64498 { 64499 return (0,external_wp_i18n_namespaceObject.sprintf)( 64500 // translators: %s: a list of global styles changes separated by a comma. 64501 (0,external_wp_i18n_namespaceObject.__)('%s.'), joinedChangesValue); 64502 } 64503 } 64504 }); 64505 } 64506 return get_global_styles_changes_EMPTY_ARRAY; 64507 } 64508 64509 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/global-styles/index.js 64510 64511 64512 64513 64514 64515 64516 64517 64518 64519 64520 64521 64522 64523 64524 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/rich-text/get-rich-text-values.js 64525 64526 /** 64527 * WordPress dependencies 64528 */ 64529 64530 64531 64532 64533 /** 64534 * Internal dependencies 64535 */ 64536 64537 64538 64539 /* 64540 * This function is similar to `@wordpress/element`'s `renderToString` function, 64541 * except that it does not render the elements to a string, but instead collects 64542 * the values of all rich text `Content` elements. 64543 */ 64544 function addValuesForElement(element, values, innerBlocks) { 64545 if (null === element || undefined === element || false === element) { 64546 return; 64547 } 64548 if (Array.isArray(element)) { 64549 return addValuesForElements(element, values, innerBlocks); 64550 } 64551 switch (typeof element) { 64552 case 'string': 64553 case 'number': 64554 return; 64555 } 64556 const { 64557 type, 64558 props 64559 } = element; 64560 switch (type) { 64561 case external_wp_element_namespaceObject.StrictMode: 64562 case external_wp_element_namespaceObject.Fragment: 64563 return addValuesForElements(props.children, values, innerBlocks); 64564 case external_wp_element_namespaceObject.RawHTML: 64565 return; 64566 case inner_blocks.Content: 64567 return addValuesForBlocks(values, innerBlocks); 64568 case Content: 64569 values.push(props.value); 64570 return; 64571 } 64572 switch (typeof type) { 64573 case 'string': 64574 if (typeof props.children !== 'undefined') { 64575 return addValuesForElements(props.children, values, innerBlocks); 64576 } 64577 return; 64578 case 'function': 64579 const el = type.prototype && typeof type.prototype.render === 'function' ? new type(props).render() : type(props); 64580 return addValuesForElement(el, values, innerBlocks); 64581 } 64582 } 64583 function addValuesForElements(children, ...args) { 64584 children = Array.isArray(children) ? children : [children]; 64585 for (let i = 0; i < children.length; i++) { 64586 addValuesForElement(children[i], ...args); 64587 } 64588 } 64589 function addValuesForBlocks(values, blocks) { 64590 for (let i = 0; i < blocks.length; i++) { 64591 const { 64592 name, 64593 attributes, 64594 innerBlocks 64595 } = blocks[i]; 64596 const saveElement = (0,external_wp_blocks_namespaceObject.getSaveElement)(name, attributes, 64597 // Instead of letting save elements use `useInnerBlocksProps.save`, 64598 // force them to use InnerBlocks.Content instead so we can intercept 64599 // a single component. 64600 (0,external_React_.createElement)(inner_blocks.Content, null)); 64601 addValuesForElement(saveElement, values, innerBlocks); 64602 } 64603 } 64604 function getRichTextValues(blocks = []) { 64605 external_wp_blocks_namespaceObject.__unstableGetBlockProps.skipFilters = true; 64606 const values = []; 64607 addValuesForBlocks(values, blocks); 64608 external_wp_blocks_namespaceObject.__unstableGetBlockProps.skipFilters = false; 64609 return values.map(value => value instanceof external_wp_richText_namespaceObject.RichTextData ? value : external_wp_richText_namespaceObject.RichTextData.fromHTMLString(value)); 64610 } 64611 64612 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/resizable-box-popover/index.js 64613 64614 /** 64615 * WordPress dependencies 64616 */ 64617 64618 64619 /** 64620 * Internal dependencies 64621 */ 64622 64623 function ResizableBoxPopover({ 64624 clientId, 64625 resizableBoxProps, 64626 ...props 64627 }) { 64628 return (0,external_React_.createElement)(block_popover, { 64629 clientId: clientId, 64630 __unstableCoverTarget: true, 64631 __unstablePopoverSlot: "__unstable-block-tools-after", 64632 shift: false, 64633 ...props 64634 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.ResizableBox, { 64635 ...resizableBoxProps 64636 })); 64637 } 64638 64639 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/use-can-block-toolbar-be-focused.js 64640 /** 64641 * WordPress dependencies 64642 */ 64643 64644 64645 64646 /** 64647 * Internal dependencies 64648 */ 64649 64650 64651 64652 /** 64653 * Returns true if the block toolbar should be able to receive focus. 64654 * 64655 * @return {boolean} Whether the block toolbar should be able to receive focus 64656 */ 64657 function useCanBlockToolbarBeFocused() { 64658 return (0,external_wp_data_namespaceObject.useSelect)(select => { 64659 const { 64660 __unstableGetEditorMode, 64661 getBlock, 64662 getSettings, 64663 getSelectedBlockClientId, 64664 getFirstMultiSelectedBlockClientId 64665 } = unlock(select(store)); 64666 const selectedBlockId = getFirstMultiSelectedBlockClientId() || getSelectedBlockClientId(); 64667 const isEmptyDefaultBlock = (0,external_wp_blocks_namespaceObject.isUnmodifiedDefaultBlock)(getBlock(selectedBlockId) || {}); 64668 64669 // Fixed Toolbar can be focused when: 64670 // - a block is selected 64671 // - fixed toolbar is on 64672 // Block Toolbar Popover can be focused when: 64673 // - a block is selected 64674 // - we are in edit mode 64675 // - it is not an empty default block 64676 return !!selectedBlockId && (getSettings().hasFixedToolbar || __unstableGetEditorMode() === 'edit' && !isEmptyDefaultBlock); 64677 }, []); 64678 } 64679 64680 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-removal-warning-modal/index.js 64681 64682 /** 64683 * WordPress dependencies 64684 */ 64685 64686 64687 64688 64689 64690 /** 64691 * Internal dependencies 64692 */ 64693 64694 64695 function BlockRemovalWarningModal({ 64696 rules 64697 }) { 64698 const { 64699 clientIds, 64700 selectPrevious, 64701 blockNamesForPrompt, 64702 messageType 64703 } = (0,external_wp_data_namespaceObject.useSelect)(select => unlock(select(store)).getRemovalPromptData()); 64704 const { 64705 clearBlockRemovalPrompt, 64706 setBlockRemovalRules, 64707 privateRemoveBlocks 64708 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store)); 64709 64710 // Load block removal rules, simultaneously signalling that the block 64711 // removal prompt is in place. 64712 (0,external_wp_element_namespaceObject.useEffect)(() => { 64713 setBlockRemovalRules(rules); 64714 return () => { 64715 setBlockRemovalRules(); 64716 }; 64717 }, [rules, setBlockRemovalRules]); 64718 if (!blockNamesForPrompt) { 64719 return; 64720 } 64721 const message = messageType === 'templates' ? (0,external_wp_i18n_namespaceObject._n)('Deleting this block will stop your post or page content from displaying on this template. It is not recommended.', 'Deleting these blocks will stop your post or page content from displaying on this template. It is not recommended.', blockNamesForPrompt.length) : (0,external_wp_i18n_namespaceObject._n)('Deleting this block could break patterns on your site that have content linked to it. Are you sure you want to delete it?', 'Deleting these blocks could break patterns on your site that have content linked to them. Are you sure you want to delete them?', blockNamesForPrompt.length); 64722 const onConfirmRemoval = () => { 64723 privateRemoveBlocks(clientIds, selectPrevious, /* force */true); 64724 clearBlockRemovalPrompt(); 64725 }; 64726 return (0,external_React_.createElement)(external_wp_components_namespaceObject.Modal, { 64727 title: (0,external_wp_i18n_namespaceObject.__)('Be careful!'), 64728 onRequestClose: clearBlockRemovalPrompt, 64729 size: "medium" 64730 }, (0,external_React_.createElement)("p", null, message), (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalHStack, { 64731 justify: "right" 64732 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 64733 variant: "tertiary", 64734 onClick: clearBlockRemovalPrompt 64735 }, (0,external_wp_i18n_namespaceObject.__)('Cancel')), (0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 64736 variant: "primary", 64737 onClick: onConfirmRemoval 64738 }, (0,external_wp_i18n_namespaceObject.__)('Delete')))); 64739 } 64740 64741 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/dimensions-tool/scale-tool.js 64742 64743 /** 64744 * WordPress dependencies 64745 */ 64746 64747 64748 64749 64750 /** 64751 * @typedef {import('@wordpress/components/build-types/select-control/types').SelectControlProps} SelectControlProps 64752 */ 64753 64754 /** 64755 * The descriptions are purposely made generic as object-fit could be used for 64756 * any replaced element. Provide your own set of options if you need different 64757 * help text or labels. 64758 * 64759 * @see https://developer.mozilla.org/en-US/docs/Web/CSS/Replaced_element 64760 * 64761 * @type {SelectControlProps[]} 64762 */ 64763 const DEFAULT_SCALE_OPTIONS = [{ 64764 value: 'fill', 64765 label: (0,external_wp_i18n_namespaceObject._x)('Fill', 'Scale option for dimensions control'), 64766 help: (0,external_wp_i18n_namespaceObject.__)('Fill the space by stretching the content.') 64767 }, { 64768 value: 'contain', 64769 label: (0,external_wp_i18n_namespaceObject._x)('Contain', 'Scale option for dimensions control'), 64770 help: (0,external_wp_i18n_namespaceObject.__)('Fit the content to the space without clipping.') 64771 }, { 64772 value: 'cover', 64773 label: (0,external_wp_i18n_namespaceObject._x)('Cover', 'Scale option for dimensions control'), 64774 help: (0,external_wp_i18n_namespaceObject.__)("Fill the space by clipping what doesn't fit.") 64775 }, { 64776 value: 'none', 64777 label: (0,external_wp_i18n_namespaceObject._x)('None', 'Scale option for dimensions control'), 64778 help: (0,external_wp_i18n_namespaceObject.__)('Do not adjust the sizing of the content. Content that is too large will be clipped, and content that is too small will have additional padding.') 64779 }, { 64780 value: 'scale-down', 64781 label: (0,external_wp_i18n_namespaceObject._x)('Scale down', 'Scale option for dimensions control'), 64782 help: (0,external_wp_i18n_namespaceObject.__)('Scale down the content to fit the space if it is too big. Content that is too small will have additional padding.') 64783 }]; 64784 64785 /** 64786 * @callback ScaleToolPropsOnChange 64787 * @param {string} nextValue New scale value. 64788 * @return {void} 64789 */ 64790 64791 /** 64792 * @typedef {Object} ScaleToolProps 64793 * @property {string} [panelId] ID of the panel that contains the controls. 64794 * @property {string} [value] Current scale value. 64795 * @property {ScaleToolPropsOnChange} [onChange] Callback to update the scale value. 64796 * @property {SelectControlProps[]} [options] Scale options. 64797 * @property {string} [defaultValue] Default scale value. 64798 * @property {boolean} [showControl=true] Whether to show the control. 64799 * @property {boolean} [isShownByDefault=true] Whether the tool panel is shown by default. 64800 */ 64801 64802 /** 64803 * A tool to select the CSS object-fit property for the image. 64804 * 64805 * @param {ScaleToolProps} props 64806 * 64807 * @return {import('react').ReactElement} The scale tool. 64808 */ 64809 function ScaleTool({ 64810 panelId, 64811 value, 64812 onChange, 64813 options = DEFAULT_SCALE_OPTIONS, 64814 defaultValue = DEFAULT_SCALE_OPTIONS[0].value, 64815 isShownByDefault = true 64816 }) { 64817 // Match the CSS default so if the value is used directly in CSS it will look correct in the control. 64818 const displayValue = value !== null && value !== void 0 ? value : 'fill'; 64819 const scaleHelp = (0,external_wp_element_namespaceObject.useMemo)(() => { 64820 return options.reduce((acc, option) => { 64821 acc[option.value] = option.help; 64822 return acc; 64823 }, {}); 64824 }, [options]); 64825 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 64826 label: (0,external_wp_i18n_namespaceObject.__)('Scale'), 64827 isShownByDefault: isShownByDefault, 64828 hasValue: () => displayValue !== defaultValue, 64829 onDeselect: () => onChange(defaultValue), 64830 panelId: panelId 64831 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToggleGroupControl, { 64832 label: (0,external_wp_i18n_namespaceObject.__)('Scale'), 64833 isBlock: true, 64834 help: scaleHelp[displayValue], 64835 value: displayValue, 64836 onChange: onChange, 64837 size: '__unstable-large' 64838 }, options.map(option => (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOption, { 64839 key: option.value, 64840 ...option 64841 })))); 64842 } 64843 64844 ;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/extends.js 64845 function extends_extends() { 64846 extends_extends = Object.assign ? Object.assign.bind() : function (target) { 64847 for (var i = 1; i < arguments.length; i++) { 64848 var source = arguments[i]; 64849 for (var key in source) { 64850 if (Object.prototype.hasOwnProperty.call(source, key)) { 64851 target[key] = source[key]; 64852 } 64853 } 64854 } 64855 return target; 64856 }; 64857 return extends_extends.apply(this, arguments); 64858 } 64859 ;// CONCATENATED MODULE: ./node_modules/@emotion/styled/node_modules/@emotion/memoize/dist/emotion-memoize.esm.js 64860 function memoize(fn) { 64861 var cache = Object.create(null); 64862 return function (arg) { 64863 if (cache[arg] === undefined) cache[arg] = fn(arg); 64864 return cache[arg]; 64865 }; 64866 } 64867 64868 64869 64870 ;// CONCATENATED MODULE: ./node_modules/@emotion/styled/node_modules/@emotion/is-prop-valid/dist/emotion-is-prop-valid.esm.js 64871 64872 64873 var reactPropsRegex = /^((children|dangerouslySetInnerHTML|key|ref|autoFocus|defaultValue|defaultChecked|innerHTML|suppressContentEditableWarning|suppressHydrationWarning|valueLink|abbr|accept|acceptCharset|accessKey|action|allow|allowUserMedia|allowPaymentRequest|allowFullScreen|allowTransparency|alt|async|autoComplete|autoPlay|capture|cellPadding|cellSpacing|challenge|charSet|checked|cite|classID|className|cols|colSpan|content|contentEditable|contextMenu|controls|controlsList|coords|crossOrigin|data|dateTime|decoding|default|defer|dir|disabled|disablePictureInPicture|download|draggable|encType|enterKeyHint|form|formAction|formEncType|formMethod|formNoValidate|formTarget|frameBorder|headers|height|hidden|high|href|hrefLang|htmlFor|httpEquiv|id|inputMode|integrity|is|keyParams|keyType|kind|label|lang|list|loading|loop|low|marginHeight|marginWidth|max|maxLength|media|mediaGroup|method|min|minLength|multiple|muted|name|nonce|noValidate|open|optimum|pattern|placeholder|playsInline|poster|preload|profile|radioGroup|readOnly|referrerPolicy|rel|required|reversed|role|rows|rowSpan|sandbox|scope|scoped|scrolling|seamless|selected|shape|size|sizes|slot|span|spellCheck|src|srcDoc|srcLang|srcSet|start|step|style|summary|tabIndex|target|title|translate|type|useMap|value|width|wmode|wrap|about|datatype|inlist|prefix|property|resource|typeof|vocab|autoCapitalize|autoCorrect|autoSave|color|incremental|fallback|inert|itemProp|itemScope|itemType|itemID|itemRef|on|option|results|security|unselectable|accentHeight|accumulate|additive|alignmentBaseline|allowReorder|alphabetic|amplitude|arabicForm|ascent|attributeName|attributeType|autoReverse|azimuth|baseFrequency|baselineShift|baseProfile|bbox|begin|bias|by|calcMode|capHeight|clip|clipPathUnits|clipPath|clipRule|colorInterpolation|colorInterpolationFilters|colorProfile|colorRendering|contentScriptType|contentStyleType|cursor|cx|cy|d|decelerate|descent|diffuseConstant|direction|display|divisor|dominantBaseline|dur|dx|dy|edgeMode|elevation|enableBackground|end|exponent|externalResourcesRequired|fill|fillOpacity|fillRule|filter|filterRes|filterUnits|floodColor|floodOpacity|focusable|fontFamily|fontSize|fontSizeAdjust|fontStretch|fontStyle|fontVariant|fontWeight|format|from|fr|fx|fy|g1|g2|glyphName|glyphOrientationHorizontal|glyphOrientationVertical|glyphRef|gradientTransform|gradientUnits|hanging|horizAdvX|horizOriginX|ideographic|imageRendering|in|in2|intercept|k|k1|k2|k3|k4|kernelMatrix|kernelUnitLength|kerning|keyPoints|keySplines|keyTimes|lengthAdjust|letterSpacing|lightingColor|limitingConeAngle|local|markerEnd|markerMid|markerStart|markerHeight|markerUnits|markerWidth|mask|maskContentUnits|maskUnits|mathematical|mode|numOctaves|offset|opacity|operator|order|orient|orientation|origin|overflow|overlinePosition|overlineThickness|panose1|paintOrder|pathLength|patternContentUnits|patternTransform|patternUnits|pointerEvents|points|pointsAtX|pointsAtY|pointsAtZ|preserveAlpha|preserveAspectRatio|primitiveUnits|r|radius|refX|refY|renderingIntent|repeatCount|repeatDur|requiredExtensions|requiredFeatures|restart|result|rotate|rx|ry|scale|seed|shapeRendering|slope|spacing|specularConstant|specularExponent|speed|spreadMethod|startOffset|stdDeviation|stemh|stemv|stitchTiles|stopColor|stopOpacity|strikethroughPosition|strikethroughThickness|string|stroke|strokeDasharray|strokeDashoffset|strokeLinecap|strokeLinejoin|strokeMiterlimit|strokeOpacity|strokeWidth|surfaceScale|systemLanguage|tableValues|targetX|targetY|textAnchor|textDecoration|textRendering|textLength|to|transform|u1|u2|underlinePosition|underlineThickness|unicode|unicodeBidi|unicodeRange|unitsPerEm|vAlphabetic|vHanging|vIdeographic|vMathematical|values|vectorEffect|version|vertAdvY|vertOriginX|vertOriginY|viewBox|viewTarget|visibility|widths|wordSpacing|writingMode|x|xHeight|x1|x2|xChannelSelector|xlinkActuate|xlinkArcrole|xlinkHref|xlinkRole|xlinkShow|xlinkTitle|xlinkType|xmlBase|xmlns|xmlnsXlink|xmlLang|xmlSpace|y|y1|y2|yChannelSelector|z|zoomAndPan|for|class|autofocus)|(([Dd][Aa][Tt][Aa]|[Aa][Rr][Ii][Aa]|x)-.*))$/; // https://esbench.com/bench/5bfee68a4cd7e6009ef61d23 64874 64875 var isPropValid = /* #__PURE__ */memoize(function (prop) { 64876 return reactPropsRegex.test(prop) || prop.charCodeAt(0) === 111 64877 /* o */ 64878 && prop.charCodeAt(1) === 110 64879 /* n */ 64880 && prop.charCodeAt(2) < 91; 64881 } 64882 /* Z+1 */ 64883 ); 64884 64885 64886 64887 ;// CONCATENATED MODULE: ./node_modules/@emotion/sheet/dist/emotion-sheet.browser.esm.js 64888 /* 64889 64890 Based off glamor's StyleSheet, thanks Sunil ❤️ 64891 64892 high performance StyleSheet for css-in-js systems 64893 64894 - uses multiple style tags behind the scenes for millions of rules 64895 - uses `insertRule` for appending in production for *much* faster performance 64896 64897 // usage 64898 64899 import { StyleSheet } from '@emotion/sheet' 64900 64901 let styleSheet = new StyleSheet({ key: '', container: document.head }) 64902 64903 styleSheet.insert('#box { border: 1px solid red; }') 64904 - appends a css rule into the stylesheet 64905 64906 styleSheet.flush() 64907 - empties the stylesheet of all its contents 64908 64909 */ 64910 // $FlowFixMe 64911 function sheetForTag(tag) { 64912 if (tag.sheet) { 64913 // $FlowFixMe 64914 return tag.sheet; 64915 } // this weirdness brought to you by firefox 64916 64917 /* istanbul ignore next */ 64918 64919 64920 for (var i = 0; i < document.styleSheets.length; i++) { 64921 if (document.styleSheets[i].ownerNode === tag) { 64922 // $FlowFixMe 64923 return document.styleSheets[i]; 64924 } 64925 } 64926 } 64927 64928 function createStyleElement(options) { 64929 var tag = document.createElement('style'); 64930 tag.setAttribute('data-emotion', options.key); 64931 64932 if (options.nonce !== undefined) { 64933 tag.setAttribute('nonce', options.nonce); 64934 } 64935 64936 tag.appendChild(document.createTextNode('')); 64937 tag.setAttribute('data-s', ''); 64938 return tag; 64939 } 64940 64941 var StyleSheet = /*#__PURE__*/function () { 64942 // Using Node instead of HTMLElement since container may be a ShadowRoot 64943 function StyleSheet(options) { 64944 var _this = this; 64945 64946 this._insertTag = function (tag) { 64947 var before; 64948 64949 if (_this.tags.length === 0) { 64950 if (_this.insertionPoint) { 64951 before = _this.insertionPoint.nextSibling; 64952 } else if (_this.prepend) { 64953 before = _this.container.firstChild; 64954 } else { 64955 before = _this.before; 64956 } 64957 } else { 64958 before = _this.tags[_this.tags.length - 1].nextSibling; 64959 } 64960 64961 _this.container.insertBefore(tag, before); 64962 64963 _this.tags.push(tag); 64964 }; 64965 64966 this.isSpeedy = options.speedy === undefined ? "production" === 'production' : options.speedy; 64967 this.tags = []; 64968 this.ctr = 0; 64969 this.nonce = options.nonce; // key is the value of the data-emotion attribute, it's used to identify different sheets 64970 64971 this.key = options.key; 64972 this.container = options.container; 64973 this.prepend = options.prepend; 64974 this.insertionPoint = options.insertionPoint; 64975 this.before = null; 64976 } 64977 64978 var _proto = StyleSheet.prototype; 64979 64980 _proto.hydrate = function hydrate(nodes) { 64981 nodes.forEach(this._insertTag); 64982 }; 64983 64984 _proto.insert = function insert(rule) { 64985 // the max length is how many rules we have per style tag, it's 65000 in speedy mode 64986 // it's 1 in dev because we insert source maps that map a single rule to a location 64987 // and you can only have one source map per style tag 64988 if (this.ctr % (this.isSpeedy ? 65000 : 1) === 0) { 64989 this._insertTag(createStyleElement(this)); 64990 } 64991 64992 var tag = this.tags[this.tags.length - 1]; 64993 64994 if (false) { var isImportRule; } 64995 64996 if (this.isSpeedy) { 64997 var sheet = sheetForTag(tag); 64998 64999 try { 65000 // this is the ultrafast version, works across browsers 65001 // the big drawback is that the css won't be editable in devtools 65002 sheet.insertRule(rule, sheet.cssRules.length); 65003 } catch (e) { 65004 if (false) {} 65005 } 65006 } else { 65007 tag.appendChild(document.createTextNode(rule)); 65008 } 65009 65010 this.ctr++; 65011 }; 65012 65013 _proto.flush = function flush() { 65014 // $FlowFixMe 65015 this.tags.forEach(function (tag) { 65016 return tag.parentNode && tag.parentNode.removeChild(tag); 65017 }); 65018 this.tags = []; 65019 this.ctr = 0; 65020 65021 if (false) {} 65022 }; 65023 65024 return StyleSheet; 65025 }(); 65026 65027 65028 65029 ;// CONCATENATED MODULE: ./node_modules/stylis/src/Utility.js 65030 /** 65031 * @param {number} 65032 * @return {number} 65033 */ 65034 var abs = Math.abs 65035 65036 /** 65037 * @param {number} 65038 * @return {string} 65039 */ 65040 var Utility_from = String.fromCharCode 65041 65042 /** 65043 * @param {object} 65044 * @return {object} 65045 */ 65046 var Utility_assign = Object.assign 65047 65048 /** 65049 * @param {string} value 65050 * @param {number} length 65051 * @return {number} 65052 */ 65053 function hash (value, length) { 65054 return Utility_charat(value, 0) ^ 45 ? (((((((length << 2) ^ Utility_charat(value, 0)) << 2) ^ Utility_charat(value, 1)) << 2) ^ Utility_charat(value, 2)) << 2) ^ Utility_charat(value, 3) : 0 65055 } 65056 65057 /** 65058 * @param {string} value 65059 * @return {string} 65060 */ 65061 function trim (value) { 65062 return value.trim() 65063 } 65064 65065 /** 65066 * @param {string} value 65067 * @param {RegExp} pattern 65068 * @return {string?} 65069 */ 65070 function Utility_match (value, pattern) { 65071 return (value = pattern.exec(value)) ? value[0] : value 65072 } 65073 65074 /** 65075 * @param {string} value 65076 * @param {(string|RegExp)} pattern 65077 * @param {string} replacement 65078 * @return {string} 65079 */ 65080 function Utility_replace (value, pattern, replacement) { 65081 return value.replace(pattern, replacement) 65082 } 65083 65084 /** 65085 * @param {string} value 65086 * @param {string} search 65087 * @return {number} 65088 */ 65089 function indexof (value, search) { 65090 return value.indexOf(search) 65091 } 65092 65093 /** 65094 * @param {string} value 65095 * @param {number} index 65096 * @return {number} 65097 */ 65098 function Utility_charat (value, index) { 65099 return value.charCodeAt(index) | 0 65100 } 65101 65102 /** 65103 * @param {string} value 65104 * @param {number} begin 65105 * @param {number} end 65106 * @return {string} 65107 */ 65108 function Utility_substr (value, begin, end) { 65109 return value.slice(begin, end) 65110 } 65111 65112 /** 65113 * @param {string} value 65114 * @return {number} 65115 */ 65116 function Utility_strlen (value) { 65117 return value.length 65118 } 65119 65120 /** 65121 * @param {any[]} value 65122 * @return {number} 65123 */ 65124 function Utility_sizeof (value) { 65125 return value.length 65126 } 65127 65128 /** 65129 * @param {any} value 65130 * @param {any[]} array 65131 * @return {any} 65132 */ 65133 function Utility_append (value, array) { 65134 return array.push(value), value 65135 } 65136 65137 /** 65138 * @param {string[]} array 65139 * @param {function} callback 65140 * @return {string} 65141 */ 65142 function Utility_combine (array, callback) { 65143 return array.map(callback).join('') 65144 } 65145 65146 ;// CONCATENATED MODULE: ./node_modules/stylis/src/Tokenizer.js 65147 65148 65149 var line = 1 65150 var column = 1 65151 var Tokenizer_length = 0 65152 var Tokenizer_position = 0 65153 var Tokenizer_character = 0 65154 var characters = '' 65155 65156 /** 65157 * @param {string} value 65158 * @param {object | null} root 65159 * @param {object | null} parent 65160 * @param {string} type 65161 * @param {string[] | string} props 65162 * @param {object[] | string} children 65163 * @param {number} length 65164 */ 65165 function node (value, root, parent, type, props, children, length) { 65166 return {value: value, root: root, parent: parent, type: type, props: props, children: children, line: line, column: column, length: length, return: ''} 65167 } 65168 65169 /** 65170 * @param {object} root 65171 * @param {object} props 65172 * @return {object} 65173 */ 65174 function Tokenizer_copy (root, props) { 65175 return Utility_assign(node('', null, null, '', null, null, 0), root, {length: -root.length}, props) 65176 } 65177 65178 /** 65179 * @return {number} 65180 */ 65181 function Tokenizer_char () { 65182 return Tokenizer_character 65183 } 65184 65185 /** 65186 * @return {number} 65187 */ 65188 function prev () { 65189 Tokenizer_character = Tokenizer_position > 0 ? Utility_charat(characters, --Tokenizer_position) : 0 65190 65191 if (column--, Tokenizer_character === 10) 65192 column = 1, line-- 65193 65194 return Tokenizer_character 65195 } 65196 65197 /** 65198 * @return {number} 65199 */ 65200 function next () { 65201 Tokenizer_character = Tokenizer_position < Tokenizer_length ? Utility_charat(characters, Tokenizer_position++) : 0 65202 65203 if (column++, Tokenizer_character === 10) 65204 column = 1, line++ 65205 65206 return Tokenizer_character 65207 } 65208 65209 /** 65210 * @return {number} 65211 */ 65212 function peek () { 65213 return Utility_charat(characters, Tokenizer_position) 65214 } 65215 65216 /** 65217 * @return {number} 65218 */ 65219 function caret () { 65220 return Tokenizer_position 65221 } 65222 65223 /** 65224 * @param {number} begin 65225 * @param {number} end 65226 * @return {string} 65227 */ 65228 function slice (begin, end) { 65229 return Utility_substr(characters, begin, end) 65230 } 65231 65232 /** 65233 * @param {number} type 65234 * @return {number} 65235 */ 65236 function token (type) { 65237 switch (type) { 65238 // \0 \t \n \r \s whitespace token 65239 case 0: case 9: case 10: case 13: case 32: 65240 return 5 65241 // ! + , / > @ ~ isolate token 65242 case 33: case 43: case 44: case 47: case 62: case 64: case 126: 65243 // ; { } breakpoint token 65244 case 59: case 123: case 125: 65245 return 4 65246 // : accompanied token 65247 case 58: 65248 return 3 65249 // " ' ( [ opening delimit token 65250 case 34: case 39: case 40: case 91: 65251 return 2 65252 // ) ] closing delimit token 65253 case 41: case 93: 65254 return 1 65255 } 65256 65257 return 0 65258 } 65259 65260 /** 65261 * @param {string} value 65262 * @return {any[]} 65263 */ 65264 function alloc (value) { 65265 return line = column = 1, Tokenizer_length = Utility_strlen(characters = value), Tokenizer_position = 0, [] 65266 } 65267 65268 /** 65269 * @param {any} value 65270 * @return {any} 65271 */ 65272 function dealloc (value) { 65273 return characters = '', value 65274 } 65275 65276 /** 65277 * @param {number} type 65278 * @return {string} 65279 */ 65280 function delimit (type) { 65281 return trim(slice(Tokenizer_position - 1, delimiter(type === 91 ? type + 2 : type === 40 ? type + 1 : type))) 65282 } 65283 65284 /** 65285 * @param {string} value 65286 * @return {string[]} 65287 */ 65288 function Tokenizer_tokenize (value) { 65289 return dealloc(tokenizer(alloc(value))) 65290 } 65291 65292 /** 65293 * @param {number} type 65294 * @return {string} 65295 */ 65296 function whitespace (type) { 65297 while (Tokenizer_character = peek()) 65298 if (Tokenizer_character < 33) 65299 next() 65300 else 65301 break 65302 65303 return token(type) > 2 || token(Tokenizer_character) > 3 ? '' : ' ' 65304 } 65305 65306 /** 65307 * @param {string[]} children 65308 * @return {string[]} 65309 */ 65310 function tokenizer (children) { 65311 while (next()) 65312 switch (token(Tokenizer_character)) { 65313 case 0: append(identifier(Tokenizer_position - 1), children) 65314 break 65315 case 2: append(delimit(Tokenizer_character), children) 65316 break 65317 default: append(from(Tokenizer_character), children) 65318 } 65319 65320 return children 65321 } 65322 65323 /** 65324 * @param {number} index 65325 * @param {number} count 65326 * @return {string} 65327 */ 65328 function escaping (index, count) { 65329 while (--count && next()) 65330 // not 0-9 A-F a-f 65331 if (Tokenizer_character < 48 || Tokenizer_character > 102 || (Tokenizer_character > 57 && Tokenizer_character < 65) || (Tokenizer_character > 70 && Tokenizer_character < 97)) 65332 break 65333 65334 return slice(index, caret() + (count < 6 && peek() == 32 && next() == 32)) 65335 } 65336 65337 /** 65338 * @param {number} type 65339 * @return {number} 65340 */ 65341 function delimiter (type) { 65342 while (next()) 65343 switch (Tokenizer_character) { 65344 // ] ) " ' 65345 case type: 65346 return Tokenizer_position 65347 // " ' 65348 case 34: case 39: 65349 if (type !== 34 && type !== 39) 65350 delimiter(Tokenizer_character) 65351 break 65352 // ( 65353 case 40: 65354 if (type === 41) 65355 delimiter(type) 65356 break 65357 // \ 65358 case 92: 65359 next() 65360 break 65361 } 65362 65363 return Tokenizer_position 65364 } 65365 65366 /** 65367 * @param {number} type 65368 * @param {number} index 65369 * @return {number} 65370 */ 65371 function commenter (type, index) { 65372 while (next()) 65373 // // 65374 if (type + Tokenizer_character === 47 + 10) 65375 break 65376 // /* 65377 else if (type + Tokenizer_character === 42 + 42 && peek() === 47) 65378 break 65379 65380 return '/*' + slice(index, Tokenizer_position - 1) + '*' + Utility_from(type === 47 ? type : next()) 65381 } 65382 65383 /** 65384 * @param {number} index 65385 * @return {string} 65386 */ 65387 function identifier (index) { 65388 while (!token(peek())) 65389 next() 65390 65391 return slice(index, Tokenizer_position) 65392 } 65393 65394 ;// CONCATENATED MODULE: ./node_modules/stylis/src/Enum.js 65395 var Enum_MS = '-ms-' 65396 var Enum_MOZ = '-moz-' 65397 var Enum_WEBKIT = '-webkit-' 65398 65399 var COMMENT = 'comm' 65400 var Enum_RULESET = 'rule' 65401 var Enum_DECLARATION = 'decl' 65402 65403 var PAGE = '@page' 65404 var MEDIA = '@media' 65405 var IMPORT = '@import' 65406 var CHARSET = '@charset' 65407 var VIEWPORT = '@viewport' 65408 var SUPPORTS = '@supports' 65409 var DOCUMENT = '@document' 65410 var NAMESPACE = '@namespace' 65411 var Enum_KEYFRAMES = '@keyframes' 65412 var FONT_FACE = '@font-face' 65413 var COUNTER_STYLE = '@counter-style' 65414 var FONT_FEATURE_VALUES = '@font-feature-values' 65415 65416 ;// CONCATENATED MODULE: ./node_modules/stylis/src/Serializer.js 65417 65418 65419 65420 /** 65421 * @param {object[]} children 65422 * @param {function} callback 65423 * @return {string} 65424 */ 65425 function Serializer_serialize (children, callback) { 65426 var output = '' 65427 var length = Utility_sizeof(children) 65428 65429 for (var i = 0; i < length; i++) 65430 output += callback(children[i], i, children, callback) || '' 65431 65432 return output 65433 } 65434 65435 /** 65436 * @param {object} element 65437 * @param {number} index 65438 * @param {object[]} children 65439 * @param {function} callback 65440 * @return {string} 65441 */ 65442 function Serializer_stringify (element, index, children, callback) { 65443 switch (element.type) { 65444 case IMPORT: case Enum_DECLARATION: return element.return = element.return || element.value 65445 case COMMENT: return '' 65446 case Enum_KEYFRAMES: return element.return = element.value + '{' + Serializer_serialize(element.children, callback) + '}' 65447 case Enum_RULESET: element.value = element.props.join(',') 65448 } 65449 65450 return Utility_strlen(children = Serializer_serialize(element.children, callback)) ? element.return = element.value + '{' + children + '}' : '' 65451 } 65452 65453 ;// CONCATENATED MODULE: ./node_modules/stylis/src/Middleware.js 65454 65455 65456 65457 65458 65459 65460 /** 65461 * @param {function[]} collection 65462 * @return {function} 65463 */ 65464 function middleware (collection) { 65465 var length = Utility_sizeof(collection) 65466 65467 return function (element, index, children, callback) { 65468 var output = '' 65469 65470 for (var i = 0; i < length; i++) 65471 output += collection[i](element, index, children, callback) || '' 65472 65473 return output 65474 } 65475 } 65476 65477 /** 65478 * @param {function} callback 65479 * @return {function} 65480 */ 65481 function rulesheet (callback) { 65482 return function (element) { 65483 if (!element.root) 65484 if (element = element.return) 65485 callback(element) 65486 } 65487 } 65488 65489 /** 65490 * @param {object} element 65491 * @param {number} index 65492 * @param {object[]} children 65493 * @param {function} callback 65494 */ 65495 function prefixer (element, index, children, callback) { 65496 if (element.length > -1) 65497 if (!element.return) 65498 switch (element.type) { 65499 case DECLARATION: element.return = prefix(element.value, element.length, children) 65500 return 65501 case KEYFRAMES: 65502 return serialize([copy(element, {value: replace(element.value, '@', '@' + WEBKIT)})], callback) 65503 case RULESET: 65504 if (element.length) 65505 return combine(element.props, function (value) { 65506 switch (match(value, /(::plac\w+|:read-\w+)/)) { 65507 // :read-(only|write) 65508 case ':read-only': case ':read-write': 65509 return serialize([copy(element, {props: [replace(value, /:(read-\w+)/, ':' + MOZ + '$1')]})], callback) 65510 // :placeholder 65511 case '::placeholder': 65512 return serialize([ 65513 copy(element, {props: [replace(value, /:(plac\w+)/, ':' + WEBKIT + 'input-$1')]}), 65514 copy(element, {props: [replace(value, /:(plac\w+)/, ':' + MOZ + '$1')]}), 65515 copy(element, {props: [replace(value, /:(plac\w+)/, MS + 'input-$1')]}) 65516 ], callback) 65517 } 65518 65519 return '' 65520 }) 65521 } 65522 } 65523 65524 /** 65525 * @param {object} element 65526 * @param {number} index 65527 * @param {object[]} children 65528 */ 65529 function namespace (element) { 65530 switch (element.type) { 65531 case RULESET: 65532 element.props = element.props.map(function (value) { 65533 return combine(tokenize(value), function (value, index, children) { 65534 switch (charat(value, 0)) { 65535 // \f 65536 case 12: 65537 return substr(value, 1, strlen(value)) 65538 // \0 ( + > ~ 65539 case 0: case 40: case 43: case 62: case 126: 65540 return value 65541 // : 65542 case 58: 65543 if (children[++index] === 'global') 65544 children[index] = '', children[++index] = '\f' + substr(children[index], index = 1, -1) 65545 // \s 65546 case 32: 65547 return index === 1 ? '' : value 65548 default: 65549 switch (index) { 65550 case 0: element = value 65551 return sizeof(children) > 1 ? '' : value 65552 case index = sizeof(children) - 1: case 2: 65553 return index === 2 ? value + element + element : value + element 65554 default: 65555 return value 65556 } 65557 } 65558 }) 65559 }) 65560 } 65561 } 65562 65563 ;// CONCATENATED MODULE: ./node_modules/stylis/src/Parser.js 65564 65565 65566 65567 65568 /** 65569 * @param {string} value 65570 * @return {object[]} 65571 */ 65572 function compile (value) { 65573 return dealloc(Parser_parse('', null, null, null, [''], value = alloc(value), 0, [0], value)) 65574 } 65575 65576 /** 65577 * @param {string} value 65578 * @param {object} root 65579 * @param {object?} parent 65580 * @param {string[]} rule 65581 * @param {string[]} rules 65582 * @param {string[]} rulesets 65583 * @param {number[]} pseudo 65584 * @param {number[]} points 65585 * @param {string[]} declarations 65586 * @return {object} 65587 */ 65588 function Parser_parse (value, root, parent, rule, rules, rulesets, pseudo, points, declarations) { 65589 var index = 0 65590 var offset = 0 65591 var length = pseudo 65592 var atrule = 0 65593 var property = 0 65594 var previous = 0 65595 var variable = 1 65596 var scanning = 1 65597 var ampersand = 1 65598 var character = 0 65599 var type = '' 65600 var props = rules 65601 var children = rulesets 65602 var reference = rule 65603 var characters = type 65604 65605 while (scanning) 65606 switch (previous = character, character = next()) { 65607 // ( 65608 case 40: 65609 if (previous != 108 && Utility_charat(characters, length - 1) == 58) { 65610 if (indexof(characters += Utility_replace(delimit(character), '&', '&\f'), '&\f') != -1) 65611 ampersand = -1 65612 break 65613 } 65614 // " ' [ 65615 case 34: case 39: case 91: 65616 characters += delimit(character) 65617 break 65618 // \t \n \r \s 65619 case 9: case 10: case 13: case 32: 65620 characters += whitespace(previous) 65621 break 65622 // \ 65623 case 92: 65624 characters += escaping(caret() - 1, 7) 65625 continue 65626 // / 65627 case 47: 65628 switch (peek()) { 65629 case 42: case 47: 65630 Utility_append(Parser_comment(commenter(next(), caret()), root, parent), declarations) 65631 break 65632 default: 65633 characters += '/' 65634 } 65635 break 65636 // { 65637 case 123 * variable: 65638 points[index++] = Utility_strlen(characters) * ampersand 65639 // } ; \0 65640 case 125 * variable: case 59: case 0: 65641 switch (character) { 65642 // \0 } 65643 case 0: case 125: scanning = 0 65644 // ; 65645 case 59 + offset: 65646 if (property > 0 && (Utility_strlen(characters) - length)) 65647 Utility_append(property > 32 ? declaration(characters + ';', rule, parent, length - 1) : declaration(Utility_replace(characters, ' ', '') + ';', rule, parent, length - 2), declarations) 65648 break 65649 // @ ; 65650 case 59: characters += ';' 65651 // { rule/at-rule 65652 default: 65653 Utility_append(reference = ruleset(characters, root, parent, index, offset, rules, points, type, props = [], children = [], length), rulesets) 65654 65655 if (character === 123) 65656 if (offset === 0) 65657 Parser_parse(characters, root, reference, reference, props, rulesets, length, points, children) 65658 else 65659 switch (atrule === 99 && Utility_charat(characters, 3) === 110 ? 100 : atrule) { 65660 // d m s 65661 case 100: case 109: case 115: 65662 Parser_parse(value, reference, reference, rule && Utility_append(ruleset(value, reference, reference, 0, 0, rules, points, type, rules, props = [], length), children), rules, children, length, points, rule ? props : children) 65663 break 65664 default: 65665 Parser_parse(characters, reference, reference, reference, [''], children, 0, points, children) 65666 } 65667 } 65668 65669 index = offset = property = 0, variable = ampersand = 1, type = characters = '', length = pseudo 65670 break 65671 // : 65672 case 58: 65673 length = 1 + Utility_strlen(characters), property = previous 65674 default: 65675 if (variable < 1) 65676 if (character == 123) 65677 --variable 65678 else if (character == 125 && variable++ == 0 && prev() == 125) 65679 continue 65680 65681 switch (characters += Utility_from(character), character * variable) { 65682 // & 65683 case 38: 65684 ampersand = offset > 0 ? 1 : (characters += '\f', -1) 65685 break 65686 // , 65687 case 44: 65688 points[index++] = (Utility_strlen(characters) - 1) * ampersand, ampersand = 1 65689 break 65690 // @ 65691 case 64: 65692 // - 65693 if (peek() === 45) 65694 characters += delimit(next()) 65695 65696 atrule = peek(), offset = length = Utility_strlen(type = characters += identifier(caret())), character++ 65697 break 65698 // - 65699 case 45: 65700 if (previous === 45 && Utility_strlen(characters) == 2) 65701 variable = 0 65702 } 65703 } 65704 65705 return rulesets 65706 } 65707 65708 /** 65709 * @param {string} value 65710 * @param {object} root 65711 * @param {object?} parent 65712 * @param {number} index 65713 * @param {number} offset 65714 * @param {string[]} rules 65715 * @param {number[]} points 65716 * @param {string} type 65717 * @param {string[]} props 65718 * @param {string[]} children 65719 * @param {number} length 65720 * @return {object} 65721 */ 65722 function ruleset (value, root, parent, index, offset, rules, points, type, props, children, length) { 65723 var post = offset - 1 65724 var rule = offset === 0 ? rules : [''] 65725 var size = Utility_sizeof(rule) 65726 65727 for (var i = 0, j = 0, k = 0; i < index; ++i) 65728 for (var x = 0, y = Utility_substr(value, post + 1, post = abs(j = points[i])), z = value; x < size; ++x) 65729 if (z = trim(j > 0 ? rule[x] + ' ' + y : Utility_replace(y, /&\f/g, rule[x]))) 65730 props[k++] = z 65731 65732 return node(value, root, parent, offset === 0 ? Enum_RULESET : type, props, children, length) 65733 } 65734 65735 /** 65736 * @param {number} value 65737 * @param {object} root 65738 * @param {object?} parent 65739 * @return {object} 65740 */ 65741 function Parser_comment (value, root, parent) { 65742 return node(value, root, parent, COMMENT, Utility_from(Tokenizer_char()), Utility_substr(value, 2, -2), 0) 65743 } 65744 65745 /** 65746 * @param {string} value 65747 * @param {object} root 65748 * @param {object?} parent 65749 * @param {number} length 65750 * @return {object} 65751 */ 65752 function declaration (value, root, parent, length) { 65753 return node(value, root, parent, Enum_DECLARATION, Utility_substr(value, 0, length), Utility_substr(value, length + 1, -1), length) 65754 } 65755 65756 ;// CONCATENATED MODULE: ./node_modules/@emotion/cache/dist/emotion-cache.browser.esm.js 65757 65758 65759 65760 65761 65762 var identifierWithPointTracking = function identifierWithPointTracking(begin, points, index) { 65763 var previous = 0; 65764 var character = 0; 65765 65766 while (true) { 65767 previous = character; 65768 character = peek(); // &\f 65769 65770 if (previous === 38 && character === 12) { 65771 points[index] = 1; 65772 } 65773 65774 if (token(character)) { 65775 break; 65776 } 65777 65778 next(); 65779 } 65780 65781 return slice(begin, Tokenizer_position); 65782 }; 65783 65784 var toRules = function toRules(parsed, points) { 65785 // pretend we've started with a comma 65786 var index = -1; 65787 var character = 44; 65788 65789 do { 65790 switch (token(character)) { 65791 case 0: 65792 // &\f 65793 if (character === 38 && peek() === 12) { 65794 // this is not 100% correct, we don't account for literal sequences here - like for example quoted strings 65795 // stylis inserts \f after & to know when & where it should replace this sequence with the context selector 65796 // and when it should just concatenate the outer and inner selectors 65797 // it's very unlikely for this sequence to actually appear in a different context, so we just leverage this fact here 65798 points[index] = 1; 65799 } 65800 65801 parsed[index] += identifierWithPointTracking(Tokenizer_position - 1, points, index); 65802 break; 65803 65804 case 2: 65805 parsed[index] += delimit(character); 65806 break; 65807 65808 case 4: 65809 // comma 65810 if (character === 44) { 65811 // colon 65812 parsed[++index] = peek() === 58 ? '&\f' : ''; 65813 points[index] = parsed[index].length; 65814 break; 65815 } 65816 65817 // fallthrough 65818 65819 default: 65820 parsed[index] += Utility_from(character); 65821 } 65822 } while (character = next()); 65823 65824 return parsed; 65825 }; 65826 65827 var getRules = function getRules(value, points) { 65828 return dealloc(toRules(alloc(value), points)); 65829 }; // WeakSet would be more appropriate, but only WeakMap is supported in IE11 65830 65831 65832 var fixedElements = /* #__PURE__ */new WeakMap(); 65833 var compat = function compat(element) { 65834 if (element.type !== 'rule' || !element.parent || // positive .length indicates that this rule contains pseudo 65835 // negative .length indicates that this rule has been already prefixed 65836 element.length < 1) { 65837 return; 65838 } 65839 65840 var value = element.value, 65841 parent = element.parent; 65842 var isImplicitRule = element.column === parent.column && element.line === parent.line; 65843 65844 while (parent.type !== 'rule') { 65845 parent = parent.parent; 65846 if (!parent) return; 65847 } // short-circuit for the simplest case 65848 65849 65850 if (element.props.length === 1 && value.charCodeAt(0) !== 58 65851 /* colon */ 65852 && !fixedElements.get(parent)) { 65853 return; 65854 } // if this is an implicitly inserted rule (the one eagerly inserted at the each new nested level) 65855 // then the props has already been manipulated beforehand as they that array is shared between it and its "rule parent" 65856 65857 65858 if (isImplicitRule) { 65859 return; 65860 } 65861 65862 fixedElements.set(element, true); 65863 var points = []; 65864 var rules = getRules(value, points); 65865 var parentRules = parent.props; 65866 65867 for (var i = 0, k = 0; i < rules.length; i++) { 65868 for (var j = 0; j < parentRules.length; j++, k++) { 65869 element.props[k] = points[i] ? rules[i].replace(/&\f/g, parentRules[j]) : parentRules[j] + " " + rules[i]; 65870 } 65871 } 65872 }; 65873 var removeLabel = function removeLabel(element) { 65874 if (element.type === 'decl') { 65875 var value = element.value; 65876 65877 if ( // charcode for l 65878 value.charCodeAt(0) === 108 && // charcode for b 65879 value.charCodeAt(2) === 98) { 65880 // this ignores label 65881 element["return"] = ''; 65882 element.value = ''; 65883 } 65884 } 65885 }; 65886 var ignoreFlag = 'emotion-disable-server-rendering-unsafe-selector-warning-please-do-not-use-this-the-warning-exists-for-a-reason'; 65887 65888 var isIgnoringComment = function isIgnoringComment(element) { 65889 return element.type === 'comm' && element.children.indexOf(ignoreFlag) > -1; 65890 }; 65891 65892 var createUnsafeSelectorsAlarm = function createUnsafeSelectorsAlarm(cache) { 65893 return function (element, index, children) { 65894 if (element.type !== 'rule' || cache.compat) return; 65895 var unsafePseudoClasses = element.value.match(/(:first|:nth|:nth-last)-child/g); 65896 65897 if (unsafePseudoClasses) { 65898 var isNested = element.parent === children[0]; // in nested rules comments become children of the "auto-inserted" rule 65899 // 65900 // considering this input: 65901 // .a { 65902 // .b /* comm */ {} 65903 // color: hotpink; 65904 // } 65905 // we get output corresponding to this: 65906 // .a { 65907 // & { 65908 // /* comm */ 65909 // color: hotpink; 65910 // } 65911 // .b {} 65912 // } 65913 65914 var commentContainer = isNested ? children[0].children : // global rule at the root level 65915 children; 65916 65917 for (var i = commentContainer.length - 1; i >= 0; i--) { 65918 var node = commentContainer[i]; 65919 65920 if (node.line < element.line) { 65921 break; 65922 } // it is quite weird but comments are *usually* put at `column: element.column - 1` 65923 // so we seek *from the end* for the node that is earlier than the rule's `element` and check that 65924 // this will also match inputs like this: 65925 // .a { 65926 // /* comm */ 65927 // .b {} 65928 // } 65929 // 65930 // but that is fine 65931 // 65932 // it would be the easiest to change the placement of the comment to be the first child of the rule: 65933 // .a { 65934 // .b { /* comm */ } 65935 // } 65936 // with such inputs we wouldn't have to search for the comment at all 65937 // TODO: consider changing this comment placement in the next major version 65938 65939 65940 if (node.column < element.column) { 65941 if (isIgnoringComment(node)) { 65942 return; 65943 } 65944 65945 break; 65946 } 65947 } 65948 65949 unsafePseudoClasses.forEach(function (unsafePseudoClass) { 65950 console.error("The pseudo class \"" + unsafePseudoClass + "\" is potentially unsafe when doing server-side rendering. Try changing it to \"" + unsafePseudoClass.split('-child')[0] + "-of-type\"."); 65951 }); 65952 } 65953 }; 65954 }; 65955 65956 var isImportRule = function isImportRule(element) { 65957 return element.type.charCodeAt(1) === 105 && element.type.charCodeAt(0) === 64; 65958 }; 65959 65960 var isPrependedWithRegularRules = function isPrependedWithRegularRules(index, children) { 65961 for (var i = index - 1; i >= 0; i--) { 65962 if (!isImportRule(children[i])) { 65963 return true; 65964 } 65965 } 65966 65967 return false; 65968 }; // use this to remove incorrect elements from further processing 65969 // so they don't get handed to the `sheet` (or anything else) 65970 // as that could potentially lead to additional logs which in turn could be overhelming to the user 65971 65972 65973 var nullifyElement = function nullifyElement(element) { 65974 element.type = ''; 65975 element.value = ''; 65976 element["return"] = ''; 65977 element.children = ''; 65978 element.props = ''; 65979 }; 65980 65981 var incorrectImportAlarm = function incorrectImportAlarm(element, index, children) { 65982 if (!isImportRule(element)) { 65983 return; 65984 } 65985 65986 if (element.parent) { 65987 console.error("`@import` rules can't be nested inside other rules. Please move it to the top level and put it before regular rules. Keep in mind that they can only be used within global styles."); 65988 nullifyElement(element); 65989 } else if (isPrependedWithRegularRules(index, children)) { 65990 console.error("`@import` rules can't be after other rules. Please put your `@import` rules before your other rules."); 65991 nullifyElement(element); 65992 } 65993 }; 65994 65995 /* eslint-disable no-fallthrough */ 65996 65997 function emotion_cache_browser_esm_prefix(value, length) { 65998 switch (hash(value, length)) { 65999 // color-adjust 66000 case 5103: 66001 return Enum_WEBKIT + 'print-' + value + value; 66002 // animation, animation-(delay|direction|duration|fill-mode|iteration-count|name|play-state|timing-function) 66003 66004 case 5737: 66005 case 4201: 66006 case 3177: 66007 case 3433: 66008 case 1641: 66009 case 4457: 66010 case 2921: // text-decoration, filter, clip-path, backface-visibility, column, box-decoration-break 66011 66012 case 5572: 66013 case 6356: 66014 case 5844: 66015 case 3191: 66016 case 6645: 66017 case 3005: // mask, mask-image, mask-(mode|clip|size), mask-(repeat|origin), mask-position, mask-composite, 66018 66019 case 6391: 66020 case 5879: 66021 case 5623: 66022 case 6135: 66023 case 4599: 66024 case 4855: // background-clip, columns, column-(count|fill|gap|rule|rule-color|rule-style|rule-width|span|width) 66025 66026 case 4215: 66027 case 6389: 66028 case 5109: 66029 case 5365: 66030 case 5621: 66031 case 3829: 66032 return Enum_WEBKIT + value + value; 66033 // appearance, user-select, transform, hyphens, text-size-adjust 66034 66035 case 5349: 66036 case 4246: 66037 case 4810: 66038 case 6968: 66039 case 2756: 66040 return Enum_WEBKIT + value + Enum_MOZ + value + Enum_MS + value + value; 66041 // flex, flex-direction 66042 66043 case 6828: 66044 case 4268: 66045 return Enum_WEBKIT + value + Enum_MS + value + value; 66046 // order 66047 66048 case 6165: 66049 return Enum_WEBKIT + value + Enum_MS + 'flex-' + value + value; 66050 // align-items 66051 66052 case 5187: 66053 return Enum_WEBKIT + value + Utility_replace(value, /(\w+).+(:[^]+)/, Enum_WEBKIT + 'box-$1$2' + Enum_MS + 'flex-$1$2') + value; 66054 // align-self 66055 66056 case 5443: 66057 return Enum_WEBKIT + value + Enum_MS + 'flex-item-' + Utility_replace(value, /flex-|-self/, '') + value; 66058 // align-content 66059 66060 case 4675: 66061 return Enum_WEBKIT + value + Enum_MS + 'flex-line-pack' + Utility_replace(value, /align-content|flex-|-self/, '') + value; 66062 // flex-shrink 66063 66064 case 5548: 66065 return Enum_WEBKIT + value + Enum_MS + Utility_replace(value, 'shrink', 'negative') + value; 66066 // flex-basis 66067 66068 case 5292: 66069 return Enum_WEBKIT + value + Enum_MS + Utility_replace(value, 'basis', 'preferred-size') + value; 66070 // flex-grow 66071 66072 case 6060: 66073 return Enum_WEBKIT + 'box-' + Utility_replace(value, '-grow', '') + Enum_WEBKIT + value + Enum_MS + Utility_replace(value, 'grow', 'positive') + value; 66074 // transition 66075 66076 case 4554: 66077 return Enum_WEBKIT + Utility_replace(value, /([^-])(transform)/g, '$1' + Enum_WEBKIT + '$2') + value; 66078 // cursor 66079 66080 case 6187: 66081 return Utility_replace(Utility_replace(Utility_replace(value, /(zoom-|grab)/, Enum_WEBKIT + '$1'), /(image-set)/, Enum_WEBKIT + '$1'), value, '') + value; 66082 // background, background-image 66083 66084 case 5495: 66085 case 3959: 66086 return Utility_replace(value, /(image-set\([^]*)/, Enum_WEBKIT + '$1' + '$`$1'); 66087 // justify-content 66088 66089 case 4968: 66090 return Utility_replace(Utility_replace(value, /(.+:)(flex-)?(.*)/, Enum_WEBKIT + 'box-pack:$3' + Enum_MS + 'flex-pack:$3'), /s.+-b[^;]+/, 'justify') + Enum_WEBKIT + value + value; 66091 // (margin|padding)-inline-(start|end) 66092 66093 case 4095: 66094 case 3583: 66095 case 4068: 66096 case 2532: 66097 return Utility_replace(value, /(.+)-inline(.+)/, Enum_WEBKIT + '$1$2') + value; 66098 // (min|max)?(width|height|inline-size|block-size) 66099 66100 case 8116: 66101 case 7059: 66102 case 5753: 66103 case 5535: 66104 case 5445: 66105 case 5701: 66106 case 4933: 66107 case 4677: 66108 case 5533: 66109 case 5789: 66110 case 5021: 66111 case 4765: 66112 // stretch, max-content, min-content, fill-available 66113 if (Utility_strlen(value) - 1 - length > 6) switch (Utility_charat(value, length + 1)) { 66114 // (m)ax-content, (m)in-content 66115 case 109: 66116 // - 66117 if (Utility_charat(value, length + 4) !== 45) break; 66118 // (f)ill-available, (f)it-content 66119 66120 case 102: 66121 return Utility_replace(value, /(.+:)(.+)-([^]+)/, '$1' + Enum_WEBKIT + '$2-$3' + '$1' + Enum_MOZ + (Utility_charat(value, length + 3) == 108 ? '$3' : '$2-$3')) + value; 66122 // (s)tretch 66123 66124 case 115: 66125 return ~indexof(value, 'stretch') ? emotion_cache_browser_esm_prefix(Utility_replace(value, 'stretch', 'fill-available'), length) + value : value; 66126 } 66127 break; 66128 // position: sticky 66129 66130 case 4949: 66131 // (s)ticky? 66132 if (Utility_charat(value, length + 1) !== 115) break; 66133 // display: (flex|inline-flex) 66134 66135 case 6444: 66136 switch (Utility_charat(value, Utility_strlen(value) - 3 - (~indexof(value, '!important') && 10))) { 66137 // stic(k)y 66138 case 107: 66139 return Utility_replace(value, ':', ':' + Enum_WEBKIT) + value; 66140 // (inline-)?fl(e)x 66141 66142 case 101: 66143 return Utility_replace(value, /(.+:)([^;!]+)(;|!.+)?/, '$1' + Enum_WEBKIT + (Utility_charat(value, 14) === 45 ? 'inline-' : '') + 'box$3' + '$1' + Enum_WEBKIT + '$2$3' + '$1' + Enum_MS + '$2box$3') + value; 66144 } 66145 66146 break; 66147 // writing-mode 66148 66149 case 5936: 66150 switch (Utility_charat(value, length + 11)) { 66151 // vertical-l(r) 66152 case 114: 66153 return Enum_WEBKIT + value + Enum_MS + Utility_replace(value, /[svh]\w+-[tblr]{2}/, 'tb') + value; 66154 // vertical-r(l) 66155 66156 case 108: 66157 return Enum_WEBKIT + value + Enum_MS + Utility_replace(value, /[svh]\w+-[tblr]{2}/, 'tb-rl') + value; 66158 // horizontal(-)tb 66159 66160 case 45: 66161 return Enum_WEBKIT + value + Enum_MS + Utility_replace(value, /[svh]\w+-[tblr]{2}/, 'lr') + value; 66162 } 66163 66164 return Enum_WEBKIT + value + Enum_MS + value + value; 66165 } 66166 66167 return value; 66168 } 66169 66170 var emotion_cache_browser_esm_prefixer = function prefixer(element, index, children, callback) { 66171 if (element.length > -1) if (!element["return"]) switch (element.type) { 66172 case Enum_DECLARATION: 66173 element["return"] = emotion_cache_browser_esm_prefix(element.value, element.length); 66174 break; 66175 66176 case Enum_KEYFRAMES: 66177 return Serializer_serialize([Tokenizer_copy(element, { 66178 value: Utility_replace(element.value, '@', '@' + Enum_WEBKIT) 66179 })], callback); 66180 66181 case Enum_RULESET: 66182 if (element.length) return Utility_combine(element.props, function (value) { 66183 switch (Utility_match(value, /(::plac\w+|:read-\w+)/)) { 66184 // :read-(only|write) 66185 case ':read-only': 66186 case ':read-write': 66187 return Serializer_serialize([Tokenizer_copy(element, { 66188 props: [Utility_replace(value, /:(read-\w+)/, ':' + Enum_MOZ + '$1')] 66189 })], callback); 66190 // :placeholder 66191 66192 case '::placeholder': 66193 return Serializer_serialize([Tokenizer_copy(element, { 66194 props: [Utility_replace(value, /:(plac\w+)/, ':' + Enum_WEBKIT + 'input-$1')] 66195 }), Tokenizer_copy(element, { 66196 props: [Utility_replace(value, /:(plac\w+)/, ':' + Enum_MOZ + '$1')] 66197 }), Tokenizer_copy(element, { 66198 props: [Utility_replace(value, /:(plac\w+)/, Enum_MS + 'input-$1')] 66199 })], callback); 66200 } 66201 66202 return ''; 66203 }); 66204 } 66205 }; 66206 66207 var defaultStylisPlugins = [emotion_cache_browser_esm_prefixer]; 66208 66209 var emotion_cache_browser_esm_createCache = function createCache(options) { 66210 var key = options.key; 66211 66212 if (false) {} 66213 66214 if ( key === 'css') { 66215 var ssrStyles = document.querySelectorAll("style[data-emotion]:not([data-s])"); // get SSRed styles out of the way of React's hydration 66216 // document.head is a safe place to move them to(though note document.head is not necessarily the last place they will be) 66217 // note this very very intentionally targets all style elements regardless of the key to ensure 66218 // that creating a cache works inside of render of a React component 66219 66220 Array.prototype.forEach.call(ssrStyles, function (node) { 66221 // we want to only move elements which have a space in the data-emotion attribute value 66222 // because that indicates that it is an Emotion 11 server-side rendered style elements 66223 // while we will already ignore Emotion 11 client-side inserted styles because of the :not([data-s]) part in the selector 66224 // Emotion 10 client-side inserted styles did not have data-s (but importantly did not have a space in their data-emotion attributes) 66225 // so checking for the space ensures that loading Emotion 11 after Emotion 10 has inserted some styles 66226 // will not result in the Emotion 10 styles being destroyed 66227 var dataEmotionAttribute = node.getAttribute('data-emotion'); 66228 66229 if (dataEmotionAttribute.indexOf(' ') === -1) { 66230 return; 66231 } 66232 document.head.appendChild(node); 66233 node.setAttribute('data-s', ''); 66234 }); 66235 } 66236 66237 var stylisPlugins = options.stylisPlugins || defaultStylisPlugins; 66238 66239 if (false) {} 66240 66241 var inserted = {}; 66242 var container; 66243 var nodesToHydrate = []; 66244 66245 { 66246 container = options.container || document.head; 66247 Array.prototype.forEach.call( // this means we will ignore elements which don't have a space in them which 66248 // means that the style elements we're looking at are only Emotion 11 server-rendered style elements 66249 document.querySelectorAll("style[data-emotion^=\"" + key + " \"]"), function (node) { 66250 var attrib = node.getAttribute("data-emotion").split(' '); // $FlowFixMe 66251 66252 for (var i = 1; i < attrib.length; i++) { 66253 inserted[attrib[i]] = true; 66254 } 66255 66256 nodesToHydrate.push(node); 66257 }); 66258 } 66259 66260 var _insert; 66261 66262 var omnipresentPlugins = [compat, removeLabel]; 66263 66264 if (false) {} 66265 66266 { 66267 var currentSheet; 66268 var finalizingPlugins = [Serializer_stringify, false ? 0 : rulesheet(function (rule) { 66269 currentSheet.insert(rule); 66270 })]; 66271 var serializer = middleware(omnipresentPlugins.concat(stylisPlugins, finalizingPlugins)); 66272 66273 var stylis = function stylis(styles) { 66274 return Serializer_serialize(compile(styles), serializer); 66275 }; 66276 66277 _insert = function insert(selector, serialized, sheet, shouldCache) { 66278 currentSheet = sheet; 66279 66280 if (false) {} 66281 66282 stylis(selector ? selector + "{" + serialized.styles + "}" : serialized.styles); 66283 66284 if (shouldCache) { 66285 cache.inserted[serialized.name] = true; 66286 } 66287 }; 66288 } 66289 66290 var cache = { 66291 key: key, 66292 sheet: new StyleSheet({ 66293 key: key, 66294 container: container, 66295 nonce: options.nonce, 66296 speedy: options.speedy, 66297 prepend: options.prepend, 66298 insertionPoint: options.insertionPoint 66299 }), 66300 nonce: options.nonce, 66301 inserted: inserted, 66302 registered: {}, 66303 insert: _insert 66304 }; 66305 cache.sheet.hydrate(nodesToHydrate); 66306 return cache; 66307 }; 66308 66309 /* harmony default export */ const emotion_cache_browser_esm = (emotion_cache_browser_esm_createCache); 66310 66311 ;// CONCATENATED MODULE: ./node_modules/@emotion/hash/dist/emotion-hash.esm.js 66312 /* eslint-disable */ 66313 // Inspired by https://github.com/garycourt/murmurhash-js 66314 // Ported from https://github.com/aappleby/smhasher/blob/61a0530f28277f2e850bfc39600ce61d02b518de/src/MurmurHash2.cpp#L37-L86 66315 function murmur2(str) { 66316 // 'm' and 'r' are mixing constants generated offline. 66317 // They're not really 'magic', they just happen to work well. 66318 // const m = 0x5bd1e995; 66319 // const r = 24; 66320 // Initialize the hash 66321 var h = 0; // Mix 4 bytes at a time into the hash 66322 66323 var k, 66324 i = 0, 66325 len = str.length; 66326 66327 for (; len >= 4; ++i, len -= 4) { 66328 k = str.charCodeAt(i) & 0xff | (str.charCodeAt(++i) & 0xff) << 8 | (str.charCodeAt(++i) & 0xff) << 16 | (str.charCodeAt(++i) & 0xff) << 24; 66329 k = 66330 /* Math.imul(k, m): */ 66331 (k & 0xffff) * 0x5bd1e995 + ((k >>> 16) * 0xe995 << 16); 66332 k ^= 66333 /* k >>> r: */ 66334 k >>> 24; 66335 h = 66336 /* Math.imul(k, m): */ 66337 (k & 0xffff) * 0x5bd1e995 + ((k >>> 16) * 0xe995 << 16) ^ 66338 /* Math.imul(h, m): */ 66339 (h & 0xffff) * 0x5bd1e995 + ((h >>> 16) * 0xe995 << 16); 66340 } // Handle the last few bytes of the input array 66341 66342 66343 switch (len) { 66344 case 3: 66345 h ^= (str.charCodeAt(i + 2) & 0xff) << 16; 66346 66347 case 2: 66348 h ^= (str.charCodeAt(i + 1) & 0xff) << 8; 66349 66350 case 1: 66351 h ^= str.charCodeAt(i) & 0xff; 66352 h = 66353 /* Math.imul(h, m): */ 66354 (h & 0xffff) * 0x5bd1e995 + ((h >>> 16) * 0xe995 << 16); 66355 } // Do a few final mixes of the hash to ensure the last few 66356 // bytes are well-incorporated. 66357 66358 66359 h ^= h >>> 13; 66360 h = 66361 /* Math.imul(h, m): */ 66362 (h & 0xffff) * 0x5bd1e995 + ((h >>> 16) * 0xe995 << 16); 66363 return ((h ^ h >>> 15) >>> 0).toString(36); 66364 } 66365 66366 /* harmony default export */ const emotion_hash_esm = (murmur2); 66367 66368 ;// CONCATENATED MODULE: ./node_modules/@emotion/unitless/dist/emotion-unitless.esm.js 66369 var unitlessKeys = { 66370 animationIterationCount: 1, 66371 borderImageOutset: 1, 66372 borderImageSlice: 1, 66373 borderImageWidth: 1, 66374 boxFlex: 1, 66375 boxFlexGroup: 1, 66376 boxOrdinalGroup: 1, 66377 columnCount: 1, 66378 columns: 1, 66379 flex: 1, 66380 flexGrow: 1, 66381 flexPositive: 1, 66382 flexShrink: 1, 66383 flexNegative: 1, 66384 flexOrder: 1, 66385 gridRow: 1, 66386 gridRowEnd: 1, 66387 gridRowSpan: 1, 66388 gridRowStart: 1, 66389 gridColumn: 1, 66390 gridColumnEnd: 1, 66391 gridColumnSpan: 1, 66392 gridColumnStart: 1, 66393 msGridRow: 1, 66394 msGridRowSpan: 1, 66395 msGridColumn: 1, 66396 msGridColumnSpan: 1, 66397 fontWeight: 1, 66398 lineHeight: 1, 66399 opacity: 1, 66400 order: 1, 66401 orphans: 1, 66402 tabSize: 1, 66403 widows: 1, 66404 zIndex: 1, 66405 zoom: 1, 66406 WebkitLineClamp: 1, 66407 // SVG-related properties 66408 fillOpacity: 1, 66409 floodOpacity: 1, 66410 stopOpacity: 1, 66411 strokeDasharray: 1, 66412 strokeDashoffset: 1, 66413 strokeMiterlimit: 1, 66414 strokeOpacity: 1, 66415 strokeWidth: 1 66416 }; 66417 66418 /* harmony default export */ const emotion_unitless_esm = (unitlessKeys); 66419 66420 ;// CONCATENATED MODULE: ./node_modules/@emotion/serialize/node_modules/@emotion/memoize/dist/emotion-memoize.esm.js 66421 function emotion_memoize_esm_memoize(fn) { 66422 var cache = Object.create(null); 66423 return function (arg) { 66424 if (cache[arg] === undefined) cache[arg] = fn(arg); 66425 return cache[arg]; 66426 }; 66427 } 66428 66429 66430 66431 ;// CONCATENATED MODULE: ./node_modules/@emotion/serialize/dist/emotion-serialize.browser.esm.js 66432 66433 66434 66435 66436 var ILLEGAL_ESCAPE_SEQUENCE_ERROR = "You have illegal escape sequence in your template literal, most likely inside content's property value.\nBecause you write your CSS inside a JavaScript string you actually have to do double escaping, so for example \"content: '\\00d7';\" should become \"content: '\\\\00d7';\".\nYou can read more about this here:\nhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#ES2018_revision_of_illegal_escape_sequences"; 66437 var UNDEFINED_AS_OBJECT_KEY_ERROR = "You have passed in falsy value as style object's key (can happen when in example you pass unexported component as computed key)."; 66438 var hyphenateRegex = /[A-Z]|^ms/g; 66439 var animationRegex = /_EMO_([^_]+?)_([^]*?)_EMO_/g; 66440 66441 var isCustomProperty = function isCustomProperty(property) { 66442 return property.charCodeAt(1) === 45; 66443 }; 66444 66445 var isProcessableValue = function isProcessableValue(value) { 66446 return value != null && typeof value !== 'boolean'; 66447 }; 66448 66449 var processStyleName = /* #__PURE__ */emotion_memoize_esm_memoize(function (styleName) { 66450 return isCustomProperty(styleName) ? styleName : styleName.replace(hyphenateRegex, '-$&').toLowerCase(); 66451 }); 66452 66453 var processStyleValue = function processStyleValue(key, value) { 66454 switch (key) { 66455 case 'animation': 66456 case 'animationName': 66457 { 66458 if (typeof value === 'string') { 66459 return value.replace(animationRegex, function (match, p1, p2) { 66460 cursor = { 66461 name: p1, 66462 styles: p2, 66463 next: cursor 66464 }; 66465 return p1; 66466 }); 66467 } 66468 } 66469 } 66470 66471 if (emotion_unitless_esm[key] !== 1 && !isCustomProperty(key) && typeof value === 'number' && value !== 0) { 66472 return value + 'px'; 66473 } 66474 66475 return value; 66476 }; 66477 66478 if (false) { var hyphenatedCache, hyphenPattern, msPattern, oldProcessStyleValue, contentValues, contentValuePattern; } 66479 66480 var noComponentSelectorMessage = (/* unused pure expression or super */ null && ('Component selectors can only be used in conjunction with ' + '@emotion/babel-plugin, the swc Emotion plugin, or another Emotion-aware ' + 'compiler transform.')); 66481 66482 function handleInterpolation(mergedProps, registered, interpolation) { 66483 if (interpolation == null) { 66484 return ''; 66485 } 66486 66487 if (interpolation.__emotion_styles !== undefined) { 66488 if (false) {} 66489 66490 return interpolation; 66491 } 66492 66493 switch (typeof interpolation) { 66494 case 'boolean': 66495 { 66496 return ''; 66497 } 66498 66499 case 'object': 66500 { 66501 if (interpolation.anim === 1) { 66502 cursor = { 66503 name: interpolation.name, 66504 styles: interpolation.styles, 66505 next: cursor 66506 }; 66507 return interpolation.name; 66508 } 66509 66510 if (interpolation.styles !== undefined) { 66511 var next = interpolation.next; 66512 66513 if (next !== undefined) { 66514 // not the most efficient thing ever but this is a pretty rare case 66515 // and there will be very few iterations of this generally 66516 while (next !== undefined) { 66517 cursor = { 66518 name: next.name, 66519 styles: next.styles, 66520 next: cursor 66521 }; 66522 next = next.next; 66523 } 66524 } 66525 66526 var styles = interpolation.styles + ";"; 66527 66528 if (false) {} 66529 66530 return styles; 66531 } 66532 66533 return createStringFromObject(mergedProps, registered, interpolation); 66534 } 66535 66536 case 'function': 66537 { 66538 if (mergedProps !== undefined) { 66539 var previousCursor = cursor; 66540 var result = interpolation(mergedProps); 66541 cursor = previousCursor; 66542 return handleInterpolation(mergedProps, registered, result); 66543 } else if (false) {} 66544 66545 break; 66546 } 66547 66548 case 'string': 66549 if (false) { var replaced, matched; } 66550 66551 break; 66552 } // finalize string values (regular strings and functions interpolated into css calls) 66553 66554 66555 if (registered == null) { 66556 return interpolation; 66557 } 66558 66559 var cached = registered[interpolation]; 66560 return cached !== undefined ? cached : interpolation; 66561 } 66562 66563 function createStringFromObject(mergedProps, registered, obj) { 66564 var string = ''; 66565 66566 if (Array.isArray(obj)) { 66567 for (var i = 0; i < obj.length; i++) { 66568 string += handleInterpolation(mergedProps, registered, obj[i]) + ";"; 66569 } 66570 } else { 66571 for (var _key in obj) { 66572 var value = obj[_key]; 66573 66574 if (typeof value !== 'object') { 66575 if (registered != null && registered[value] !== undefined) { 66576 string += _key + "{" + registered[value] + "}"; 66577 } else if (isProcessableValue(value)) { 66578 string += processStyleName(_key) + ":" + processStyleValue(_key, value) + ";"; 66579 } 66580 } else { 66581 if (_key === 'NO_COMPONENT_SELECTOR' && "production" !== 'production') {} 66582 66583 if (Array.isArray(value) && typeof value[0] === 'string' && (registered == null || registered[value[0]] === undefined)) { 66584 for (var _i = 0; _i < value.length; _i++) { 66585 if (isProcessableValue(value[_i])) { 66586 string += processStyleName(_key) + ":" + processStyleValue(_key, value[_i]) + ";"; 66587 } 66588 } 66589 } else { 66590 var interpolated = handleInterpolation(mergedProps, registered, value); 66591 66592 switch (_key) { 66593 case 'animation': 66594 case 'animationName': 66595 { 66596 string += processStyleName(_key) + ":" + interpolated + ";"; 66597 break; 66598 } 66599 66600 default: 66601 { 66602 if (false) {} 66603 66604 string += _key + "{" + interpolated + "}"; 66605 } 66606 } 66607 } 66608 } 66609 } 66610 } 66611 66612 return string; 66613 } 66614 66615 var labelPattern = /label:\s*([^\s;\n{]+)\s*(;|$)/g; 66616 var sourceMapPattern; 66617 66618 if (false) {} // this is the cursor for keyframes 66619 // keyframes are stored on the SerializedStyles object as a linked list 66620 66621 66622 var cursor; 66623 var emotion_serialize_browser_esm_serializeStyles = function serializeStyles(args, registered, mergedProps) { 66624 if (args.length === 1 && typeof args[0] === 'object' && args[0] !== null && args[0].styles !== undefined) { 66625 return args[0]; 66626 } 66627 66628 var stringMode = true; 66629 var styles = ''; 66630 cursor = undefined; 66631 var strings = args[0]; 66632 66633 if (strings == null || strings.raw === undefined) { 66634 stringMode = false; 66635 styles += handleInterpolation(mergedProps, registered, strings); 66636 } else { 66637 if (false) {} 66638 66639 styles += strings[0]; 66640 } // we start at 1 since we've already handled the first arg 66641 66642 66643 for (var i = 1; i < args.length; i++) { 66644 styles += handleInterpolation(mergedProps, registered, args[i]); 66645 66646 if (stringMode) { 66647 if (false) {} 66648 66649 styles += strings[i]; 66650 } 66651 } 66652 66653 var sourceMap; 66654 66655 if (false) {} // using a global regex with .exec is stateful so lastIndex has to be reset each time 66656 66657 66658 labelPattern.lastIndex = 0; 66659 var identifierName = ''; 66660 var match; // https://esbench.com/bench/5b809c2cf2949800a0f61fb5 66661 66662 while ((match = labelPattern.exec(styles)) !== null) { 66663 identifierName += '-' + // $FlowFixMe we know it's not null 66664 match[1]; 66665 } 66666 66667 var name = emotion_hash_esm(styles) + identifierName; 66668 66669 if (false) {} 66670 66671 return { 66672 name: name, 66673 styles: styles, 66674 next: cursor 66675 }; 66676 }; 66677 66678 66679 66680 ;// CONCATENATED MODULE: ./node_modules/@emotion/use-insertion-effect-with-fallbacks/dist/emotion-use-insertion-effect-with-fallbacks.browser.esm.js 66681 66682 66683 66684 var syncFallback = function syncFallback(create) { 66685 return create(); 66686 }; 66687 66688 var useInsertionEffect = external_React_['useInsertion' + 'Effect'] ? external_React_['useInsertion' + 'Effect'] : false; 66689 var emotion_use_insertion_effect_with_fallbacks_browser_esm_useInsertionEffectAlwaysWithSyncFallback = useInsertionEffect || syncFallback; 66690 var useInsertionEffectWithLayoutFallback = (/* unused pure expression or super */ null && (useInsertionEffect || useLayoutEffect)); 66691 66692 66693 66694 ;// CONCATENATED MODULE: ./node_modules/@emotion/react/dist/emotion-element-6a883da9.browser.esm.js 66695 66696 66697 66698 66699 66700 66701 66702 66703 66704 var emotion_element_6a883da9_browser_esm_hasOwnProperty = {}.hasOwnProperty; 66705 66706 var EmotionCacheContext = /* #__PURE__ */(0,external_React_.createContext)( // we're doing this to avoid preconstruct's dead code elimination in this one case 66707 // because this module is primarily intended for the browser and node 66708 // but it's also required in react native and similar environments sometimes 66709 // and we could have a special build just for that 66710 // but this is much easier and the native packages 66711 // might use a different theme context in the future anyway 66712 typeof HTMLElement !== 'undefined' ? /* #__PURE__ */emotion_cache_browser_esm({ 66713 key: 'css' 66714 }) : null); 66715 66716 if (false) {} 66717 66718 var CacheProvider = EmotionCacheContext.Provider; 66719 var __unsafe_useEmotionCache = function useEmotionCache() { 66720 return useContext(EmotionCacheContext); 66721 }; 66722 66723 var withEmotionCache = function withEmotionCache(func) { 66724 // $FlowFixMe 66725 return /*#__PURE__*/(0,external_React_.forwardRef)(function (props, ref) { 66726 // the cache will never be null in the browser 66727 var cache = (0,external_React_.useContext)(EmotionCacheContext); 66728 return func(props, cache, ref); 66729 }); 66730 }; 66731 66732 var ThemeContext = /* #__PURE__ */(0,external_React_.createContext)({}); 66733 66734 if (false) {} 66735 66736 var useTheme = function useTheme() { 66737 return useContext(ThemeContext); 66738 }; 66739 66740 var getTheme = function getTheme(outerTheme, theme) { 66741 if (typeof theme === 'function') { 66742 var mergedTheme = theme(outerTheme); 66743 66744 if (false) {} 66745 66746 return mergedTheme; 66747 } 66748 66749 if (false) {} 66750 66751 return _extends({}, outerTheme, theme); 66752 }; 66753 66754 var createCacheWithTheme = /* #__PURE__ */(/* unused pure expression or super */ null && (weakMemoize(function (outerTheme) { 66755 return weakMemoize(function (theme) { 66756 return getTheme(outerTheme, theme); 66757 }); 66758 }))); 66759 var ThemeProvider = function ThemeProvider(props) { 66760 var theme = useContext(ThemeContext); 66761 66762 if (props.theme !== theme) { 66763 theme = createCacheWithTheme(theme)(props.theme); 66764 } 66765 66766 return /*#__PURE__*/createElement(ThemeContext.Provider, { 66767 value: theme 66768 }, props.children); 66769 }; 66770 function withTheme(Component) { 66771 var componentName = Component.displayName || Component.name || 'Component'; 66772 66773 var render = function render(props, ref) { 66774 var theme = useContext(ThemeContext); 66775 return /*#__PURE__*/createElement(Component, _extends({ 66776 theme: theme, 66777 ref: ref 66778 }, props)); 66779 }; // $FlowFixMe 66780 66781 66782 var WithTheme = /*#__PURE__*/forwardRef(render); 66783 WithTheme.displayName = "WithTheme(" + componentName + ")"; 66784 return hoistNonReactStatics(WithTheme, Component); 66785 } 66786 66787 var getLastPart = function getLastPart(functionName) { 66788 // The match may be something like 'Object.createEmotionProps' or 66789 // 'Loader.prototype.render' 66790 var parts = functionName.split('.'); 66791 return parts[parts.length - 1]; 66792 }; 66793 66794 var getFunctionNameFromStackTraceLine = function getFunctionNameFromStackTraceLine(line) { 66795 // V8 66796 var match = /^\s+at\s+([A-Za-z0-9$.]+)\s/.exec(line); 66797 if (match) return getLastPart(match[1]); // Safari / Firefox 66798 66799 match = /^([A-Za-z0-9$.]+)@/.exec(line); 66800 if (match) return getLastPart(match[1]); 66801 return undefined; 66802 }; 66803 66804 var internalReactFunctionNames = /* #__PURE__ */new Set(['renderWithHooks', 'processChild', 'finishClassComponent', 'renderToString']); // These identifiers come from error stacks, so they have to be valid JS 66805 // identifiers, thus we only need to replace what is a valid character for JS, 66806 // but not for CSS. 66807 66808 var sanitizeIdentifier = function sanitizeIdentifier(identifier) { 66809 return identifier.replace(/\$/g, '-'); 66810 }; 66811 66812 var getLabelFromStackTrace = function getLabelFromStackTrace(stackTrace) { 66813 if (!stackTrace) return undefined; 66814 var lines = stackTrace.split('\n'); 66815 66816 for (var i = 0; i < lines.length; i++) { 66817 var functionName = getFunctionNameFromStackTraceLine(lines[i]); // The first line of V8 stack traces is just "Error" 66818 66819 if (!functionName) continue; // If we reach one of these, we have gone too far and should quit 66820 66821 if (internalReactFunctionNames.has(functionName)) break; // The component name is the first function in the stack that starts with an 66822 // uppercase letter 66823 66824 if (/^[A-Z]/.test(functionName)) return sanitizeIdentifier(functionName); 66825 } 66826 66827 return undefined; 66828 }; 66829 66830 var typePropName = '__EMOTION_TYPE_PLEASE_DO_NOT_USE__'; 66831 var labelPropName = '__EMOTION_LABEL_PLEASE_DO_NOT_USE__'; 66832 var createEmotionProps = function createEmotionProps(type, props) { 66833 if (false) {} 66834 66835 var newProps = {}; 66836 66837 for (var key in props) { 66838 if (emotion_element_6a883da9_browser_esm_hasOwnProperty.call(props, key)) { 66839 newProps[key] = props[key]; 66840 } 66841 } 66842 66843 newProps[typePropName] = type; // For performance, only call getLabelFromStackTrace in development and when 66844 // the label hasn't already been computed 66845 66846 if (false) { var label; } 66847 66848 return newProps; 66849 }; 66850 66851 var Insertion = function Insertion(_ref) { 66852 var cache = _ref.cache, 66853 serialized = _ref.serialized, 66854 isStringTag = _ref.isStringTag; 66855 registerStyles(cache, serialized, isStringTag); 66856 var rules = useInsertionEffectAlwaysWithSyncFallback(function () { 66857 return insertStyles(cache, serialized, isStringTag); 66858 }); 66859 66860 return null; 66861 }; 66862 66863 var Emotion = /* #__PURE__ */(/* unused pure expression or super */ null && (withEmotionCache(function (props, cache, ref) { 66864 var cssProp = props.css; // so that using `css` from `emotion` and passing the result to the css prop works 66865 // not passing the registered cache to serializeStyles because it would 66866 // make certain babel optimisations not possible 66867 66868 if (typeof cssProp === 'string' && cache.registered[cssProp] !== undefined) { 66869 cssProp = cache.registered[cssProp]; 66870 } 66871 66872 var WrappedComponent = props[typePropName]; 66873 var registeredStyles = [cssProp]; 66874 var className = ''; 66875 66876 if (typeof props.className === 'string') { 66877 className = getRegisteredStyles(cache.registered, registeredStyles, props.className); 66878 } else if (props.className != null) { 66879 className = props.className + " "; 66880 } 66881 66882 var serialized = serializeStyles(registeredStyles, undefined, useContext(ThemeContext)); 66883 66884 if (false) { var labelFromStack; } 66885 66886 className += cache.key + "-" + serialized.name; 66887 var newProps = {}; 66888 66889 for (var key in props) { 66890 if (emotion_element_6a883da9_browser_esm_hasOwnProperty.call(props, key) && key !== 'css' && key !== typePropName && ( true || 0)) { 66891 newProps[key] = props[key]; 66892 } 66893 } 66894 66895 newProps.ref = ref; 66896 newProps.className = className; 66897 return /*#__PURE__*/createElement(Fragment, null, /*#__PURE__*/createElement(Insertion, { 66898 cache: cache, 66899 serialized: serialized, 66900 isStringTag: typeof WrappedComponent === 'string' 66901 }), /*#__PURE__*/createElement(WrappedComponent, newProps)); 66902 }))); 66903 66904 if (false) {} 66905 66906 66907 66908 ;// CONCATENATED MODULE: ./node_modules/@emotion/utils/dist/emotion-utils.browser.esm.js 66909 var isBrowser = "object" !== 'undefined'; 66910 function emotion_utils_browser_esm_getRegisteredStyles(registered, registeredStyles, classNames) { 66911 var rawClassName = ''; 66912 classNames.split(' ').forEach(function (className) { 66913 if (registered[className] !== undefined) { 66914 registeredStyles.push(registered[className] + ";"); 66915 } else { 66916 rawClassName += className + " "; 66917 } 66918 }); 66919 return rawClassName; 66920 } 66921 var emotion_utils_browser_esm_registerStyles = function registerStyles(cache, serialized, isStringTag) { 66922 var className = cache.key + "-" + serialized.name; 66923 66924 if ( // we only need to add the styles to the registered cache if the 66925 // class name could be used further down 66926 // the tree but if it's a string tag, we know it won't 66927 // so we don't have to add it to registered cache. 66928 // this improves memory usage since we can avoid storing the whole style string 66929 (isStringTag === false || // we need to always store it if we're in compat mode and 66930 // in node since emotion-server relies on whether a style is in 66931 // the registered cache to know whether a style is global or not 66932 // also, note that this check will be dead code eliminated in the browser 66933 isBrowser === false ) && cache.registered[className] === undefined) { 66934 cache.registered[className] = serialized.styles; 66935 } 66936 }; 66937 var emotion_utils_browser_esm_insertStyles = function insertStyles(cache, serialized, isStringTag) { 66938 emotion_utils_browser_esm_registerStyles(cache, serialized, isStringTag); 66939 var className = cache.key + "-" + serialized.name; 66940 66941 if (cache.inserted[serialized.name] === undefined) { 66942 var current = serialized; 66943 66944 do { 66945 var maybeStyles = cache.insert(serialized === current ? "." + className : '', current, cache.sheet, true); 66946 66947 current = current.next; 66948 } while (current !== undefined); 66949 } 66950 }; 66951 66952 66953 66954 ;// CONCATENATED MODULE: ./node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js 66955 66956 66957 66958 66959 66960 66961 66962 66963 var testOmitPropsOnStringTag = isPropValid; 66964 66965 var testOmitPropsOnComponent = function testOmitPropsOnComponent(key) { 66966 return key !== 'theme'; 66967 }; 66968 66969 var getDefaultShouldForwardProp = function getDefaultShouldForwardProp(tag) { 66970 return typeof tag === 'string' && // 96 is one less than the char code 66971 // for "a" so this is checking that 66972 // it's a lowercase character 66973 tag.charCodeAt(0) > 96 ? testOmitPropsOnStringTag : testOmitPropsOnComponent; 66974 }; 66975 var composeShouldForwardProps = function composeShouldForwardProps(tag, options, isReal) { 66976 var shouldForwardProp; 66977 66978 if (options) { 66979 var optionsShouldForwardProp = options.shouldForwardProp; 66980 shouldForwardProp = tag.__emotion_forwardProp && optionsShouldForwardProp ? function (propName) { 66981 return tag.__emotion_forwardProp(propName) && optionsShouldForwardProp(propName); 66982 } : optionsShouldForwardProp; 66983 } 66984 66985 if (typeof shouldForwardProp !== 'function' && isReal) { 66986 shouldForwardProp = tag.__emotion_forwardProp; 66987 } 66988 66989 return shouldForwardProp; 66990 }; 66991 66992 var emotion_styled_base_browser_esm_ILLEGAL_ESCAPE_SEQUENCE_ERROR = "You have illegal escape sequence in your template literal, most likely inside content's property value.\nBecause you write your CSS inside a JavaScript string you actually have to do double escaping, so for example \"content: '\\00d7';\" should become \"content: '\\\\00d7';\".\nYou can read more about this here:\nhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#ES2018_revision_of_illegal_escape_sequences"; 66993 66994 var emotion_styled_base_browser_esm_Insertion = function Insertion(_ref) { 66995 var cache = _ref.cache, 66996 serialized = _ref.serialized, 66997 isStringTag = _ref.isStringTag; 66998 emotion_utils_browser_esm_registerStyles(cache, serialized, isStringTag); 66999 var rules = emotion_use_insertion_effect_with_fallbacks_browser_esm_useInsertionEffectAlwaysWithSyncFallback(function () { 67000 return emotion_utils_browser_esm_insertStyles(cache, serialized, isStringTag); 67001 }); 67002 67003 return null; 67004 }; 67005 67006 var createStyled = function createStyled(tag, options) { 67007 if (false) {} 67008 67009 var isReal = tag.__emotion_real === tag; 67010 var baseTag = isReal && tag.__emotion_base || tag; 67011 var identifierName; 67012 var targetClassName; 67013 67014 if (options !== undefined) { 67015 identifierName = options.label; 67016 targetClassName = options.target; 67017 } 67018 67019 var shouldForwardProp = composeShouldForwardProps(tag, options, isReal); 67020 var defaultShouldForwardProp = shouldForwardProp || getDefaultShouldForwardProp(baseTag); 67021 var shouldUseAs = !defaultShouldForwardProp('as'); 67022 return function () { 67023 var args = arguments; 67024 var styles = isReal && tag.__emotion_styles !== undefined ? tag.__emotion_styles.slice(0) : []; 67025 67026 if (identifierName !== undefined) { 67027 styles.push("label:" + identifierName + ";"); 67028 } 67029 67030 if (args[0] == null || args[0].raw === undefined) { 67031 styles.push.apply(styles, args); 67032 } else { 67033 if (false) {} 67034 67035 styles.push(args[0][0]); 67036 var len = args.length; 67037 var i = 1; 67038 67039 for (; i < len; i++) { 67040 if (false) {} 67041 67042 styles.push(args[i], args[0][i]); 67043 } 67044 } // $FlowFixMe: we need to cast StatelessFunctionalComponent to our PrivateStyledComponent class 67045 67046 67047 var Styled = withEmotionCache(function (props, cache, ref) { 67048 var FinalTag = shouldUseAs && props.as || baseTag; 67049 var className = ''; 67050 var classInterpolations = []; 67051 var mergedProps = props; 67052 67053 if (props.theme == null) { 67054 mergedProps = {}; 67055 67056 for (var key in props) { 67057 mergedProps[key] = props[key]; 67058 } 67059 67060 mergedProps.theme = (0,external_React_.useContext)(ThemeContext); 67061 } 67062 67063 if (typeof props.className === 'string') { 67064 className = emotion_utils_browser_esm_getRegisteredStyles(cache.registered, classInterpolations, props.className); 67065 } else if (props.className != null) { 67066 className = props.className + " "; 67067 } 67068 67069 var serialized = emotion_serialize_browser_esm_serializeStyles(styles.concat(classInterpolations), cache.registered, mergedProps); 67070 className += cache.key + "-" + serialized.name; 67071 67072 if (targetClassName !== undefined) { 67073 className += " " + targetClassName; 67074 } 67075 67076 var finalShouldForwardProp = shouldUseAs && shouldForwardProp === undefined ? getDefaultShouldForwardProp(FinalTag) : defaultShouldForwardProp; 67077 var newProps = {}; 67078 67079 for (var _key in props) { 67080 if (shouldUseAs && _key === 'as') continue; 67081 67082 if ( // $FlowFixMe 67083 finalShouldForwardProp(_key)) { 67084 newProps[_key] = props[_key]; 67085 } 67086 } 67087 67088 newProps.className = className; 67089 newProps.ref = ref; 67090 return /*#__PURE__*/(0,external_React_.createElement)(external_React_.Fragment, null, /*#__PURE__*/(0,external_React_.createElement)(emotion_styled_base_browser_esm_Insertion, { 67091 cache: cache, 67092 serialized: serialized, 67093 isStringTag: typeof FinalTag === 'string' 67094 }), /*#__PURE__*/(0,external_React_.createElement)(FinalTag, newProps)); 67095 }); 67096 Styled.displayName = identifierName !== undefined ? identifierName : "Styled(" + (typeof baseTag === 'string' ? baseTag : baseTag.displayName || baseTag.name || 'Component') + ")"; 67097 Styled.defaultProps = tag.defaultProps; 67098 Styled.__emotion_real = Styled; 67099 Styled.__emotion_base = baseTag; 67100 Styled.__emotion_styles = styles; 67101 Styled.__emotion_forwardProp = shouldForwardProp; 67102 Object.defineProperty(Styled, 'toString', { 67103 value: function value() { 67104 if (targetClassName === undefined && "production" !== 'production') {} // $FlowFixMe: coerce undefined to string 67105 67106 67107 return "." + targetClassName; 67108 } 67109 }); 67110 67111 Styled.withComponent = function (nextTag, nextOptions) { 67112 return createStyled(nextTag, extends_extends({}, options, nextOptions, { 67113 shouldForwardProp: composeShouldForwardProps(Styled, nextOptions, true) 67114 })).apply(void 0, styles); 67115 }; 67116 67117 return Styled; 67118 }; 67119 }; 67120 67121 /* harmony default export */ const emotion_styled_base_browser_esm = (createStyled); 67122 67123 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/dimensions-tool/width-height-tool.js 67124 67125 67126 function _EMOTION_STRINGIFIED_CSS_ERROR__() { return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; } 67127 /** 67128 * External dependencies 67129 */ 67130 67131 /** 67132 * WordPress dependencies 67133 */ 67134 67135 67136 const SingleColumnToolsPanelItem = /*#__PURE__*/emotion_styled_base_browser_esm(external_wp_components_namespaceObject.__experimentalToolsPanelItem, true ? { 67137 target: "ef8pe3d0" 67138 } : 0)( true ? { 67139 name: "957xgf", 67140 styles: "grid-column:span 1" 67141 } : 0); 67142 67143 /** 67144 * @typedef {import('@wordpress/components/build-types/unit-control/types').WPUnitControlUnit} WPUnitControlUnit 67145 */ 67146 67147 /** 67148 * @typedef {Object} WidthHeightToolValue 67149 * @property {string} [width] Width CSS value. 67150 * @property {string} [height] Height CSS value. 67151 */ 67152 67153 /** 67154 * @callback WidthHeightToolOnChange 67155 * @param {WidthHeightToolValue} nextValue Next dimensions value. 67156 * @return {void} 67157 */ 67158 67159 /** 67160 * @typedef {Object} WidthHeightToolProps 67161 * @property {string} [panelId] ID of the panel that contains the controls. 67162 * @property {WidthHeightToolValue} [value] Current dimensions values. 67163 * @property {WidthHeightToolOnChange} [onChange] Callback to update the dimensions values. 67164 * @property {WPUnitControlUnit[]} [units] Units options. 67165 * @property {boolean} [isShownByDefault] Whether the panel is shown by default. 67166 */ 67167 67168 /** 67169 * Component that renders controls to edit the dimensions of an image or container. 67170 * 67171 * @param {WidthHeightToolProps} props The component props. 67172 * 67173 * @return {import('react').ReactElement} The width and height tool. 67174 */ 67175 function WidthHeightTool({ 67176 panelId, 67177 value = {}, 67178 onChange = () => {}, 67179 units, 67180 isShownByDefault = true 67181 }) { 67182 var _value$width, _value$height; 67183 // null, undefined, and 'auto' all represent the default value. 67184 const width = value.width === 'auto' ? '' : (_value$width = value.width) !== null && _value$width !== void 0 ? _value$width : ''; 67185 const height = value.height === 'auto' ? '' : (_value$height = value.height) !== null && _value$height !== void 0 ? _value$height : ''; 67186 const onDimensionChange = dimension => nextDimension => { 67187 const nextValue = { 67188 ...value 67189 }; 67190 // Empty strings or undefined may be passed and both represent removing the value. 67191 if (!nextDimension) { 67192 delete nextValue[dimension]; 67193 } else { 67194 nextValue[dimension] = nextDimension; 67195 } 67196 onChange(nextValue); 67197 }; 67198 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(SingleColumnToolsPanelItem, { 67199 label: (0,external_wp_i18n_namespaceObject.__)('Width'), 67200 isShownByDefault: isShownByDefault, 67201 hasValue: () => width !== '', 67202 onDeselect: onDimensionChange('width'), 67203 panelId: panelId 67204 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalUnitControl, { 67205 label: (0,external_wp_i18n_namespaceObject.__)('Width'), 67206 placeholder: (0,external_wp_i18n_namespaceObject.__)('Auto'), 67207 labelPosition: "top", 67208 units: units, 67209 min: 0, 67210 value: width, 67211 onChange: onDimensionChange('width'), 67212 size: '__unstable-large' 67213 })), (0,external_React_.createElement)(SingleColumnToolsPanelItem, { 67214 label: (0,external_wp_i18n_namespaceObject.__)('Height'), 67215 isShownByDefault: isShownByDefault, 67216 hasValue: () => height !== '', 67217 onDeselect: onDimensionChange('height'), 67218 panelId: panelId 67219 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalUnitControl, { 67220 label: (0,external_wp_i18n_namespaceObject.__)('Height'), 67221 placeholder: (0,external_wp_i18n_namespaceObject.__)('Auto'), 67222 labelPosition: "top", 67223 units: units, 67224 min: 0, 67225 value: height, 67226 onChange: onDimensionChange('height'), 67227 size: '__unstable-large' 67228 }))); 67229 } 67230 67231 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/dimensions-tool/index.js 67232 67233 /** 67234 * WordPress dependencies 67235 */ 67236 67237 67238 /** 67239 * Internal dependencies 67240 */ 67241 67242 67243 67244 67245 /** 67246 * @typedef {import('@wordpress/components/build-types/select-control/types').SelectControlProps} SelectControlProps 67247 */ 67248 67249 /** 67250 * @typedef {import('@wordpress/components/build-types/unit-control/types').WPUnitControlUnit} WPUnitControlUnit 67251 */ 67252 67253 /** 67254 * @typedef {Object} Dimensions 67255 * @property {string} [width] CSS width property. 67256 * @property {string} [height] CSS height property. 67257 * @property {string} [scale] CSS object-fit property. 67258 * @property {string} [aspectRatio] CSS aspect-ratio property. 67259 */ 67260 67261 /** 67262 * @callback DimensionsControlsOnChange 67263 * @param {Dimensions} nextValue 67264 * @return {void} 67265 */ 67266 67267 /** 67268 * @typedef {Object} DimensionsControlsProps 67269 * @property {string} [panelId] ID of the panel that contains the controls. 67270 * @property {Dimensions} [value] Current dimensions values. 67271 * @property {DimensionsControlsOnChange} [onChange] Callback to update the dimensions values. 67272 * @property {SelectControlProps[]} [aspectRatioOptions] Aspect ratio options. 67273 * @property {SelectControlProps[]} [scaleOptions] Scale options. 67274 * @property {WPUnitControlUnit[]} [unitsOptions] Units options. 67275 */ 67276 67277 /** 67278 * Component that renders controls to edit the dimensions of an image or container. 67279 * 67280 * @param {DimensionsControlsProps} props The component props. 67281 * 67282 * @return {Element} The dimensions controls. 67283 */ 67284 function DimensionsTool({ 67285 panelId, 67286 value = {}, 67287 onChange = () => {}, 67288 aspectRatioOptions, 67289 // Default options handled by AspectRatioTool. 67290 defaultAspectRatio = 'auto', 67291 // Match CSS default value for aspect-ratio. 67292 scaleOptions, 67293 // Default options handled by ScaleTool. 67294 defaultScale = 'fill', 67295 // Match CSS default value for object-fit. 67296 unitsOptions // Default options handled by UnitControl. 67297 }) { 67298 // Coerce undefined and CSS default values to be null. 67299 const width = value.width === undefined || value.width === 'auto' ? null : value.width; 67300 const height = value.height === undefined || value.height === 'auto' ? null : value.height; 67301 const aspectRatio = value.aspectRatio === undefined || value.aspectRatio === 'auto' ? null : value.aspectRatio; 67302 const scale = value.scale === undefined || value.scale === 'fill' ? null : value.scale; 67303 67304 // Keep track of state internally, so when the value is cleared by means 67305 // other than directly editing that field, it's easier to restore the 67306 // previous value. 67307 const [lastScale, setLastScale] = (0,external_wp_element_namespaceObject.useState)(scale); 67308 const [lastAspectRatio, setLastAspectRatio] = (0,external_wp_element_namespaceObject.useState)(aspectRatio); 67309 67310 // 'custom' is not a valid value for CSS aspect-ratio, but it is used in the 67311 // dropdown to indicate that setting both the width and height is the same 67312 // as a custom aspect ratio. 67313 const aspectRatioValue = width && height ? 'custom' : lastAspectRatio; 67314 const showScaleControl = aspectRatio || width && height; 67315 return (0,external_React_.createElement)(external_React_.Fragment, null, (0,external_React_.createElement)(AspectRatioTool, { 67316 panelId: panelId, 67317 options: aspectRatioOptions, 67318 defaultValue: defaultAspectRatio, 67319 value: aspectRatioValue, 67320 onChange: nextAspectRatio => { 67321 const nextValue = { 67322 ...value 67323 }; 67324 67325 // 'auto' is CSS default, so it gets treated as null. 67326 nextAspectRatio = nextAspectRatio === 'auto' ? null : nextAspectRatio; 67327 setLastAspectRatio(nextAspectRatio); 67328 67329 // Update aspectRatio. 67330 if (!nextAspectRatio) { 67331 delete nextValue.aspectRatio; 67332 } else { 67333 nextValue.aspectRatio = nextAspectRatio; 67334 } 67335 67336 // Auto-update scale. 67337 if (!nextAspectRatio) { 67338 delete nextValue.scale; 67339 } else if (lastScale) { 67340 nextValue.scale = lastScale; 67341 } else { 67342 nextValue.scale = defaultScale; 67343 setLastScale(defaultScale); 67344 } 67345 67346 // Auto-update width and height. 67347 if ('custom' !== nextAspectRatio && width && height) { 67348 delete nextValue.height; 67349 } 67350 onChange(nextValue); 67351 } 67352 }), (0,external_React_.createElement)(WidthHeightTool, { 67353 panelId: panelId, 67354 units: unitsOptions, 67355 value: { 67356 width, 67357 height 67358 }, 67359 onChange: ({ 67360 width: nextWidth, 67361 height: nextHeight 67362 }) => { 67363 const nextValue = { 67364 ...value 67365 }; 67366 67367 // 'auto' is CSS default, so it gets treated as null. 67368 nextWidth = nextWidth === 'auto' ? null : nextWidth; 67369 nextHeight = nextHeight === 'auto' ? null : nextHeight; 67370 67371 // Update width. 67372 if (!nextWidth) { 67373 delete nextValue.width; 67374 } else { 67375 nextValue.width = nextWidth; 67376 } 67377 67378 // Update height. 67379 if (!nextHeight) { 67380 delete nextValue.height; 67381 } else { 67382 nextValue.height = nextHeight; 67383 } 67384 67385 // Auto-update aspectRatio. 67386 if (nextWidth && nextHeight) { 67387 delete nextValue.aspectRatio; 67388 } else if (lastAspectRatio) { 67389 nextValue.aspectRatio = lastAspectRatio; 67390 } else { 67391 // No setting defaultAspectRatio here, because 67392 // aspectRatio is optional in this scenario, 67393 // unlike scale. 67394 } 67395 67396 // Auto-update scale. 67397 if (!lastAspectRatio && !!nextWidth !== !!nextHeight) { 67398 delete nextValue.scale; 67399 } else if (lastScale) { 67400 nextValue.scale = lastScale; 67401 } else { 67402 nextValue.scale = defaultScale; 67403 setLastScale(defaultScale); 67404 } 67405 onChange(nextValue); 67406 } 67407 }), showScaleControl && (0,external_React_.createElement)(ScaleTool, { 67408 panelId: panelId, 67409 options: scaleOptions, 67410 defaultValue: defaultScale, 67411 value: lastScale, 67412 onChange: nextScale => { 67413 const nextValue = { 67414 ...value 67415 }; 67416 67417 // 'fill' is CSS default, so it gets treated as null. 67418 nextScale = nextScale === 'fill' ? null : nextScale; 67419 setLastScale(nextScale); 67420 67421 // Update scale. 67422 if (!nextScale) { 67423 delete nextValue.scale; 67424 } else { 67425 nextValue.scale = nextScale; 67426 } 67427 onChange(nextValue); 67428 } 67429 })); 67430 } 67431 /* harmony default export */ const dimensions_tool = (DimensionsTool); 67432 67433 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/resolution-tool/index.js 67434 67435 /** 67436 * WordPress dependencies 67437 */ 67438 67439 67440 const DEFAULT_SIZE_OPTIONS = [{ 67441 label: (0,external_wp_i18n_namespaceObject._x)('Thumbnail', 'Image size option for resolution control'), 67442 value: 'thumbnail' 67443 }, { 67444 label: (0,external_wp_i18n_namespaceObject._x)('Medium', 'Image size option for resolution control'), 67445 value: 'medium' 67446 }, { 67447 label: (0,external_wp_i18n_namespaceObject._x)('Large', 'Image size option for resolution control'), 67448 value: 'large' 67449 }, { 67450 label: (0,external_wp_i18n_namespaceObject._x)('Full Size', 'Image size option for resolution control'), 67451 value: 'full' 67452 }]; 67453 function ResolutionTool({ 67454 panelId, 67455 value, 67456 onChange, 67457 options = DEFAULT_SIZE_OPTIONS, 67458 defaultValue = DEFAULT_SIZE_OPTIONS[0].value, 67459 isShownByDefault = true 67460 }) { 67461 const displayValue = value !== null && value !== void 0 ? value : defaultValue; 67462 return (0,external_React_.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 67463 hasValue: () => displayValue !== defaultValue, 67464 label: (0,external_wp_i18n_namespaceObject.__)('Resolution'), 67465 onDeselect: () => onChange(defaultValue), 67466 isShownByDefault: isShownByDefault, 67467 panelId: panelId 67468 }, (0,external_React_.createElement)(external_wp_components_namespaceObject.SelectControl, { 67469 label: (0,external_wp_i18n_namespaceObject.__)('Resolution'), 67470 value: displayValue, 67471 options: options, 67472 onChange: onChange, 67473 help: (0,external_wp_i18n_namespaceObject.__)('Select the size of the source image.'), 67474 size: '__unstable-large' 67475 })); 67476 } 67477 67478 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/private-apis.js 67479 /** 67480 * Internal dependencies 67481 */ 67482 67483 67484 67485 67486 67487 67488 67489 67490 67491 67492 67493 67494 67495 67496 67497 67498 67499 67500 67501 67502 67503 67504 67505 67506 67507 67508 /** 67509 * Private @wordpress/block-editor APIs. 67510 */ 67511 const privateApis = {}; 67512 lock(privateApis, { 67513 ...global_styles_namespaceObject, 67514 ExperimentalBlockCanvas: ExperimentalBlockCanvas, 67515 ExperimentalBlockEditorProvider: ExperimentalBlockEditorProvider, 67516 getDuotoneFilter: getDuotoneFilter, 67517 getRichTextValues: getRichTextValues, 67518 PrivateInserter: ComposedPrivateInserter, 67519 PrivateQuickInserter: QuickInserter, 67520 PrivateListView: PrivateListView, 67521 ResizableBoxPopover: ResizableBoxPopover, 67522 BlockInfo: block_info_slot_fill, 67523 useCanBlockToolbarBeFocused: useCanBlockToolbarBeFocused, 67524 cleanEmptyObject: utils_cleanEmptyObject, 67525 useStyleOverride: useStyleOverride, 67526 BlockQuickNavigation: BlockQuickNavigation, 67527 LayoutStyle: LayoutStyle, 67528 BlockRemovalWarningModal: BlockRemovalWarningModal, 67529 useLayoutClasses: useLayoutClasses, 67530 useLayoutStyles: useLayoutStyles, 67531 DimensionsTool: dimensions_tool, 67532 ResolutionTool: ResolutionTool, 67533 ReusableBlocksRenameHint: ReusableBlocksRenameHint, 67534 useReusableBlocksRenameHint: useReusableBlocksRenameHint, 67535 usesContextKey: usesContextKey, 67536 useFlashEditableBlocks: useFlashEditableBlocks, 67537 selectBlockPatternsKey: selectBlockPatternsKey, 67538 requiresWrapperOnCopy: requiresWrapperOnCopy, 67539 PrivateRichText: PrivateRichText 67540 }); 67541 67542 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/index.js 67543 /** 67544 * Internal dependencies 67545 */ 67546 67547 67548 67549 67550 67551 67552 67553 67554 67555 })(); 67556 67557 (window.wp = window.wp || {}).blockEditor = __webpack_exports__; 67558 /******/ })() 67559 ;
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Sat Apr 20 08:20:01 2024 | Cross-referenced by PHPXref |